@splitsoftware/splitio-commons 1.16.1-rc.1 → 1.16.1-rc.3
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/cjs/logger/messages/info.js +1 -1
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +15 -15
- package/cjs/sync/streaming/parseUtils.js +3 -8
- package/cjs/sync/streaming/pushManager.js +15 -17
- package/esm/logger/messages/info.js +1 -1
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +15 -15
- package/esm/sync/streaming/parseUtils.js +3 -8
- package/esm/sync/streaming/pushManager.js +15 -17
- package/package.json +1 -1
- package/src/logger/messages/info.ts +1 -1
- package/src/sync/polling/types.ts +1 -1
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +12 -12
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +2 -2
- 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/parseUtils.ts +6 -10
- package/src/sync/streaming/pushManager.ts +11 -14
- package/types/sync/polling/types.d.ts +1 -1
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -2
- package/types/sync/streaming/UpdateWorkers/SegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/UpdateWorkers/SplitsUpdateWorker.d.ts +3 -2
- package/types/sync/streaming/UpdateWorkers/types.d.ts +2 -2
- package/types/sync/streaming/parseUtils.d.ts +2 -4
|
@@ -23,7 +23,7 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
23
23
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
24
24
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
25
25
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
26
|
-
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and
|
|
26
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and resetting timer.'],
|
|
27
27
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
28
28
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
29
29
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -3,6 +3,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.mySegmentsUpdaterFactory = void 0;
|
|
4
4
|
var timeout_1 = require("../../../utils/promise/timeout");
|
|
5
5
|
var constants_1 = require("../../../logger/constants");
|
|
6
|
+
var lang_1 = require("../../../utils/lang");
|
|
6
7
|
/**
|
|
7
8
|
* factory of MySegments updater, a task that:
|
|
8
9
|
* - fetches mySegments using `mySegmentsFetcher`
|
|
@@ -21,23 +22,22 @@ function mySegmentsUpdaterFactory(log, mySegmentsFetcher, mySegmentsCache, notif
|
|
|
21
22
|
// @TODO if allowing pluggable storages, handle async execution
|
|
22
23
|
function updateSegments(segmentsData) {
|
|
23
24
|
var shouldNotifyUpdate;
|
|
24
|
-
if (
|
|
25
|
-
//
|
|
26
|
-
|
|
25
|
+
if ((0, lang_1.isObject)(segmentsData[0])) {
|
|
26
|
+
// Add/Delete the segment names
|
|
27
|
+
segmentsData.forEach(function (_a) {
|
|
28
|
+
var name = _a.name, add = _a.add;
|
|
29
|
+
if (mySegmentsCache.isInSegment(name) !== add) {
|
|
30
|
+
shouldNotifyUpdate = true;
|
|
31
|
+
if (add)
|
|
32
|
+
mySegmentsCache.addToSegment(name);
|
|
33
|
+
else
|
|
34
|
+
mySegmentsCache.removeFromSegment(name);
|
|
35
|
+
}
|
|
36
|
+
});
|
|
27
37
|
}
|
|
28
38
|
else {
|
|
29
|
-
//
|
|
30
|
-
|
|
31
|
-
if (mySegmentsCache.isInSegment(name_1) !== add) {
|
|
32
|
-
shouldNotifyUpdate = true;
|
|
33
|
-
if (add)
|
|
34
|
-
mySegmentsCache.addToSegment(name_1);
|
|
35
|
-
else
|
|
36
|
-
mySegmentsCache.removeFromSegment(name_1);
|
|
37
|
-
}
|
|
38
|
-
else {
|
|
39
|
-
shouldNotifyUpdate = false;
|
|
40
|
-
}
|
|
39
|
+
// Reset the list of segment names
|
|
40
|
+
shouldNotifyUpdate = mySegmentsCache.resetSegments(segmentsData);
|
|
41
41
|
}
|
|
42
42
|
// Notify update if required
|
|
43
43
|
if (shouldNotifyUpdate || readyOnAlreadyExistentState) {
|
|
@@ -80,15 +80,10 @@ function isInBitmap(bitmap, hash64hex) {
|
|
|
80
80
|
exports.isInBitmap = isInBitmap;
|
|
81
81
|
/**
|
|
82
82
|
* Parse feature flags notifications for instant feature flag updates
|
|
83
|
-
*
|
|
84
|
-
* @param {ISplitUpdateData} data
|
|
85
|
-
* @returns {KeyList}
|
|
86
83
|
*/
|
|
87
84
|
function parseFFUpdatePayload(compression, data) {
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
else
|
|
92
|
-
return JSON.parse((0, base64_1.decodeFromBase64)(data));
|
|
85
|
+
return compression > 0 ?
|
|
86
|
+
parseKeyList(data, compression, false) :
|
|
87
|
+
JSON.parse((0, base64_1.decodeFromBase64)(data));
|
|
93
88
|
}
|
|
94
89
|
exports.parseFFUpdatePayload = parseFFUpdatePayload;
|
|
@@ -244,14 +244,14 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
244
244
|
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
245
245
|
if (add !== undefined) {
|
|
246
246
|
isLS ?
|
|
247
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
worker.put(parsedData.changeNumber, {
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
247
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, [{
|
|
248
|
+
name: parsedData.largeSegments[0],
|
|
249
|
+
add: add
|
|
250
|
+
}]) :
|
|
251
|
+
worker.put(parsedData.changeNumber, [{
|
|
252
|
+
name: parsedData.segmentName,
|
|
253
|
+
add: add
|
|
254
|
+
}]);
|
|
255
255
|
}
|
|
256
256
|
});
|
|
257
257
|
return;
|
|
@@ -264,16 +264,14 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
264
264
|
(0, lang_1.forOwn)(clients, function (_a) {
|
|
265
265
|
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
266
266
|
isLS ?
|
|
267
|
-
workerLarge && parsedData.largeSegments.
|
|
268
|
-
|
|
269
|
-
name: largeSegment,
|
|
270
|
-
add: false
|
|
271
|
-
});
|
|
272
|
-
}) :
|
|
273
|
-
worker.put(parsedData.changeNumber, {
|
|
274
|
-
name: parsedData.segmentName,
|
|
267
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, parsedData.largeSegments.map(function (largeSegment) { return ({
|
|
268
|
+
name: largeSegment,
|
|
275
269
|
add: false
|
|
276
|
-
});
|
|
270
|
+
}); })) :
|
|
271
|
+
worker.put(parsedData.changeNumber, [{
|
|
272
|
+
name: parsedData.segmentName,
|
|
273
|
+
add: false
|
|
274
|
+
}]);
|
|
277
275
|
});
|
|
278
276
|
return;
|
|
279
277
|
}
|
|
@@ -19,7 +19,7 @@ export var codesInfo = codesWarn.concat([
|
|
|
19
19
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
20
20
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
21
21
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
22
|
-
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and
|
|
22
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and resetting timer.'],
|
|
23
23
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
24
24
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
25
25
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { timeout } from '../../../utils/promise/timeout';
|
|
2
2
|
import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
|
|
3
|
+
import { isObject } from '../../../utils/lang';
|
|
3
4
|
/**
|
|
4
5
|
* factory of MySegments updater, a task that:
|
|
5
6
|
* - fetches mySegments using `mySegmentsFetcher`
|
|
@@ -18,23 +19,22 @@ export function mySegmentsUpdaterFactory(log, mySegmentsFetcher, mySegmentsCache
|
|
|
18
19
|
// @TODO if allowing pluggable storages, handle async execution
|
|
19
20
|
function updateSegments(segmentsData) {
|
|
20
21
|
var shouldNotifyUpdate;
|
|
21
|
-
if (
|
|
22
|
-
//
|
|
23
|
-
|
|
22
|
+
if (isObject(segmentsData[0])) {
|
|
23
|
+
// Add/Delete the segment names
|
|
24
|
+
segmentsData.forEach(function (_a) {
|
|
25
|
+
var name = _a.name, add = _a.add;
|
|
26
|
+
if (mySegmentsCache.isInSegment(name) !== add) {
|
|
27
|
+
shouldNotifyUpdate = true;
|
|
28
|
+
if (add)
|
|
29
|
+
mySegmentsCache.addToSegment(name);
|
|
30
|
+
else
|
|
31
|
+
mySegmentsCache.removeFromSegment(name);
|
|
32
|
+
}
|
|
33
|
+
});
|
|
24
34
|
}
|
|
25
35
|
else {
|
|
26
|
-
//
|
|
27
|
-
|
|
28
|
-
if (mySegmentsCache.isInSegment(name_1) !== add) {
|
|
29
|
-
shouldNotifyUpdate = true;
|
|
30
|
-
if (add)
|
|
31
|
-
mySegmentsCache.addToSegment(name_1);
|
|
32
|
-
else
|
|
33
|
-
mySegmentsCache.removeFromSegment(name_1);
|
|
34
|
-
}
|
|
35
|
-
else {
|
|
36
|
-
shouldNotifyUpdate = false;
|
|
37
|
-
}
|
|
36
|
+
// Reset the list of segment names
|
|
37
|
+
shouldNotifyUpdate = mySegmentsCache.resetSegments(segmentsData);
|
|
38
38
|
}
|
|
39
39
|
// Notify update if required
|
|
40
40
|
if (shouldNotifyUpdate || readyOnAlreadyExistentState) {
|
|
@@ -74,14 +74,9 @@ export function isInBitmap(bitmap, hash64hex) {
|
|
|
74
74
|
}
|
|
75
75
|
/**
|
|
76
76
|
* Parse feature flags notifications for instant feature flag updates
|
|
77
|
-
*
|
|
78
|
-
* @param {ISplitUpdateData} data
|
|
79
|
-
* @returns {KeyList}
|
|
80
77
|
*/
|
|
81
78
|
export function parseFFUpdatePayload(compression, data) {
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
else
|
|
86
|
-
return JSON.parse(decodeFromBase64(data));
|
|
79
|
+
return compression > 0 ?
|
|
80
|
+
parseKeyList(data, compression, false) :
|
|
81
|
+
JSON.parse(decodeFromBase64(data));
|
|
87
82
|
}
|
|
@@ -240,14 +240,14 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
240
240
|
var add = added_1.has(hash64.dec) ? true : removed_1.has(hash64.dec) ? false : undefined;
|
|
241
241
|
if (add !== undefined) {
|
|
242
242
|
isLS ?
|
|
243
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, {
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
worker.put(parsedData.changeNumber, {
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
243
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, [{
|
|
244
|
+
name: parsedData.largeSegments[0],
|
|
245
|
+
add: add
|
|
246
|
+
}]) :
|
|
247
|
+
worker.put(parsedData.changeNumber, [{
|
|
248
|
+
name: parsedData.segmentName,
|
|
249
|
+
add: add
|
|
250
|
+
}]);
|
|
251
251
|
}
|
|
252
252
|
});
|
|
253
253
|
return;
|
|
@@ -260,16 +260,14 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
260
260
|
forOwn(clients, function (_a) {
|
|
261
261
|
var worker = _a.worker, workerLarge = _a.workerLarge;
|
|
262
262
|
isLS ?
|
|
263
|
-
workerLarge && parsedData.largeSegments.
|
|
264
|
-
|
|
265
|
-
name: largeSegment,
|
|
266
|
-
add: false
|
|
267
|
-
});
|
|
268
|
-
}) :
|
|
269
|
-
worker.put(parsedData.changeNumber, {
|
|
270
|
-
name: parsedData.segmentName,
|
|
263
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, parsedData.largeSegments.map(function (largeSegment) { return ({
|
|
264
|
+
name: largeSegment,
|
|
271
265
|
add: false
|
|
272
|
-
});
|
|
266
|
+
}); })) :
|
|
267
|
+
worker.put(parsedData.changeNumber, [{
|
|
268
|
+
name: parsedData.segmentName,
|
|
269
|
+
add: false
|
|
270
|
+
}]);
|
|
273
271
|
});
|
|
274
272
|
return;
|
|
275
273
|
}
|
package/package.json
CHANGED
|
@@ -22,7 +22,7 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
22
22
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
23
23
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
24
24
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
25
|
-
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and
|
|
25
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and resetting timer.'],
|
|
26
26
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
27
27
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
28
28
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -12,7 +12,7 @@ export type MySegmentsData = string[] | {
|
|
|
12
12
|
name: string,
|
|
13
13
|
/* action: `true` for add, and `false` for delete */
|
|
14
14
|
add: boolean
|
|
15
|
-
}
|
|
15
|
+
}[]
|
|
16
16
|
|
|
17
17
|
export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean], boolean> { }
|
|
18
18
|
|
|
@@ -4,6 +4,7 @@ import { timeout } from '../../../utils/promise/timeout';
|
|
|
4
4
|
import { ILogger } from '../../../logger/types';
|
|
5
5
|
import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
|
|
6
6
|
import { MySegmentsData } from '../types';
|
|
7
|
+
import { isObject } from '../../../utils/lang';
|
|
7
8
|
|
|
8
9
|
type IMySegmentsUpdater = (segmentList?: MySegmentsData, noCache?: boolean) => Promise<boolean>
|
|
9
10
|
|
|
@@ -36,19 +37,18 @@ export function mySegmentsUpdaterFactory(
|
|
|
36
37
|
function updateSegments(segmentsData: MySegmentsData) {
|
|
37
38
|
|
|
38
39
|
let shouldNotifyUpdate;
|
|
39
|
-
if (
|
|
40
|
-
//
|
|
41
|
-
|
|
40
|
+
if (isObject(segmentsData[0])) {
|
|
41
|
+
// Add/Delete the segment names
|
|
42
|
+
(segmentsData as { name: string, add: boolean }[]).forEach(({ name, add }) => {
|
|
43
|
+
if (mySegmentsCache.isInSegment(name) !== add) {
|
|
44
|
+
shouldNotifyUpdate = true;
|
|
45
|
+
if (add) mySegmentsCache.addToSegment(name);
|
|
46
|
+
else mySegmentsCache.removeFromSegment(name);
|
|
47
|
+
}
|
|
48
|
+
});
|
|
42
49
|
} else {
|
|
43
|
-
//
|
|
44
|
-
|
|
45
|
-
if (mySegmentsCache.isInSegment(name) !== add) {
|
|
46
|
-
shouldNotifyUpdate = true;
|
|
47
|
-
if (add) mySegmentsCache.addToSegment(name);
|
|
48
|
-
else mySegmentsCache.removeFromSegment(name);
|
|
49
|
-
} else {
|
|
50
|
-
shouldNotifyUpdate = false;
|
|
51
|
-
}
|
|
50
|
+
// Reset the list of segment names
|
|
51
|
+
shouldNotifyUpdate = mySegmentsCache.resetSegments(segmentsData as string[]);
|
|
52
52
|
}
|
|
53
53
|
|
|
54
54
|
// Notify update if required
|
|
@@ -7,7 +7,7 @@ import { UpdatesFromSSEEnum } from '../../submitters/types';
|
|
|
7
7
|
/**
|
|
8
8
|
* MySegmentsUpdateWorker factory
|
|
9
9
|
*/
|
|
10
|
-
export function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker, updateType: UpdatesFromSSEEnum): IUpdateWorker {
|
|
10
|
+
export function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker, updateType: UpdatesFromSSEEnum): IUpdateWorker<[changeNumber: number, segmentsData?: MySegmentsData, delay?: number]> {
|
|
11
11
|
|
|
12
12
|
let maxChangeNumber = 0; // keeps the maximum changeNumber among queued events
|
|
13
13
|
let currentChangeNumber = -1;
|
|
@@ -15,7 +15,7 @@ export function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask,
|
|
|
15
15
|
let isHandlingEvent: boolean;
|
|
16
16
|
let _segmentsData: MySegmentsData | undefined; // keeps the segmentsData (if included in notification payload) from the queued event with maximum changeNumber
|
|
17
17
|
let _delay: undefined | number;
|
|
18
|
-
let _delayTimeoutID:
|
|
18
|
+
let _delayTimeoutID: any;
|
|
19
19
|
const backoff = new Backoff(__handleMySegmentsUpdateCall);
|
|
20
20
|
|
|
21
21
|
function __handleMySegmentsUpdateCall() {
|
|
@@ -9,7 +9,7 @@ import { IUpdateWorker } from './types';
|
|
|
9
9
|
/**
|
|
10
10
|
* SegmentsUpdateWorker factory
|
|
11
11
|
*/
|
|
12
|
-
export function SegmentsUpdateWorker(log: ILogger, segmentsSyncTask: ISegmentsSyncTask, segmentsCache: ISegmentsCacheSync): IUpdateWorker {
|
|
12
|
+
export function SegmentsUpdateWorker(log: ILogger, segmentsSyncTask: ISegmentsSyncTask, segmentsCache: ISegmentsCacheSync): IUpdateWorker<[ISegmentUpdateData]> {
|
|
13
13
|
|
|
14
14
|
// Handles retries with CDN bypass per segment name
|
|
15
15
|
function SegmentUpdateWorker(segment: string) {
|
|
@@ -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 & { killSplit(event: ISplitKillData): void } {
|
|
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 } {
|
|
18
18
|
|
|
19
19
|
let maxChangeNumber = 0;
|
|
20
20
|
let handleNewEvent = false;
|
|
@@ -1,6 +1,7 @@
|
|
|
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';
|
|
4
5
|
|
|
5
6
|
const GZIP = 1;
|
|
6
7
|
const ZLIB = 2;
|
|
@@ -42,7 +43,7 @@ function decompress(data: string, compression: Compression) {
|
|
|
42
43
|
* @returns {{a?: string[], r?: string[] }}
|
|
43
44
|
* @throws if data string cannot be decoded, decompressed or parsed
|
|
44
45
|
*/
|
|
45
|
-
export function parseKeyList(data: string, compression: Compression, avoidPrecisionLoss
|
|
46
|
+
export function parseKeyList(data: string, compression: Compression, avoidPrecisionLoss = true): KeyList {
|
|
46
47
|
const binKeyList = decompress(data, compression);
|
|
47
48
|
let strKeyList = Uint8ArrayToString(binKeyList);
|
|
48
49
|
// replace numbers to strings, to avoid losing precision
|
|
@@ -80,14 +81,9 @@ export function isInBitmap(bitmap: Uint8Array, hash64hex: string) {
|
|
|
80
81
|
|
|
81
82
|
/**
|
|
82
83
|
* Parse feature flags notifications for instant feature flag updates
|
|
83
|
-
*
|
|
84
|
-
* @param {ISplitUpdateData} data
|
|
85
|
-
* @returns {KeyList}
|
|
86
84
|
*/
|
|
87
|
-
export function parseFFUpdatePayload(compression: Compression, data: string):
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
else
|
|
92
|
-
return JSON.parse(decodeFromBase64(data));
|
|
85
|
+
export function parseFFUpdatePayload(compression: Compression, data: string): ISplit | undefined {
|
|
86
|
+
return compression > 0 ?
|
|
87
|
+
parseKeyList(data, compression, false) :
|
|
88
|
+
JSON.parse(decodeFromBase64(data));
|
|
93
89
|
}
|
|
@@ -21,7 +21,6 @@ import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
|
|
|
21
21
|
import { IAuthTokenPushEnabled } from './AuthClient/types';
|
|
22
22
|
import { TOKEN_REFRESH, AUTH_REJECTION, MY_LARGE_SEGMENT, MY_SEGMENT } from '../../utils/constants';
|
|
23
23
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
24
|
-
import { IUpdateWorker } from './UpdateWorkers/types';
|
|
25
24
|
|
|
26
25
|
export function getDelay(parsedData: Pick<IMyLargeSegmentsUpdateData, 'i' | 'h' | 's'>, matchingKey: string) {
|
|
27
26
|
const interval = parsedData.i || 60000;
|
|
@@ -72,7 +71,7 @@ export function pushManagerFactory(
|
|
|
72
71
|
const userKeyHashes: Record<string, string> = {};
|
|
73
72
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
74
73
|
// Hash64 is used to process MY_SEGMENTS_UPDATE_V2 events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
75
|
-
const clients: Record<string, { hash64: Hash64, worker:
|
|
74
|
+
const clients: Record<string, { hash64: Hash64, worker: ReturnType<typeof MySegmentsUpdateWorker>, workerLarge?: ReturnType<typeof MySegmentsUpdateWorker> }> = {};
|
|
76
75
|
|
|
77
76
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
78
77
|
let connectForNewClient = false;
|
|
@@ -284,14 +283,14 @@ export function pushManagerFactory(
|
|
|
284
283
|
const add = added.has(hash64.dec) ? true : removed.has(hash64.dec) ? false : undefined;
|
|
285
284
|
if (add !== undefined) {
|
|
286
285
|
isLS ?
|
|
287
|
-
workerLarge && workerLarge.put(parsedData.changeNumber, {
|
|
286
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, [{
|
|
288
287
|
name: parsedData.largeSegments[0],
|
|
289
288
|
add
|
|
290
|
-
}) :
|
|
291
|
-
worker.put(parsedData.changeNumber, {
|
|
289
|
+
}]) :
|
|
290
|
+
worker.put(parsedData.changeNumber, [{
|
|
292
291
|
name: parsedData.segmentName,
|
|
293
292
|
add
|
|
294
|
-
});
|
|
293
|
+
}]);
|
|
295
294
|
}
|
|
296
295
|
});
|
|
297
296
|
return;
|
|
@@ -304,16 +303,14 @@ export function pushManagerFactory(
|
|
|
304
303
|
|
|
305
304
|
forOwn(clients, ({ worker, workerLarge }) => {
|
|
306
305
|
isLS ?
|
|
307
|
-
workerLarge && parsedData.largeSegments.
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
}) :
|
|
313
|
-
worker.put(parsedData.changeNumber, {
|
|
306
|
+
workerLarge && workerLarge.put(parsedData.changeNumber, parsedData.largeSegments.map(largeSegment => ({
|
|
307
|
+
name: largeSegment,
|
|
308
|
+
add: false
|
|
309
|
+
}))) :
|
|
310
|
+
worker.put(parsedData.changeNumber, [{
|
|
314
311
|
name: parsedData.segmentName,
|
|
315
312
|
add: false
|
|
316
|
-
});
|
|
313
|
+
}]);
|
|
317
314
|
});
|
|
318
315
|
return;
|
|
319
316
|
}
|
|
@@ -12,7 +12,7 @@ export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, se
|
|
|
12
12
|
export declare type MySegmentsData = string[] | {
|
|
13
13
|
name: string;
|
|
14
14
|
add: boolean;
|
|
15
|
-
};
|
|
15
|
+
}[];
|
|
16
16
|
export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean], boolean> {
|
|
17
17
|
}
|
|
18
18
|
export interface IPollingManager extends ITask {
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { IMySegmentsSyncTask } from '../../polling/types';
|
|
1
|
+
import { IMySegmentsSyncTask, MySegmentsData } from '../../polling/types';
|
|
2
2
|
import { IUpdateWorker } from './types';
|
|
3
3
|
import { ITelemetryTracker } from '../../../trackers/types';
|
|
4
4
|
import { UpdatesFromSSEEnum } from '../../submitters/types';
|
|
5
5
|
/**
|
|
6
6
|
* MySegmentsUpdateWorker factory
|
|
7
7
|
*/
|
|
8
|
-
export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker, updateType: UpdatesFromSSEEnum): IUpdateWorker
|
|
8
|
+
export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker, updateType: UpdatesFromSSEEnum): IUpdateWorker<[changeNumber: number, segmentsData?: MySegmentsData, delay?: number]>;
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
import { ILogger } from '../../../logger/types';
|
|
2
2
|
import { ISegmentsCacheSync } from '../../../storages/types';
|
|
3
3
|
import { ISegmentsSyncTask } from '../../polling/types';
|
|
4
|
+
import { ISegmentUpdateData } from '../SSEHandler/types';
|
|
4
5
|
import { IUpdateWorker } from './types';
|
|
5
6
|
/**
|
|
6
7
|
* SegmentsUpdateWorker factory
|
|
7
8
|
*/
|
|
8
|
-
export declare function SegmentsUpdateWorker(log: ILogger, segmentsSyncTask: ISegmentsSyncTask, segmentsCache: ISegmentsCacheSync): IUpdateWorker
|
|
9
|
+
export declare function SegmentsUpdateWorker(log: ILogger, segmentsSyncTask: ISegmentsSyncTask, segmentsCache: ISegmentsCacheSync): IUpdateWorker<[ISegmentUpdateData]>;
|
|
@@ -1,13 +1,14 @@
|
|
|
1
|
+
import { ISplit } from '../../../dtos/types';
|
|
1
2
|
import { ILogger } from '../../../logger/types';
|
|
2
3
|
import { ISplitsEventEmitter } from '../../../readiness/types';
|
|
3
4
|
import { ISplitsCacheSync } from '../../../storages/types';
|
|
4
5
|
import { ITelemetryTracker } from '../../../trackers/types';
|
|
5
6
|
import { ISegmentsSyncTask, ISplitsSyncTask } from '../../polling/types';
|
|
6
|
-
import { ISplitKillData } from '../SSEHandler/types';
|
|
7
|
+
import { ISplitKillData, ISplitUpdateData } from '../SSEHandler/types';
|
|
7
8
|
import { IUpdateWorker } from './types';
|
|
8
9
|
/**
|
|
9
10
|
* SplitsUpdateWorker factory
|
|
10
11
|
*/
|
|
11
|
-
export declare function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker & {
|
|
12
|
+
export declare function SplitsUpdateWorker(log: ILogger, splitsCache: ISplitsCacheSync, splitsSyncTask: ISplitsSyncTask, splitsEventEmitter: ISplitsEventEmitter, telemetryTracker: ITelemetryTracker, segmentsSyncTask?: ISegmentsSyncTask): IUpdateWorker<[updateData: ISplitUpdateData, payload?: ISplit]> & {
|
|
12
13
|
killSplit(event: ISplitKillData): void;
|
|
13
14
|
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Compression, KeyList } from './SSEHandler/types';
|
|
2
|
+
import { ISplit } from '../../dtos/types';
|
|
2
3
|
/**
|
|
3
4
|
* Decode, decompress and parse the provided 'data' into a KeyList object
|
|
4
5
|
*
|
|
@@ -28,8 +29,5 @@ export declare function parseBitmap(data: string, compression: Compression): Uin
|
|
|
28
29
|
export declare function isInBitmap(bitmap: Uint8Array, hash64hex: string): boolean;
|
|
29
30
|
/**
|
|
30
31
|
* Parse feature flags notifications for instant feature flag updates
|
|
31
|
-
*
|
|
32
|
-
* @param {ISplitUpdateData} data
|
|
33
|
-
* @returns {KeyList}
|
|
34
32
|
*/
|
|
35
|
-
export declare function parseFFUpdatePayload(compression: Compression, data: string):
|
|
33
|
+
export declare function parseFFUpdatePayload(compression: Compression, data: string): ISplit | undefined;
|