@splitsoftware/splitio-commons 1.16.1-rc.8 → 1.17.0-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.
- package/CHANGES.txt +2 -1
- package/cjs/evaluator/matchers/index.js +1 -3
- package/cjs/evaluator/matchers/matcherTypes.js +0 -1
- package/cjs/evaluator/matchersTransform/index.js +1 -1
- package/cjs/logger/constants.js +4 -3
- package/cjs/logger/messages/info.js +2 -1
- package/cjs/readiness/readinessManager.js +10 -14
- package/cjs/readiness/sdkReadinessManager.js +6 -5
- package/cjs/sdkClient/sdkClientMethodCS.js +2 -2
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +2 -2
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/services/decorateHeaders.js +42 -0
- package/cjs/services/splitApi.js +0 -4
- package/cjs/services/splitHttpClient.js +5 -4
- package/cjs/storages/AbstractSplitsCacheAsync.js +2 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +6 -5
- package/cjs/storages/KeyBuilder.js +0 -3
- package/cjs/storages/KeyBuilderCS.js +5 -17
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +4 -16
- package/cjs/storages/inLocalStorage/index.js +2 -6
- package/cjs/storages/inMemory/InMemoryStorageCS.js +0 -5
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +11 -20
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +10 -7
- package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +1 -5
- package/cjs/sync/polling/pollingManagerCS.js +33 -51
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +21 -20
- package/cjs/sync/streaming/SSEClient/index.js +0 -4
- package/cjs/sync/streaming/SSEHandler/index.js +0 -1
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +9 -23
- package/cjs/sync/streaming/constants.js +1 -2
- package/cjs/sync/streaming/parseUtils.js +8 -3
- package/cjs/sync/streaming/pushManager.js +68 -99
- package/cjs/sync/submitters/telemetrySubmitter.js +0 -4
- package/cjs/sync/syncManagerOnline.js +14 -24
- package/cjs/utils/constants/index.js +2 -4
- package/cjs/utils/settingsValidation/index.js +2 -7
- package/esm/evaluator/matchers/index.js +1 -3
- package/esm/evaluator/matchers/matcherTypes.js +0 -1
- package/esm/evaluator/matchersTransform/index.js +1 -1
- package/esm/logger/constants.js +1 -0
- package/esm/logger/messages/info.js +2 -1
- package/esm/readiness/readinessManager.js +10 -14
- package/esm/readiness/sdkReadinessManager.js +6 -5
- package/esm/sdkClient/sdkClientMethodCS.js +2 -2
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +2 -2
- package/esm/sdkFactory/index.js +1 -1
- package/esm/services/decorateHeaders.js +38 -0
- package/esm/services/splitApi.js +1 -5
- package/esm/services/splitHttpClient.js +5 -4
- package/esm/storages/AbstractSplitsCacheAsync.js +2 -2
- package/esm/storages/AbstractSplitsCacheSync.js +4 -3
- package/esm/storages/KeyBuilder.js +0 -3
- package/esm/storages/KeyBuilderCS.js +4 -15
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +5 -17
- package/esm/storages/inLocalStorage/index.js +3 -7
- package/esm/storages/inMemory/InMemoryStorageCS.js +0 -5
- package/esm/storages/inMemory/SplitsCacheInMemory.js +12 -21
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +10 -7
- package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +1 -5
- package/esm/sync/polling/pollingManagerCS.js +34 -52
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +19 -18
- package/esm/sync/streaming/SSEClient/index.js +1 -5
- package/esm/sync/streaming/SSEHandler/index.js +1 -2
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +9 -23
- package/esm/sync/streaming/constants.js +0 -1
- package/esm/sync/streaming/parseUtils.js +8 -3
- package/esm/sync/streaming/pushManager.js +69 -99
- package/esm/sync/submitters/telemetrySubmitter.js +0 -4
- package/esm/sync/syncManagerOnline.js +15 -25
- package/esm/utils/constants/index.js +1 -3
- package/esm/utils/settingsValidation/index.js +2 -7
- package/package.json +1 -1
- package/src/dtos/types.ts +7 -17
- package/src/evaluator/matchers/index.ts +0 -2
- package/src/evaluator/matchers/matcherTypes.ts +0 -1
- package/src/evaluator/matchersTransform/index.ts +1 -1
- package/src/logger/constants.ts +1 -0
- package/src/logger/messages/info.ts +2 -1
- package/src/readiness/readinessManager.ts +9 -13
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +2 -3
- package/src/sdkClient/sdkClientMethodCS.ts +2 -2
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +2 -2
- package/src/sdkFactory/index.ts +1 -1
- package/src/services/decorateHeaders.ts +40 -0
- package/src/services/splitApi.ts +2 -7
- package/src/services/splitHttpClient.ts +6 -5
- package/src/services/types.ts +0 -1
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -2
- package/src/storages/AbstractSplitsCacheSync.ts +5 -4
- package/src/storages/KeyBuilder.ts +0 -3
- package/src/storages/KeyBuilderCS.ts +5 -25
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +3 -3
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +5 -20
- package/src/storages/inLocalStorage/index.ts +4 -8
- package/src/storages/inMemory/InMemoryStorageCS.ts +0 -5
- package/src/storages/inMemory/SplitsCacheInMemory.ts +10 -15
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +11 -7
- package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
- package/src/storages/types.ts +5 -7
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +2 -6
- package/src/sync/polling/pollingManagerCS.ts +29 -61
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +10 -10
- package/src/sync/polling/types.ts +3 -4
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +20 -17
- package/src/sync/streaming/SSEClient/index.ts +7 -10
- package/src/sync/streaming/SSEHandler/index.ts +1 -2
- package/src/sync/streaming/SSEHandler/types.ts +2 -14
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +10 -26
- package/src/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +1 -1
- package/src/sync/streaming/UpdateWorkers/types.ts +2 -2
- package/src/sync/streaming/constants.ts +0 -1
- package/src/sync/streaming/parseUtils.ts +10 -6
- package/src/sync/streaming/pushManager.ts +67 -103
- package/src/sync/streaming/types.ts +3 -5
- package/src/sync/submitters/telemetrySubmitter.ts +0 -4
- package/src/sync/submitters/types.ts +4 -11
- package/src/sync/syncManagerOnline.ts +11 -19
- package/src/types.ts +9 -28
- package/src/utils/constants/index.ts +1 -3
- package/src/utils/settingsValidation/index.ts +3 -8
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +6 -14
- package/types/logger/constants.d.ts +1 -0
- package/types/readiness/readinessManager.d.ts +2 -2
- package/types/readiness/sdkReadinessManager.d.ts +3 -2
- package/types/readiness/types.d.ts +2 -3
- package/types/services/decorateHeaders.d.ts +2 -0
- package/types/services/splitApi.d.ts +1 -1
- package/types/services/splitHttpClient.d.ts +1 -1
- package/types/services/types.d.ts +0 -1
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +3 -3
- package/types/storages/KeyBuilder.d.ts +0 -1
- package/types/storages/KeyBuilderCS.d.ts +2 -7
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +2 -3
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +6 -4
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
- package/types/storages/types.d.ts +3 -4
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +3 -2
- package/types/sync/polling/types.d.ts +3 -10
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +4 -4
- package/types/sync/streaming/SSEClient/index.d.ts +0 -1
- package/types/sync/streaming/SSEHandler/types.d.ts +2 -13
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -3
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +1 -2
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +2 -3
- package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
- package/types/sync/streaming/constants.d.ts +0 -1
- package/types/sync/streaming/parseUtils.d.ts +4 -2
- package/types/sync/streaming/pushManager.d.ts +0 -2
- package/types/sync/streaming/types.d.ts +4 -5
- package/types/sync/submitters/types.d.ts +3 -10
- package/types/types.d.ts +11 -26
- package/types/utils/constants/index.d.ts +1 -3
- package/types/utils/settingsValidation/index.d.ts +0 -2
- package/types/utils/settingsValidation/types.d.ts +1 -1
- package/cjs/evaluator/matchers/large_segment.js +0 -16
- package/esm/evaluator/matchers/large_segment.js +0 -12
- package/src/evaluator/matchers/large_segment.ts +0 -18
|
@@ -14,7 +14,7 @@ import { IUpdateWorker } from './types';
|
|
|
14
14
|
/**
|
|
15
15
|
* SplitsUpdateWorker factory
|
|
16
16
|
*/
|
|
17
|
-
export function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker
|
|
17
|
+
export function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker & { killSplit(event: ISplitKillData): void } {
|
|
18
18
|
|
|
19
19
|
let maxChangeNumber = 0;
|
|
20
20
|
let handleNewEvent = false;
|
|
@@ -30,7 +30,6 @@ export const MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
|
|
|
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 MY_LARGE_SEGMENTS_UPDATE = 'MY_LARGE_SEGMENTS_UPDATE';
|
|
34
33
|
|
|
35
34
|
// Control-type push notifications, handled by NotificationKeeper
|
|
36
35
|
export const CONTROL = 'CONTROL';
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import { algorithms } from '../../utils/decompress';
|
|
2
2
|
import { decodeFromBase64 } from '../../utils/base64';
|
|
3
3
|
import { Compression, KeyList } from './SSEHandler/types';
|
|
4
|
-
import { ISplit } from '../../dtos/types';
|
|
5
4
|
|
|
6
5
|
const GZIP = 1;
|
|
7
6
|
const ZLIB = 2;
|
|
@@ -43,7 +42,7 @@ function decompress(data: string, compression: Compression) {
|
|
|
43
42
|
* @returns {{a?: string[], r?: string[] }}
|
|
44
43
|
* @throws if data string cannot be decoded, decompressed or parsed
|
|
45
44
|
*/
|
|
46
|
-
export function parseKeyList(data: string, compression: Compression, avoidPrecisionLoss = true): KeyList {
|
|
45
|
+
export function parseKeyList(data: string, compression: Compression, avoidPrecisionLoss: boolean = true): KeyList {
|
|
47
46
|
const binKeyList = decompress(data, compression);
|
|
48
47
|
let strKeyList = Uint8ArrayToString(binKeyList);
|
|
49
48
|
// replace numbers to strings, to avoid losing precision
|
|
@@ -81,9 +80,14 @@ export function isInBitmap(bitmap: Uint8Array, hash64hex: string) {
|
|
|
81
80
|
|
|
82
81
|
/**
|
|
83
82
|
* Parse feature flags notifications for instant feature flag updates
|
|
83
|
+
*
|
|
84
|
+
* @param {ISplitUpdateData} data
|
|
85
|
+
* @returns {KeyList}
|
|
84
86
|
*/
|
|
85
|
-
export function parseFFUpdatePayload(compression: Compression, data: string):
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
87
|
+
export function parseFFUpdatePayload(compression: Compression, data: string): KeyList | undefined {
|
|
88
|
+
const avoidPrecisionLoss = false;
|
|
89
|
+
if (compression > 0)
|
|
90
|
+
return parseKeyList(data, compression, avoidPrecisionLoss);
|
|
91
|
+
else
|
|
92
|
+
return JSON.parse(decodeFromBase64(data));
|
|
89
93
|
}
|
|
@@ -11,25 +11,16 @@ 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 { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, PUSH_NONRETRYABLE_ERROR, PUSH_SUBSYSTEM_DOWN, SECONDS_BEFORE_EXPIRATION, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, PUSH_RETRYABLE_ERROR, PUSH_SUBSYSTEM_UP, ControlType
|
|
14
|
+
import { MY_SEGMENTS_UPDATE, MY_SEGMENTS_UPDATE_V2, 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
15
|
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT, STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
|
|
16
|
-
import {
|
|
16
|
+
import { KeyList, UpdateStrategy } from './SSEHandler/types';
|
|
17
17
|
import { isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
|
|
18
18
|
import { ISet, _Set } from '../../utils/lang/sets';
|
|
19
|
-
import { hash } from '../../utils/murmur3/murmur3';
|
|
20
19
|
import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
|
|
21
20
|
import { IAuthTokenPushEnabled } from './AuthClient/types';
|
|
22
|
-
import { TOKEN_REFRESH, AUTH_REJECTION
|
|
21
|
+
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
23
22
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
24
|
-
|
|
25
|
-
export function getDelay(parsedData: Pick<IMyLargeSegmentsUpdateData, 'i' | 'h' | 's'>, matchingKey: string) {
|
|
26
|
-
if (parsedData.h === 0) return 0;
|
|
27
|
-
|
|
28
|
-
const interval = parsedData.i || 60000;
|
|
29
|
-
const seed = parsedData.s || 0;
|
|
30
|
-
|
|
31
|
-
return hash(matchingKey, seed) % interval;
|
|
32
|
-
}
|
|
23
|
+
import { IUpdateWorker } from './UpdateWorkers/types';
|
|
33
24
|
|
|
34
25
|
/**
|
|
35
26
|
* PushManager factory:
|
|
@@ -73,7 +64,7 @@ export function pushManagerFactory(
|
|
|
73
64
|
const userKeyHashes: Record<string, string> = {};
|
|
74
65
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
75
66
|
// Hash64 is used to process MY_SEGMENTS_UPDATE_V2 events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
76
|
-
const clients: Record<string, { hash64: Hash64, worker:
|
|
67
|
+
const clients: Record<string, { hash64: Hash64, worker: IUpdateWorker }> = {};
|
|
77
68
|
|
|
78
69
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
79
70
|
let connectForNewClient = false;
|
|
@@ -180,10 +171,7 @@ export function pushManagerFactory(
|
|
|
180
171
|
// cancel scheduled fetch retries of Splits, Segments, and MySegments Update Workers
|
|
181
172
|
function stopWorkers() {
|
|
182
173
|
splitsUpdateWorker.stop();
|
|
183
|
-
if (userKey) forOwn(clients, ({ worker
|
|
184
|
-
worker.stop();
|
|
185
|
-
workerLarge && workerLarge.stop();
|
|
186
|
-
});
|
|
174
|
+
if (userKey) forOwn(clients, ({ worker }) => worker.stop());
|
|
187
175
|
else segmentsUpdateWorker!.stop();
|
|
188
176
|
}
|
|
189
177
|
|
|
@@ -248,96 +236,76 @@ export function pushManagerFactory(
|
|
|
248
236
|
splitsUpdateWorker.put(parsedData);
|
|
249
237
|
});
|
|
250
238
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
} catch (e) {
|
|
260
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
261
|
-
break;
|
|
262
|
-
}
|
|
263
|
-
|
|
264
|
-
forOwn(clients, ({ hash64, worker, workerLarge }, matchingKey) => {
|
|
265
|
-
if (isInBitmap(bitmap, hash64.hex)) {
|
|
266
|
-
isLS ?
|
|
267
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
268
|
-
worker.put(parsedData.changeNumber);
|
|
269
|
-
}
|
|
270
|
-
});
|
|
271
|
-
return;
|
|
239
|
+
if (userKey) {
|
|
240
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
|
|
241
|
+
const userKeyHash = channel.split('_')[2];
|
|
242
|
+
const userKey = userKeyHashes[userKeyHash];
|
|
243
|
+
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
244
|
+
clients[userKey].worker.put(
|
|
245
|
+
parsedData.changeNumber,
|
|
246
|
+
parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
272
247
|
}
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
248
|
+
});
|
|
249
|
+
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, function handleMySegmentsUpdate(parsedData) {
|
|
250
|
+
switch (parsedData.u) {
|
|
251
|
+
case UpdateStrategy.BoundedFetchRequest: {
|
|
252
|
+
let bitmap: Uint8Array;
|
|
253
|
+
try {
|
|
254
|
+
bitmap = parseBitmap(parsedData.d, parsedData.c);
|
|
255
|
+
} catch (e) {
|
|
256
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['BoundedFetchRequest', e]);
|
|
257
|
+
break;
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
forOwn(clients, ({ hash64, worker }) => {
|
|
261
|
+
if (isInBitmap(bitmap, hash64.hex)) {
|
|
262
|
+
worker.put(parsedData.changeNumber); // fetch mySegments
|
|
263
|
+
}
|
|
264
|
+
});
|
|
265
|
+
return;
|
|
282
266
|
}
|
|
267
|
+
case UpdateStrategy.KeyList: {
|
|
268
|
+
let keyList: KeyList, added: ISet<string>, removed: ISet<string>;
|
|
269
|
+
try {
|
|
270
|
+
keyList = parseKeyList(parsedData.d, parsedData.c);
|
|
271
|
+
added = new _Set(keyList.a);
|
|
272
|
+
removed = new _Set(keyList.r);
|
|
273
|
+
} catch (e) {
|
|
274
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['KeyList', e]);
|
|
275
|
+
break;
|
|
276
|
+
}
|
|
283
277
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, [{
|
|
289
|
-
name: parsedData.largeSegments[0],
|
|
290
|
-
add
|
|
291
|
-
}]) :
|
|
292
|
-
worker.put(parsedData.changeNumber, [{
|
|
278
|
+
forOwn(clients, ({ hash64, worker }) => {
|
|
279
|
+
const add = added.has(hash64.dec) ? true : removed.has(hash64.dec) ? false : undefined;
|
|
280
|
+
if (add !== undefined) {
|
|
281
|
+
worker.put(parsedData.changeNumber, {
|
|
293
282
|
name: parsedData.segmentName,
|
|
294
283
|
add
|
|
295
|
-
}
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
}
|
|
300
|
-
case UpdateStrategy.SegmentRemoval:
|
|
301
|
-
if ((isLS && parsedData.largeSegments.length === 0) || (!isLS && !parsedData.segmentName)) {
|
|
302
|
-
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
303
|
-
break;
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
});
|
|
287
|
+
return;
|
|
304
288
|
}
|
|
289
|
+
case UpdateStrategy.SegmentRemoval:
|
|
290
|
+
if (!parsedData.segmentName) {
|
|
291
|
+
log.warn(STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, ['SegmentRemoval', 'No segment name was provided']);
|
|
292
|
+
break;
|
|
293
|
+
}
|
|
305
294
|
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, parsedData.largeSegments.map(largeSegment => ({
|
|
309
|
-
name: largeSegment,
|
|
310
|
-
add: false
|
|
311
|
-
}))) :
|
|
312
|
-
worker.put(parsedData.changeNumber, [{
|
|
295
|
+
forOwn(clients, ({ worker }) =>
|
|
296
|
+
worker.put(parsedData.changeNumber, {
|
|
313
297
|
name: parsedData.segmentName,
|
|
314
298
|
add: false
|
|
315
|
-
}
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
299
|
+
})
|
|
300
|
+
);
|
|
301
|
+
return;
|
|
302
|
+
}
|
|
319
303
|
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
isLS ?
|
|
323
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, undefined, getDelay(parsedData, matchingKey)) :
|
|
304
|
+
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
305
|
+
forOwn(clients, ({ worker }) => {
|
|
324
306
|
worker.put(parsedData.changeNumber);
|
|
307
|
+
});
|
|
325
308
|
});
|
|
326
|
-
}
|
|
327
|
-
|
|
328
|
-
if (userKey) {
|
|
329
|
-
pushEmitter.on(MY_SEGMENTS_UPDATE, function handleMySegmentsUpdate(parsedData, channel) {
|
|
330
|
-
const userKeyHash = channel.split('_')[2];
|
|
331
|
-
const userKey = userKeyHashes[userKeyHash];
|
|
332
|
-
if (userKey && clients[userKey]) { // check existence since it can be undefined if client has been destroyed
|
|
333
|
-
clients[userKey].worker.put(
|
|
334
|
-
parsedData.changeNumber,
|
|
335
|
-
parsedData.includesPayload ? parsedData.segmentList ? parsedData.segmentList : [] : undefined);
|
|
336
|
-
}
|
|
337
|
-
});
|
|
338
|
-
|
|
339
|
-
pushEmitter.on(MY_SEGMENTS_UPDATE_V2, handleMySegmentsUpdate);
|
|
340
|
-
pushEmitter.on(MY_LARGE_SEGMENTS_UPDATE, handleMySegmentsUpdate);
|
|
341
309
|
} else {
|
|
342
310
|
pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker!.put);
|
|
343
311
|
}
|
|
@@ -360,7 +328,7 @@ export function pushManagerFactory(
|
|
|
360
328
|
if (disabled || disconnected === false) return;
|
|
361
329
|
disconnected = false;
|
|
362
330
|
|
|
363
|
-
if (userKey) this.add(userKey, pollingManager.segmentsSyncTask
|
|
331
|
+
if (userKey) this.add(userKey, pollingManager.segmentsSyncTask as IMySegmentsSyncTask); // client-side
|
|
364
332
|
else setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
365
333
|
},
|
|
366
334
|
|
|
@@ -370,16 +338,12 @@ export function pushManagerFactory(
|
|
|
370
338
|
},
|
|
371
339
|
|
|
372
340
|
// [Only for client-side]
|
|
373
|
-
add(userKey: string, mySegmentsSyncTask: IMySegmentsSyncTask
|
|
341
|
+
add(userKey: string, mySegmentsSyncTask: IMySegmentsSyncTask) {
|
|
374
342
|
const hash = hashUserKey(userKey);
|
|
375
343
|
|
|
376
344
|
if (!userKeyHashes[hash]) {
|
|
377
345
|
userKeyHashes[hash] = userKey;
|
|
378
|
-
clients[userKey] = {
|
|
379
|
-
hash64: hash64(userKey),
|
|
380
|
-
worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker, MY_SEGMENT),
|
|
381
|
-
workerLarge: myLargeSegmentsSyncTask ? MySegmentsUpdateWorker(myLargeSegmentsSyncTask, telemetryTracker, MY_LARGE_SEGMENT) : undefined
|
|
382
|
-
};
|
|
346
|
+
clients[userKey] = { hash64: hash64(userKey), worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker) };
|
|
383
347
|
connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
|
|
384
348
|
|
|
385
349
|
// Reconnects in case of a new client.
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { IMySegmentsUpdateData, IMySegmentsUpdateV2Data, ISegmentUpdateData, ISplitUpdateData, ISplitKillData
|
|
1
|
+
import { IMySegmentsUpdateData, IMySegmentsUpdateV2Data, ISegmentUpdateData, ISplitUpdateData, ISplitKillData } from './SSEHandler/types';
|
|
2
2
|
import { ITask } from '../types';
|
|
3
3
|
import { IMySegmentsSyncTask } from '../polling/types';
|
|
4
4
|
import { IEventEmitter } from '../../types';
|
|
@@ -16,18 +16,16 @@ export type MY_SEGMENTS_UPDATE_V2 = 'MY_SEGMENTS_UPDATE_V2';
|
|
|
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 MY_LARGE_SEGMENTS_UPDATE = 'MY_LARGE_SEGMENTS_UPDATE';
|
|
20
19
|
|
|
21
20
|
// Control-type push notifications, handled by NotificationKeeper
|
|
22
21
|
export type CONTROL = 'CONTROL';
|
|
23
22
|
export type OCCUPANCY = 'OCCUPANCY';
|
|
24
23
|
|
|
25
|
-
export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MY_SEGMENTS_UPDATE | MY_SEGMENTS_UPDATE_V2 | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL |
|
|
24
|
+
export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MY_SEGMENTS_UPDATE | MY_SEGMENTS_UPDATE_V2 | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET
|
|
26
25
|
|
|
27
26
|
type IParsedData<T extends IPushEvent> =
|
|
28
27
|
T extends MY_SEGMENTS_UPDATE ? IMySegmentsUpdateData :
|
|
29
28
|
T extends MY_SEGMENTS_UPDATE_V2 ? IMySegmentsUpdateV2Data :
|
|
30
|
-
T extends MY_LARGE_SEGMENTS_UPDATE ? IMyLargeSegmentsUpdateData :
|
|
31
29
|
T extends SEGMENT_UPDATE ? ISegmentUpdateData :
|
|
32
30
|
T extends SPLIT_UPDATE ? ISplitUpdateData :
|
|
33
31
|
T extends SPLIT_KILL ? ISplitKillData : undefined;
|
|
@@ -47,6 +45,6 @@ export interface IPushEventEmitter extends IEventEmitter {
|
|
|
47
45
|
*/
|
|
48
46
|
export interface IPushManager extends ITask, IPushEventEmitter {
|
|
49
47
|
// Methods used in client-side, to support multiple clients
|
|
50
|
-
add(userKey: string, mySegmentsSyncTask: IMySegmentsSyncTask
|
|
48
|
+
add(userKey: string, mySegmentsSyncTask: IMySegmentsSyncTask): void,
|
|
51
49
|
remove(userKey: string): void
|
|
52
50
|
}
|
|
@@ -71,19 +71,15 @@ export function telemetryCacheConfigAdapter(telemetry: ITelemetryCacheSync, sett
|
|
|
71
71
|
pop(): TelemetryConfigStatsPayload {
|
|
72
72
|
const { urls, scheduler } = settings;
|
|
73
73
|
const isClientSide = settings.core.key !== undefined;
|
|
74
|
-
const largeSegmentsEnabled = isClientSide && settings.sync.largeSegmentsEnabled;
|
|
75
74
|
|
|
76
75
|
const { flagSetsTotal, flagSetsIgnored } = getTelemetryFlagSetsStats(settings.sync.__splitFiltersValidation);
|
|
77
76
|
|
|
78
77
|
return objectAssign(getTelemetryConfigStats(settings.mode, settings.storage.type), {
|
|
79
78
|
sE: settings.streamingEnabled,
|
|
80
|
-
lsE: largeSegmentsEnabled ? largeSegmentsEnabled : undefined,
|
|
81
|
-
wls: largeSegmentsEnabled ? settings.startup.waitForLargeSegments : undefined,
|
|
82
79
|
rR: {
|
|
83
80
|
sp: scheduler.featuresRefreshRate / 1000,
|
|
84
81
|
se: isClientSide ? undefined : scheduler.segmentsRefreshRate / 1000,
|
|
85
82
|
ms: isClientSide ? scheduler.segmentsRefreshRate / 1000 : undefined,
|
|
86
|
-
mls: largeSegmentsEnabled ? scheduler.largeSegmentsRefreshRate / 1000 : undefined,
|
|
87
83
|
im: scheduler.impressionsRefreshRate / 1000,
|
|
88
84
|
ev: scheduler.eventsPushRate / 1000,
|
|
89
85
|
te: scheduler.telemetryRefreshRate / 1000,
|
|
@@ -103,7 +103,7 @@ export type DROPPED = 1;
|
|
|
103
103
|
export type DEDUPED = 2;
|
|
104
104
|
export type ImpressionDataType = QUEUED | DROPPED | DEDUPED
|
|
105
105
|
export type EventDataType = QUEUED | DROPPED;
|
|
106
|
-
export type UpdatesFromSSEEnum = SPLITS | MY_SEGMENT
|
|
106
|
+
export type UpdatesFromSSEEnum = SPLITS | MY_SEGMENT;
|
|
107
107
|
|
|
108
108
|
export type SPLITS = 'sp';
|
|
109
109
|
export type IMPRESSIONS = 'im';
|
|
@@ -113,8 +113,7 @@ export type TELEMETRY = 'te';
|
|
|
113
113
|
export type TOKEN = 'to';
|
|
114
114
|
export type SEGMENT = 'se';
|
|
115
115
|
export type MY_SEGMENT = 'ms';
|
|
116
|
-
export type
|
|
117
|
-
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT | MY_LARGE_SEGMENT;
|
|
116
|
+
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
118
117
|
|
|
119
118
|
export type LastSync = Partial<Record<OperationType, number | undefined>>
|
|
120
119
|
export type HttpErrors = Partial<Record<OperationType, { [statusCode: string]: number }>>
|
|
@@ -159,9 +158,8 @@ export type TelemetryUsageStats = {
|
|
|
159
158
|
|
|
160
159
|
// amount of instant updates that we are doing by avoiding fetching to Split servers
|
|
161
160
|
export type UpdatesFromSSE = {
|
|
162
|
-
sp
|
|
161
|
+
sp: number, // splits
|
|
163
162
|
ms?: number, // my segments
|
|
164
|
-
mls?: number // my large segments
|
|
165
163
|
}
|
|
166
164
|
|
|
167
165
|
// 'metrics/usage' JSON request body
|
|
@@ -177,14 +175,12 @@ export type TelemetryUsageStatsPayload = TelemetryUsageStats & {
|
|
|
177
175
|
spC?: number, // splitCount
|
|
178
176
|
seC?: number, // segmentCount
|
|
179
177
|
skC?: number, // segmentKeyCount
|
|
180
|
-
lseC?: number, // largeSegmentCount
|
|
181
|
-
lskC?: number, // largeSegmentKeyCount
|
|
182
178
|
sL?: number, // sessionLengthMs
|
|
183
179
|
eQ: number, // eventsQueued
|
|
184
180
|
eD: number, // eventsDropped
|
|
185
181
|
sE: Array<StreamingEvent>, // streamingEvents
|
|
186
182
|
t?: Array<string>, // tags
|
|
187
|
-
ufs?: UpdatesFromSSE, //
|
|
183
|
+
ufs?: UpdatesFromSSE, //UpdatesFromSSE
|
|
188
184
|
}
|
|
189
185
|
|
|
190
186
|
/**
|
|
@@ -205,7 +201,6 @@ export type RefreshRates = {
|
|
|
205
201
|
sp: number, // splits
|
|
206
202
|
se?: number, // segments
|
|
207
203
|
ms?: number, // mySegments
|
|
208
|
-
mls?: number, // myLargeSegments
|
|
209
204
|
im: number, // impressions
|
|
210
205
|
ev: number, // events
|
|
211
206
|
te: number, // telemetry
|
|
@@ -231,8 +226,6 @@ export type TelemetryConfigStats = {
|
|
|
231
226
|
// 'metrics/config' JSON request body
|
|
232
227
|
export type TelemetryConfigStatsPayload = TelemetryConfigStats & {
|
|
233
228
|
sE: boolean, // streamingEnabled
|
|
234
|
-
lsE?: boolean, // largeSegmentsEnabled
|
|
235
|
-
wls?: boolean, // waitForLargeSegments
|
|
236
229
|
rR: RefreshRates, // refreshRates
|
|
237
230
|
uO: UrlOverrides, // urlOverrides
|
|
238
231
|
iQ: number, // impressionsQueueSize
|
|
@@ -7,7 +7,7 @@ import { IPollingManager, IPollingManagerCS } from './polling/types';
|
|
|
7
7
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
8
8
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
9
9
|
import { isConsentGranted } from '../consent';
|
|
10
|
-
import {
|
|
10
|
+
import { POLLING, STREAMING, SYNC_MODE_UPDATE } from '../utils/constants';
|
|
11
11
|
import { ISdkFactoryContextSync } from '../sdkFactory/types';
|
|
12
12
|
|
|
13
13
|
/**
|
|
@@ -141,44 +141,36 @@ export function syncManagerOnlineFactory(
|
|
|
141
141
|
shared(matchingKey: string, readinessManager: IReadinessManager, storage: IStorageSync) {
|
|
142
142
|
if (!pollingManager) return;
|
|
143
143
|
|
|
144
|
-
const
|
|
144
|
+
const mySegmentsSyncTask = (pollingManager as IPollingManagerCS).add(matchingKey, readinessManager, storage);
|
|
145
145
|
|
|
146
146
|
return {
|
|
147
|
-
isRunning:
|
|
147
|
+
isRunning: mySegmentsSyncTask.isRunning,
|
|
148
148
|
start() {
|
|
149
149
|
if (syncEnabled) {
|
|
150
150
|
if (pushManager) {
|
|
151
151
|
if (pollingManager!.isRunning()) {
|
|
152
152
|
// if doing polling, we must start the periodic fetch of data
|
|
153
|
-
if (storage.splits.
|
|
154
|
-
if (mlsSyncTask && storage.splits.usesMatcher(IN_LARGE_SEGMENT)) mlsSyncTask.start();
|
|
153
|
+
if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
|
|
155
154
|
} else {
|
|
156
155
|
// if not polling, we must execute the sync task for the initial fetch
|
|
157
156
|
// of segments since `syncAll` was already executed when starting the main client
|
|
158
|
-
|
|
159
|
-
mlsSyncTask && mlsSyncTask.execute();
|
|
157
|
+
mySegmentsSyncTask.execute();
|
|
160
158
|
}
|
|
161
|
-
pushManager.add(matchingKey,
|
|
159
|
+
pushManager.add(matchingKey, mySegmentsSyncTask);
|
|
162
160
|
} else {
|
|
163
|
-
if (storage.splits.
|
|
164
|
-
if (mlsSyncTask && storage.splits.usesMatcher(IN_LARGE_SEGMENT)) mlsSyncTask.start();
|
|
161
|
+
if (storage.splits.usesSegments()) mySegmentsSyncTask.start();
|
|
165
162
|
}
|
|
166
163
|
} else {
|
|
167
|
-
if (!readinessManager.isReady())
|
|
168
|
-
msSyncTask.execute();
|
|
169
|
-
mlsSyncTask && mlsSyncTask.execute();
|
|
170
|
-
}
|
|
164
|
+
if (!readinessManager.isReady()) mySegmentsSyncTask.execute();
|
|
171
165
|
}
|
|
172
166
|
},
|
|
173
167
|
stop() {
|
|
174
168
|
// check in case `client.destroy()` has been invoked more than once for the same client
|
|
175
|
-
const
|
|
176
|
-
if (
|
|
177
|
-
const { msSyncTask, mlsSyncTask } = syncTasks;
|
|
169
|
+
const mySegmentsSyncTask = (pollingManager as IPollingManagerCS).get(matchingKey);
|
|
170
|
+
if (mySegmentsSyncTask) {
|
|
178
171
|
// stop syncing
|
|
179
172
|
if (pushManager) pushManager.remove(matchingKey);
|
|
180
|
-
if (
|
|
181
|
-
if (mlsSyncTask && mlsSyncTask.isRunning()) mlsSyncTask.stop();
|
|
173
|
+
if (mySegmentsSyncTask.isRunning()) mySegmentsSyncTask.stop();
|
|
182
174
|
|
|
183
175
|
(pollingManager as IPollingManagerCS).remove(matchingKey);
|
|
184
176
|
}
|
package/src/types.ts
CHANGED
|
@@ -86,7 +86,6 @@ export interface ISettings {
|
|
|
86
86
|
metricsRefreshRate?: number,
|
|
87
87
|
telemetryRefreshRate: number,
|
|
88
88
|
segmentsRefreshRate: number,
|
|
89
|
-
largeSegmentsRefreshRate: number,
|
|
90
89
|
offlineRefreshRate: number,
|
|
91
90
|
eventsPushRate: number,
|
|
92
91
|
eventsQueueSize: number,
|
|
@@ -96,8 +95,7 @@ export interface ISettings {
|
|
|
96
95
|
readyTimeout: number,
|
|
97
96
|
requestTimeoutBeforeReady: number,
|
|
98
97
|
retriesOnFailureBeforeReady: number,
|
|
99
|
-
eventsFirstPushWindow: number
|
|
100
|
-
waitForLargeSegments: boolean
|
|
98
|
+
eventsFirstPushWindow: number
|
|
101
99
|
},
|
|
102
100
|
readonly storage: IStorageSyncFactory | IStorageAsyncFactory,
|
|
103
101
|
readonly integrations: Array<{
|
|
@@ -121,8 +119,10 @@ export interface ISettings {
|
|
|
121
119
|
__splitFiltersValidation: ISplitFiltersValidation,
|
|
122
120
|
localhostMode?: SplitIO.LocalhostFactory,
|
|
123
121
|
enabled: boolean,
|
|
124
|
-
|
|
125
|
-
|
|
122
|
+
flagSpecVersion: string,
|
|
123
|
+
requestOptions?: {
|
|
124
|
+
getHeaderOverrides?: (context: { headers: Record<string, string> }) => Record<string, string>
|
|
125
|
+
}
|
|
126
126
|
},
|
|
127
127
|
readonly runtime: {
|
|
128
128
|
ip: string | false
|
|
@@ -221,7 +221,10 @@ interface ISharedSettings {
|
|
|
221
221
|
* Enables synchronization.
|
|
222
222
|
* @property {boolean} enabled
|
|
223
223
|
*/
|
|
224
|
-
enabled
|
|
224
|
+
enabled?: boolean,
|
|
225
|
+
requestOptions?: {
|
|
226
|
+
getHeaderOverrides?: (context: { headers: Record<string, string> }) => Record<string, string>
|
|
227
|
+
},
|
|
225
228
|
}
|
|
226
229
|
}
|
|
227
230
|
/**
|
|
@@ -816,13 +819,6 @@ export namespace SplitIO {
|
|
|
816
819
|
* @default 10
|
|
817
820
|
*/
|
|
818
821
|
eventsFirstPushWindow?: number,
|
|
819
|
-
/**
|
|
820
|
-
* Whether the SDK should wait for large segments to be ready before emitting SDK_READY event.
|
|
821
|
-
* It only applies if largeSegmentsEnabled is true.
|
|
822
|
-
* @property {number} waitForLargeSegments
|
|
823
|
-
* @default true
|
|
824
|
-
*/
|
|
825
|
-
waitForLargeSegments?: boolean
|
|
826
822
|
},
|
|
827
823
|
/**
|
|
828
824
|
* SDK scheduler settings.
|
|
@@ -867,13 +863,6 @@ export namespace SplitIO {
|
|
|
867
863
|
* @default 60
|
|
868
864
|
*/
|
|
869
865
|
segmentsRefreshRate?: number,
|
|
870
|
-
/**
|
|
871
|
-
* The SDK polls Split servers for changes to large segment definitions. This parameter controls this polling period in seconds.
|
|
872
|
-
* It only applies if largeSegmentsEnabled is true.
|
|
873
|
-
* @property {number} largeSegmentsRefreshRate
|
|
874
|
-
* @default 60
|
|
875
|
-
*/
|
|
876
|
-
largeSegmentsRefreshRate?: number,
|
|
877
866
|
/**
|
|
878
867
|
* The SDK posts the queued events data in bulks. This parameter controls the posting rate in seconds.
|
|
879
868
|
* @property {number} eventsPushRate
|
|
@@ -946,14 +935,6 @@ export namespace SplitIO {
|
|
|
946
935
|
* @property {Object} urls
|
|
947
936
|
*/
|
|
948
937
|
urls?: UrlSettings,
|
|
949
|
-
sync?: ISharedSettings['sync'] & {
|
|
950
|
-
/**
|
|
951
|
-
* Enables synchronization of large segments.
|
|
952
|
-
* @property {boolean} largeSegmentsEnabled
|
|
953
|
-
* @default false
|
|
954
|
-
*/
|
|
955
|
-
largeSegmentsEnabled?: boolean
|
|
956
|
-
}
|
|
957
938
|
}
|
|
958
939
|
/**
|
|
959
940
|
* Settings interface for SDK instances created on NodeJS.
|
|
@@ -76,7 +76,6 @@ export const TELEMETRY = 'te';
|
|
|
76
76
|
export const TOKEN = 'to';
|
|
77
77
|
export const SEGMENT = 'se';
|
|
78
78
|
export const MY_SEGMENT = 'ms';
|
|
79
|
-
export const MY_LARGE_SEGMENT = 'mls';
|
|
80
79
|
|
|
81
80
|
export const TREATMENT = 't';
|
|
82
81
|
export const TREATMENTS = 'ts';
|
|
@@ -106,8 +105,7 @@ export const DISABLED = 0;
|
|
|
106
105
|
export const ENABLED = 1;
|
|
107
106
|
export const PAUSED = 2;
|
|
108
107
|
|
|
109
|
-
export const FLAG_SPEC_VERSION = '1.
|
|
108
|
+
export const FLAG_SPEC_VERSION = '1.1';
|
|
110
109
|
|
|
111
110
|
// Matcher types
|
|
112
111
|
export const IN_SEGMENT = 'IN_SEGMENT';
|
|
113
|
-
export const IN_LARGE_SEGMENT = 'IN_LARGE_SEGMENT';
|
|
@@ -32,8 +32,6 @@ export const base = {
|
|
|
32
32
|
featuresRefreshRate: 60,
|
|
33
33
|
// fetch segments updates each 60 sec
|
|
34
34
|
segmentsRefreshRate: 60,
|
|
35
|
-
// fetch large segments updates each 60 sec
|
|
36
|
-
largeSegmentsRefreshRate: 60,
|
|
37
35
|
// publish telemetry stats each 3600 secs (1 hour)
|
|
38
36
|
telemetryRefreshRate: 3600,
|
|
39
37
|
// publish evaluations each 300 sec (default value for OPTIMIZED impressions mode)
|
|
@@ -87,8 +85,7 @@ export const base = {
|
|
|
87
85
|
impressionsMode: OPTIMIZED,
|
|
88
86
|
localhostMode: undefined,
|
|
89
87
|
enabled: true,
|
|
90
|
-
flagSpecVersion: FLAG_SPEC_VERSION
|
|
91
|
-
largeSegmentsEnabled: false
|
|
88
|
+
flagSpecVersion: FLAG_SPEC_VERSION
|
|
92
89
|
},
|
|
93
90
|
|
|
94
91
|
// Logger
|
|
@@ -135,7 +132,6 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
135
132
|
const { scheduler, startup } = withDefaults;
|
|
136
133
|
scheduler.featuresRefreshRate = fromSecondsToMillis(scheduler.featuresRefreshRate);
|
|
137
134
|
scheduler.segmentsRefreshRate = fromSecondsToMillis(scheduler.segmentsRefreshRate);
|
|
138
|
-
scheduler.largeSegmentsRefreshRate = fromSecondsToMillis(scheduler.largeSegmentsRefreshRate);
|
|
139
135
|
scheduler.offlineRefreshRate = fromSecondsToMillis(scheduler.offlineRefreshRate);
|
|
140
136
|
scheduler.eventsPushRate = fromSecondsToMillis(scheduler.eventsPushRate);
|
|
141
137
|
scheduler.telemetryRefreshRate = fromSecondsToMillis(validateMinValue('telemetryRefreshRate', scheduler.telemetryRefreshRate, 60));
|
|
@@ -213,12 +209,11 @@ export function settingsValidation(config: unknown, validationParams: ISettingsV
|
|
|
213
209
|
const splitFiltersValidation = validateSplitFilters(log, sync.splitFilters, withDefaults.mode);
|
|
214
210
|
sync.splitFilters = splitFiltersValidation.validFilters;
|
|
215
211
|
sync.__splitFiltersValidation = splitFiltersValidation;
|
|
216
|
-
|
|
217
|
-
// ensure a valid flag spec version
|
|
218
212
|
sync.flagSpecVersion = flagSpec ? flagSpec(withDefaults) : FLAG_SPEC_VERSION;
|
|
213
|
+
|
|
219
214
|
// ensure a valid user consent value
|
|
220
215
|
// @ts-ignore, modify readonly prop
|
|
221
|
-
withDefaults.userConsent = consent
|
|
216
|
+
withDefaults.userConsent = consent(withDefaults);
|
|
222
217
|
|
|
223
218
|
return withDefaults;
|
|
224
219
|
}
|
|
@@ -25,7 +25,7 @@ export interface ISettingsValidationParams {
|
|
|
25
25
|
/** Localhost mode validator (`settings.sync.localhostMode`) */
|
|
26
26
|
localhost?: (settings: ISettings) => ISettings['sync']['localhostMode'],
|
|
27
27
|
/** User consent validator (`settings.userConsent`) */
|
|
28
|
-
consent
|
|
28
|
+
consent: (settings: ISettings) => ISettings['userConsent'],
|
|
29
29
|
/** Flag spec version validation. Configurable by the JS Synchronizer but not by the SDKs */
|
|
30
30
|
flagSpec?: (settings: ISettings) => ISettings['sync']['flagSpecVersion']
|
|
31
31
|
}
|