@splitsoftware/splitio-commons 1.16.1-rc.10 → 1.16.1-rc.11
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/constants.js +2 -2
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/services/splitApi.js +1 -1
- package/cjs/storages/AbstractSegmentsCacheSync.js +41 -7
- package/cjs/storages/dataLoader.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +19 -63
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +5 -40
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +7 -17
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +5 -7
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +8 -6
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/pushManager.js +21 -24
- package/cjs/utils/constants/index.js +3 -4
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/services/splitApi.js +2 -2
- package/esm/storages/AbstractSegmentsCacheSync.js +41 -7
- package/esm/storages/dataLoader.js +1 -1
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +19 -63
- package/esm/storages/inMemory/MySegmentsCacheInMemory.js +5 -40
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +7 -17
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEHandler/index.js +6 -8
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +8 -6
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/pushManager.js +24 -27
- package/esm/utils/constants/index.js +1 -2
- package/package.json +1 -1
- package/src/dtos/types.ts +9 -12
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/services/splitApi.ts +2 -2
- package/src/storages/AbstractSegmentsCacheSync.ts +52 -7
- package/src/storages/AbstractSplitsCacheSync.ts +1 -1
- package/src/storages/dataLoader.ts +1 -1
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +15 -69
- package/src/storages/inMemory/MySegmentsCacheInMemory.ts +6 -46
- package/src/storages/types.ts +5 -4
- package/src/sync/polling/types.ts +8 -9
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +9 -14
- package/src/sync/streaming/AuthClient/index.ts +1 -1
- package/src/sync/streaming/SSEHandler/index.ts +9 -11
- package/src/sync/streaming/SSEHandler/types.ts +6 -6
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +8 -7
- package/src/sync/streaming/constants.ts +2 -2
- package/src/sync/streaming/parseUtils.ts +2 -2
- package/src/sync/streaming/pushManager.ts +26 -29
- package/src/sync/streaming/types.ts +6 -6
- package/src/sync/submitters/types.ts +3 -4
- package/src/utils/constants/index.ts +1 -2
- package/types/dtos/types.d.ts +8 -12
- package/types/logger/constants.d.ts +1 -1
- package/types/storages/AbstractSegmentsCacheSync.d.ts +8 -6
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +1 -12
- package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +1 -9
- package/types/storages/types.d.ts +5 -4
- package/types/sync/polling/types.d.ts +8 -6
- package/types/sync/streaming/SSEHandler/types.d.ts +6 -6
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +1 -2
- package/types/sync/streaming/constants.d.ts +2 -2
- package/types/sync/streaming/parseUtils.d.ts +2 -2
- package/types/sync/streaming/types.d.ts +5 -5
- package/types/sync/submitters/types.d.ts +3 -4
- package/types/utils/constants/index.d.ts +1 -2
|
@@ -11,14 +11,14 @@ 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 {
|
|
15
|
-
import { STREAMING_FALLBACK, STREAMING_REFRESH_TOKEN, STREAMING_CONNECTING, STREAMING_DISABLED, ERROR_STREAMING_AUTH, STREAMING_DISCONNECTING, STREAMING_RECONNECT,
|
|
16
|
-
import {
|
|
14
|
+
import { MEMBERSHIP_MS_UPDATE, MEMBERSHIP_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_MEMBERSHIP_UPDATE, STREAMING_PARSING_SPLIT_UPDATE } from '../../logger/constants';
|
|
16
|
+
import { IMembershipMSUpdateData, IMembershipLSUpdateData, KeyList, UpdateStrategy } from './SSEHandler/types';
|
|
17
17
|
import { getDelay, isInBitmap, parseBitmap, parseFFUpdatePayload, parseKeyList } from './parseUtils';
|
|
18
18
|
import { ISet, _Set } from '../../utils/lang/sets';
|
|
19
19
|
import { Hash64, hash64 } from '../../utils/murmur3/murmur3_64';
|
|
20
20
|
import { IAuthTokenPushEnabled } from './AuthClient/types';
|
|
21
|
-
import { TOKEN_REFRESH, AUTH_REJECTION
|
|
21
|
+
import { TOKEN_REFRESH, AUTH_REJECTION } from '../../utils/constants';
|
|
22
22
|
import { ISdkFactoryContextSync } from '../../sdkFactory/types';
|
|
23
23
|
|
|
24
24
|
/**
|
|
@@ -59,10 +59,10 @@ export function pushManagerFactory(
|
|
|
59
59
|
// For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
|
|
60
60
|
const splitsUpdateWorker = SplitsUpdateWorker(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask as ISegmentsSyncTask);
|
|
61
61
|
|
|
62
|
-
// [Only for client-side] map of hashes to user keys, to dispatch
|
|
62
|
+
// [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
|
|
63
63
|
const userKeyHashes: Record<string, string> = {};
|
|
64
64
|
// [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
|
|
65
|
-
// Hash64 is used to process
|
|
65
|
+
// Hash64 is used to process membership update events and dispatch actions to the corresponding MySegmentsUpdateWorker.
|
|
66
66
|
const clients: Record<string, { hash64: Hash64, worker: ReturnType<typeof MySegmentsUpdateWorker>, workerLarge: ReturnType<typeof MySegmentsUpdateWorker> }> = {};
|
|
67
67
|
|
|
68
68
|
// [Only for client-side] variable to flag that a new client was added. It is needed to reconnect streaming.
|
|
@@ -238,8 +238,8 @@ export function pushManagerFactory(
|
|
|
238
238
|
splitsUpdateWorker.put(parsedData);
|
|
239
239
|
});
|
|
240
240
|
|
|
241
|
-
function handleMySegmentsUpdate(parsedData:
|
|
242
|
-
const isLS = parsedData.
|
|
241
|
+
function handleMySegmentsUpdate(parsedData: IMembershipMSUpdateData | IMembershipLSUpdateData) {
|
|
242
|
+
const isLS = parsedData.type === MEMBERSHIP_LS_UPDATE;
|
|
243
243
|
|
|
244
244
|
switch (parsedData.u) {
|
|
245
245
|
case UpdateStrategy.BoundedFetchRequest: {
|
|
@@ -247,13 +247,13 @@ export function pushManagerFactory(
|
|
|
247
247
|
try {
|
|
248
248
|
bitmap = parseBitmap(parsedData.d!, parsedData.c!);
|
|
249
249
|
} catch (e) {
|
|
250
|
-
log.warn(
|
|
250
|
+
log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['BoundedFetchRequest', e]);
|
|
251
251
|
break;
|
|
252
252
|
}
|
|
253
253
|
|
|
254
254
|
forOwn(clients, ({ hash64, worker, workerLarge }, matchingKey) => {
|
|
255
255
|
if (isInBitmap(bitmap, hash64.hex)) {
|
|
256
|
-
(isLS ? workerLarge : worker).put(parsedData
|
|
256
|
+
(isLS ? workerLarge : worker).put(parsedData, undefined, getDelay(parsedData, matchingKey));
|
|
257
257
|
}
|
|
258
258
|
});
|
|
259
259
|
return;
|
|
@@ -265,53 +265,50 @@ export function pushManagerFactory(
|
|
|
265
265
|
added = new _Set(keyList.a);
|
|
266
266
|
removed = new _Set(keyList.r);
|
|
267
267
|
} catch (e) {
|
|
268
|
-
log.warn(
|
|
268
|
+
log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', e]);
|
|
269
269
|
break;
|
|
270
270
|
}
|
|
271
271
|
|
|
272
272
|
if (!parsedData.n || !parsedData.n.length) {
|
|
273
|
-
log.warn(
|
|
273
|
+
log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['KeyList', 'No segment name was provided']);
|
|
274
274
|
break;
|
|
275
275
|
}
|
|
276
276
|
|
|
277
277
|
forOwn(clients, ({ hash64, worker, workerLarge }) => {
|
|
278
278
|
const add = added.has(hash64.dec) ? true : removed.has(hash64.dec) ? false : undefined;
|
|
279
279
|
if (add !== undefined) {
|
|
280
|
-
(isLS ? workerLarge : worker).put(parsedData
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
}]);
|
|
280
|
+
(isLS ? workerLarge : worker).put(parsedData, {
|
|
281
|
+
added: add ? [parsedData.n![0]] : [],
|
|
282
|
+
removed: add ? [] : [parsedData.n![0]]
|
|
283
|
+
});
|
|
285
284
|
}
|
|
286
285
|
});
|
|
287
286
|
return;
|
|
288
287
|
}
|
|
289
288
|
case UpdateStrategy.SegmentRemoval:
|
|
290
289
|
if (!parsedData.n || !parsedData.n.length) {
|
|
291
|
-
log.warn(
|
|
290
|
+
log.warn(STREAMING_PARSING_MEMBERSHIP_UPDATE, ['SegmentRemoval', 'No segment name was provided']);
|
|
292
291
|
break;
|
|
293
292
|
}
|
|
294
293
|
|
|
295
294
|
forOwn(clients, ({ worker, workerLarge }) => {
|
|
296
|
-
(isLS ? workerLarge : worker).put(parsedData
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
cn: parsedData.cn
|
|
301
|
-
})));
|
|
295
|
+
(isLS ? workerLarge : worker).put(parsedData, {
|
|
296
|
+
added: [],
|
|
297
|
+
removed: parsedData.n!
|
|
298
|
+
});
|
|
302
299
|
});
|
|
303
300
|
return;
|
|
304
301
|
}
|
|
305
302
|
|
|
306
303
|
// `UpdateStrategy.UnboundedFetchRequest` and fallbacks of other cases
|
|
307
304
|
forOwn(clients, ({ worker, workerLarge }, matchingKey) => {
|
|
308
|
-
(isLS ? workerLarge : worker).put(parsedData
|
|
305
|
+
(isLS ? workerLarge : worker).put(parsedData, undefined, getDelay(parsedData, matchingKey));
|
|
309
306
|
});
|
|
310
307
|
}
|
|
311
308
|
|
|
312
309
|
if (userKey) {
|
|
313
|
-
pushEmitter.on(
|
|
314
|
-
pushEmitter.on(
|
|
310
|
+
pushEmitter.on(MEMBERSHIP_MS_UPDATE, handleMySegmentsUpdate);
|
|
311
|
+
pushEmitter.on(MEMBERSHIP_LS_UPDATE, handleMySegmentsUpdate);
|
|
315
312
|
} else {
|
|
316
313
|
pushEmitter.on(SEGMENT_UPDATE, segmentsUpdateWorker!.put);
|
|
317
314
|
}
|
|
@@ -351,8 +348,8 @@ export function pushManagerFactory(
|
|
|
351
348
|
userKeyHashes[hash] = userKey;
|
|
352
349
|
clients[userKey] = {
|
|
353
350
|
hash64: hash64(userKey),
|
|
354
|
-
worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker
|
|
355
|
-
workerLarge: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker
|
|
351
|
+
worker: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker),
|
|
352
|
+
workerLarge: MySegmentsUpdateWorker(mySegmentsSyncTask, telemetryTracker)
|
|
356
353
|
};
|
|
357
354
|
connectForNewClient = true; // we must reconnect on start, to listen the channel for the new user key
|
|
358
355
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IMembershipMSUpdateData, IMembershipLSUpdateData, ISegmentUpdateData, ISplitUpdateData, ISplitKillData, INotificationData } from './SSEHandler/types';
|
|
2
2
|
import { ITask } from '../types';
|
|
3
3
|
import { IMySegmentsSyncTask } from '../polling/types';
|
|
4
4
|
import { IEventEmitter } from '../../types';
|
|
@@ -11,21 +11,21 @@ export type PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR'
|
|
|
11
11
|
export type PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR'
|
|
12
12
|
|
|
13
13
|
// Update-type push notifications, handled by NotificationProcessor
|
|
14
|
-
export type
|
|
14
|
+
export type MEMBERSHIP_MS_UPDATE = 'MEMBERSHIP_MS_UPDATE';
|
|
15
|
+
export type MEMBERSHIP_LS_UPDATE = 'MEMBERSHIP_LS_UPDATE';
|
|
15
16
|
export type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
|
|
16
17
|
export type SPLIT_KILL = 'SPLIT_KILL';
|
|
17
18
|
export type SPLIT_UPDATE = 'SPLIT_UPDATE';
|
|
18
|
-
export type MY_LARGE_SEGMENTS_UPDATE = 'MY_LARGE_SEGMENTS_UPDATE';
|
|
19
19
|
|
|
20
20
|
// Control-type push notifications, handled by NotificationKeeper
|
|
21
21
|
export type CONTROL = 'CONTROL';
|
|
22
22
|
export type OCCUPANCY = 'OCCUPANCY';
|
|
23
23
|
|
|
24
|
-
export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR |
|
|
24
|
+
export type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET
|
|
25
25
|
|
|
26
26
|
type IParsedData<T extends IPushEvent> =
|
|
27
|
-
T extends
|
|
28
|
-
T extends
|
|
27
|
+
T extends MEMBERSHIP_MS_UPDATE ? IMembershipMSUpdateData :
|
|
28
|
+
T extends MEMBERSHIP_LS_UPDATE ? IMembershipLSUpdateData :
|
|
29
29
|
T extends SEGMENT_UPDATE ? ISegmentUpdateData :
|
|
30
30
|
T extends SPLIT_UPDATE ? ISplitUpdateData :
|
|
31
31
|
T extends SPLIT_KILL ? ISplitKillData : INotificationData;
|
|
@@ -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 |
|
|
106
|
+
export type UpdatesFromSSEEnum = SPLITS | MEMBERSHIPS;
|
|
107
107
|
|
|
108
108
|
export type SPLITS = 'sp';
|
|
109
109
|
export type IMPRESSIONS = 'im';
|
|
@@ -112,9 +112,8 @@ export type EVENTS = 'ev';
|
|
|
112
112
|
export type TELEMETRY = 'te';
|
|
113
113
|
export type TOKEN = 'to';
|
|
114
114
|
export type SEGMENT = 'se';
|
|
115
|
-
export type
|
|
116
|
-
export type
|
|
117
|
-
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
115
|
+
export type MEMBERSHIPS = 'ms';
|
|
116
|
+
export type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MEMBERSHIPS;
|
|
118
117
|
|
|
119
118
|
export type LastSync = Partial<Record<OperationType, number | undefined>>
|
|
120
119
|
export type HttpErrors = Partial<Record<OperationType, { [statusCode: string]: number }>>
|
|
@@ -75,8 +75,7 @@ export const EVENTS = 'ev';
|
|
|
75
75
|
export const TELEMETRY = 'te';
|
|
76
76
|
export const TOKEN = 'to';
|
|
77
77
|
export const SEGMENT = 'se';
|
|
78
|
-
export const
|
|
79
|
-
export const MY_LARGE_SEGMENT = 'mls';
|
|
78
|
+
export const MEMBERSHIPS = 'ms';
|
|
80
79
|
|
|
81
80
|
export const TREATMENT = 't';
|
|
82
81
|
export const TREATMENTS = 'ts';
|
package/types/dtos/types.d.ts
CHANGED
|
@@ -177,20 +177,16 @@ export interface ISegmentChangesResponse {
|
|
|
177
177
|
since: number;
|
|
178
178
|
till: number;
|
|
179
179
|
}
|
|
180
|
+
export interface IMySegmentsResponse {
|
|
181
|
+
cn?: number;
|
|
182
|
+
k?: {
|
|
183
|
+
n: string;
|
|
184
|
+
}[];
|
|
185
|
+
}
|
|
180
186
|
/** Interface of the parsed JSON response of `/memberships/{userKey}` */
|
|
181
187
|
export interface IMembershipsResponse {
|
|
182
|
-
ms?:
|
|
183
|
-
|
|
184
|
-
k?: Array<{
|
|
185
|
-
n: string;
|
|
186
|
-
}>;
|
|
187
|
-
};
|
|
188
|
-
ls?: {
|
|
189
|
-
cn?: number;
|
|
190
|
-
k?: Array<{
|
|
191
|
-
n: string;
|
|
192
|
-
}>;
|
|
193
|
-
};
|
|
188
|
+
ms?: IMySegmentsResponse;
|
|
189
|
+
ls?: IMySegmentsResponse;
|
|
194
190
|
}
|
|
195
191
|
/** Metadata internal type for storages */
|
|
196
192
|
export interface IMetadata {
|
|
@@ -77,7 +77,7 @@ export declare const WARN_SPLITS_FILTER_IGNORED = 219;
|
|
|
77
77
|
export declare const WARN_SPLITS_FILTER_INVALID = 220;
|
|
78
78
|
export declare const WARN_SPLITS_FILTER_EMPTY = 221;
|
|
79
79
|
export declare const WARN_SDK_KEY = 222;
|
|
80
|
-
export declare const
|
|
80
|
+
export declare const STREAMING_PARSING_MEMBERSHIP_UPDATE = 223;
|
|
81
81
|
export declare const STREAMING_PARSING_SPLIT_UPDATE = 224;
|
|
82
82
|
export declare const WARN_INVALID_FLAGSET = 225;
|
|
83
83
|
export declare const WARN_LOWERCASE_FLAGSET = 226;
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { IMySegmentsResponse } from '../dtos/types';
|
|
2
|
+
import { MySegmentsData } from '../sync/polling/types';
|
|
1
3
|
import { ISegmentsCacheSync } from './types';
|
|
2
4
|
/**
|
|
3
5
|
* This class provides a skeletal implementation of the ISegmentsCacheSync interface
|
|
@@ -22,7 +24,7 @@ export declare abstract class AbstractSegmentsCacheSync implements ISegmentsCach
|
|
|
22
24
|
/**
|
|
23
25
|
* clear the cache.
|
|
24
26
|
*/
|
|
25
|
-
|
|
27
|
+
clear(): void;
|
|
26
28
|
/**
|
|
27
29
|
* For server-side synchronizer: add the given list of segments to the cache, with an empty list of keys. The segments that already exist are not modified.
|
|
28
30
|
* For client-side synchronizer: the method is not used.
|
|
@@ -39,14 +41,14 @@ export declare abstract class AbstractSegmentsCacheSync implements ISegmentsCach
|
|
|
39
41
|
*/
|
|
40
42
|
abstract getKeysCount(): number;
|
|
41
43
|
/**
|
|
42
|
-
* For server-side synchronizer:
|
|
43
|
-
* For client-side synchronizer:
|
|
44
|
+
* For server-side synchronizer: change number of `name` segment.
|
|
45
|
+
* For client-side synchronizer: change number of mySegments.
|
|
44
46
|
*/
|
|
45
|
-
setChangeNumber(name
|
|
47
|
+
abstract setChangeNumber(name?: string, changeNumber?: number): boolean | void;
|
|
46
48
|
abstract getChangeNumber(name: string): number;
|
|
47
49
|
/**
|
|
48
50
|
* For server-side synchronizer: the method is not used.
|
|
49
|
-
* For client-side synchronizer:
|
|
51
|
+
* For client-side synchronizer: it resets or updates the cache.
|
|
50
52
|
*/
|
|
51
|
-
resetSegments(
|
|
53
|
+
resetSegments(segmentsData: MySegmentsData | IMySegmentsResponse): boolean;
|
|
52
54
|
}
|
|
@@ -12,7 +12,7 @@ export declare abstract class AbstractSplitsCacheSync implements ISplitsCacheSyn
|
|
|
12
12
|
removeSplits(names: string[]): boolean[];
|
|
13
13
|
abstract getSplit(name: string): ISplit | null;
|
|
14
14
|
getSplits(names: string[]): Record<string, ISplit | null>;
|
|
15
|
-
abstract setChangeNumber(changeNumber: number): boolean;
|
|
15
|
+
abstract setChangeNumber(changeNumber: number): boolean | void;
|
|
16
16
|
abstract getChangeNumber(): number;
|
|
17
17
|
getAll(): ISplit[];
|
|
18
18
|
abstract getSplitNames(): string[];
|
|
@@ -5,22 +5,11 @@ export declare class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
|
5
5
|
private readonly keys;
|
|
6
6
|
private readonly log;
|
|
7
7
|
constructor(log: ILogger, keys: MySegmentsKeyBuilder);
|
|
8
|
-
/**
|
|
9
|
-
* Removes list of segments from localStorage
|
|
10
|
-
* @NOTE this method is not being used at the moment.
|
|
11
|
-
*/
|
|
12
|
-
clear(): void;
|
|
13
8
|
addToSegment(name: string): boolean;
|
|
14
9
|
removeFromSegment(name: string): boolean;
|
|
15
10
|
isInSegment(name: string): boolean;
|
|
16
|
-
/**
|
|
17
|
-
* Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
|
|
18
|
-
*
|
|
19
|
-
* @param {string[]} names list of segment names
|
|
20
|
-
* @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
|
|
21
|
-
*/
|
|
22
|
-
resetSegments(names: string[], changeNumber?: number): boolean;
|
|
23
11
|
getRegisteredSegments(): string[];
|
|
24
12
|
getKeysCount(): number;
|
|
13
|
+
setChangeNumber(name?: string, changeNumber?: number): void;
|
|
25
14
|
getChangeNumber(): number;
|
|
26
15
|
}
|
|
@@ -6,18 +6,10 @@ import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
|
|
|
6
6
|
export declare class MySegmentsCacheInMemory extends AbstractSegmentsCacheSync {
|
|
7
7
|
private segmentCache;
|
|
8
8
|
private cn?;
|
|
9
|
-
clear(): void;
|
|
10
9
|
addToSegment(name: string): boolean;
|
|
11
10
|
removeFromSegment(name: string): boolean;
|
|
12
11
|
isInSegment(name: string): boolean;
|
|
13
|
-
|
|
14
|
-
* Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
|
|
15
|
-
* @NOTE based on the way we use segments in the browser, this way is the best option
|
|
16
|
-
*
|
|
17
|
-
* @param {string[]} names list of segment names
|
|
18
|
-
* @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
|
|
19
|
-
*/
|
|
20
|
-
resetSegments(names: string[], changeNumber?: number): boolean;
|
|
12
|
+
setChangeNumber(name?: string, changeNumber?: number): void;
|
|
21
13
|
getChangeNumber(): number;
|
|
22
14
|
getRegisteredSegments(): string[];
|
|
23
15
|
getKeysCount(): number;
|
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { MaybeThenable, ISplit } from '../dtos/types';
|
|
1
|
+
import { MaybeThenable, ISplit, IMySegmentsResponse } from '../dtos/types';
|
|
2
|
+
import { MySegmentsData } from '../sync/polling/types';
|
|
2
3
|
import { EventDataType, HttpErrors, HttpLatencies, ImpressionDataType, LastSync, Method, MethodExceptions, MethodLatencies, MultiMethodExceptions, MultiMethodLatencies, MultiConfigs, OperationType, StoredEventWithMetadata, StoredImpressionWithMetadata, StreamingEvent, UniqueKeysPayloadCs, UniqueKeysPayloadSs, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../sync/submitters/types';
|
|
3
4
|
import { SplitIO, ImpressionDTO, ISettings } from '../types';
|
|
4
5
|
import { ISet } from '../utils/lang/sets';
|
|
@@ -200,7 +201,7 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
200
201
|
removeSplits(names: string[]): boolean[];
|
|
201
202
|
getSplit(name: string): ISplit | null;
|
|
202
203
|
getSplits(names: string[]): Record<string, ISplit | null>;
|
|
203
|
-
setChangeNumber(changeNumber: number): boolean;
|
|
204
|
+
setChangeNumber(changeNumber: number): boolean | void;
|
|
204
205
|
getChangeNumber(): number;
|
|
205
206
|
getAll(): ISplit[];
|
|
206
207
|
getSplitNames(): string[];
|
|
@@ -245,9 +246,9 @@ export interface ISegmentsCacheSync extends ISegmentsCacheBase {
|
|
|
245
246
|
registerSegments(names: string[]): boolean;
|
|
246
247
|
getRegisteredSegments(): string[];
|
|
247
248
|
getKeysCount(): number;
|
|
248
|
-
setChangeNumber(name: string, changeNumber: number): boolean;
|
|
249
|
+
setChangeNumber(name: string, changeNumber: number): boolean | void;
|
|
249
250
|
getChangeNumber(name: string): number;
|
|
250
|
-
resetSegments(
|
|
251
|
+
resetSegments(segmentsData: MySegmentsData | IMySegmentsResponse): boolean;
|
|
251
252
|
clear(): void;
|
|
252
253
|
}
|
|
253
254
|
export interface ISegmentsCacheAsync extends ISegmentsCacheBase {
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ISplit } from '../../dtos/types';
|
|
2
2
|
import { IReadinessManager } from '../../readiness/types';
|
|
3
3
|
import { IStorageSync } from '../../storages/types';
|
|
4
|
+
import { MEMBERSHIP_LS_UPDATE, MEMBERSHIP_MS_UPDATE } from '../streaming/types';
|
|
4
5
|
import { ITask, ISyncTask } from '../types';
|
|
5
6
|
export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: {
|
|
6
7
|
payload: ISplit;
|
|
@@ -9,11 +10,12 @@ export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: nu
|
|
|
9
10
|
}
|
|
10
11
|
export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> {
|
|
11
12
|
}
|
|
12
|
-
export declare type MySegmentsData =
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
export declare type MySegmentsData = {
|
|
14
|
+
type: MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE;
|
|
15
|
+
cn: number;
|
|
16
|
+
added: string[];
|
|
17
|
+
removed: string[];
|
|
18
|
+
};
|
|
17
19
|
export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean], boolean> {
|
|
18
20
|
}
|
|
19
21
|
export interface IPollingManager extends ITask {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ControlType } from '../constants';
|
|
2
|
-
import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY,
|
|
2
|
+
import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIP_LS_UPDATE, MEMBERSHIP_MS_UPDATE } from '../types';
|
|
3
3
|
export declare enum Compression {
|
|
4
4
|
None = 0,
|
|
5
5
|
Gzip = 1,
|
|
@@ -15,8 +15,8 @@ export interface KeyList {
|
|
|
15
15
|
a?: string[];
|
|
16
16
|
r?: string[];
|
|
17
17
|
}
|
|
18
|
-
interface
|
|
19
|
-
|
|
18
|
+
interface IMembershipUpdateData<T extends string> {
|
|
19
|
+
type: T;
|
|
20
20
|
cn: number;
|
|
21
21
|
n?: string[];
|
|
22
22
|
c?: Compression;
|
|
@@ -26,9 +26,9 @@ interface IMySegmentsUpdateData<T extends string> {
|
|
|
26
26
|
h?: number;
|
|
27
27
|
s?: number;
|
|
28
28
|
}
|
|
29
|
-
export interface
|
|
29
|
+
export interface IMembershipMSUpdateData extends IMembershipUpdateData<MEMBERSHIP_MS_UPDATE> {
|
|
30
30
|
}
|
|
31
|
-
export interface
|
|
31
|
+
export interface IMembershipLSUpdateData extends IMembershipUpdateData<MEMBERSHIP_LS_UPDATE> {
|
|
32
32
|
}
|
|
33
33
|
export interface ISegmentUpdateData {
|
|
34
34
|
type: SEGMENT_UPDATE;
|
|
@@ -58,7 +58,7 @@ export interface IOccupancyData {
|
|
|
58
58
|
publishers: number;
|
|
59
59
|
};
|
|
60
60
|
}
|
|
61
|
-
export declare type INotificationData =
|
|
61
|
+
export declare type INotificationData = IMembershipMSUpdateData | IMembershipLSUpdateData | ISegmentUpdateData | ISplitUpdateData | ISplitKillData | IControlData | IOccupancyData;
|
|
62
62
|
export declare type INotificationMessage = {
|
|
63
63
|
parsedData: INotificationData;
|
|
64
64
|
channel: string;
|
|
@@ -1,8 +1,7 @@
|
|
|
1
1
|
import { IMySegmentsSyncTask, MySegmentsData } from '../../polling/types';
|
|
2
2
|
import { IUpdateWorker } from './types';
|
|
3
3
|
import { ITelemetryTracker } from '../../../trackers/types';
|
|
4
|
-
import { UpdatesFromSSEEnum } from '../../submitters/types';
|
|
5
4
|
/**
|
|
6
5
|
* MySegmentsUpdateWorker factory
|
|
7
6
|
*/
|
|
8
|
-
export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker
|
|
7
|
+
export declare function MySegmentsUpdateWorker(mySegmentsSyncTask: IMySegmentsSyncTask, telemetryTracker: ITelemetryTracker): IUpdateWorker<[mySegmentsData?: Pick<MySegmentsData, 'type' | 'cn'>, payload?: Pick<MySegmentsData, 'added' | 'removed'>, delay?: number]>;
|
|
@@ -19,11 +19,11 @@ export declare const PUSH_SUBSYSTEM_UP = "PUSH_SUBSYSTEM_UP";
|
|
|
19
19
|
* triggers `startPolling` and `stopWorkers` calls
|
|
20
20
|
*/
|
|
21
21
|
export declare const PUSH_SUBSYSTEM_DOWN = "PUSH_SUBSYSTEM_DOWN";
|
|
22
|
-
export declare const
|
|
22
|
+
export declare const MEMBERSHIP_MS_UPDATE = "MEMBERSHIP_MS_UPDATE";
|
|
23
|
+
export declare const MEMBERSHIP_LS_UPDATE = "MEMBERSHIP_LS_UPDATE";
|
|
23
24
|
export declare const SEGMENT_UPDATE = "SEGMENT_UPDATE";
|
|
24
25
|
export declare const SPLIT_KILL = "SPLIT_KILL";
|
|
25
26
|
export declare const SPLIT_UPDATE = "SPLIT_UPDATE";
|
|
26
|
-
export declare const MY_LARGE_SEGMENTS_UPDATE = "MY_LARGE_SEGMENTS_UPDATE";
|
|
27
27
|
export declare const CONTROL = "CONTROL";
|
|
28
28
|
export declare const OCCUPANCY = "OCCUPANCY";
|
|
29
29
|
export declare enum ControlType {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Compression,
|
|
1
|
+
import { Compression, IMembershipMSUpdateData, KeyList } from './SSEHandler/types';
|
|
2
2
|
import { ISplit } from '../../dtos/types';
|
|
3
3
|
/**
|
|
4
4
|
* Decode, decompress and parse the provided 'data' into a KeyList object
|
|
@@ -31,4 +31,4 @@ export declare function isInBitmap(bitmap: Uint8Array, hash64hex: string): boole
|
|
|
31
31
|
* Parse feature flags notifications for instant feature flag updates
|
|
32
32
|
*/
|
|
33
33
|
export declare function parseFFUpdatePayload(compression: Compression, data: string): ISplit | undefined;
|
|
34
|
-
export declare function getDelay(parsedData: Pick<
|
|
34
|
+
export declare function getDelay(parsedData: Pick<IMembershipMSUpdateData, 'i' | 'h' | 's'>, matchingKey: string): number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { IMembershipMSUpdateData, IMembershipLSUpdateData, ISegmentUpdateData, ISplitUpdateData, ISplitKillData, INotificationData } from './SSEHandler/types';
|
|
2
2
|
import { ITask } from '../types';
|
|
3
3
|
import { IMySegmentsSyncTask } from '../polling/types';
|
|
4
4
|
import { IEventEmitter } from '../../types';
|
|
@@ -7,15 +7,15 @@ export declare type PUSH_SUBSYSTEM_UP = 'PUSH_SUBSYSTEM_UP';
|
|
|
7
7
|
export declare type PUSH_SUBSYSTEM_DOWN = 'PUSH_SUBSYSTEM_DOWN';
|
|
8
8
|
export declare type PUSH_NONRETRYABLE_ERROR = 'PUSH_NONRETRYABLE_ERROR';
|
|
9
9
|
export declare type PUSH_RETRYABLE_ERROR = 'PUSH_RETRYABLE_ERROR';
|
|
10
|
-
export declare type
|
|
10
|
+
export declare type MEMBERSHIP_MS_UPDATE = 'MEMBERSHIP_MS_UPDATE';
|
|
11
|
+
export declare type MEMBERSHIP_LS_UPDATE = 'MEMBERSHIP_LS_UPDATE';
|
|
11
12
|
export declare type SEGMENT_UPDATE = 'SEGMENT_UPDATE';
|
|
12
13
|
export declare type SPLIT_KILL = 'SPLIT_KILL';
|
|
13
14
|
export declare type SPLIT_UPDATE = 'SPLIT_UPDATE';
|
|
14
|
-
export declare type MY_LARGE_SEGMENTS_UPDATE = 'MY_LARGE_SEGMENTS_UPDATE';
|
|
15
15
|
export declare type CONTROL = 'CONTROL';
|
|
16
16
|
export declare type OCCUPANCY = 'OCCUPANCY';
|
|
17
|
-
export declare type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR |
|
|
18
|
-
declare type IParsedData<T extends IPushEvent> = T extends
|
|
17
|
+
export declare type IPushEvent = PUSH_SUBSYSTEM_UP | PUSH_SUBSYSTEM_DOWN | PUSH_NONRETRYABLE_ERROR | PUSH_RETRYABLE_ERROR | MEMBERSHIP_MS_UPDATE | MEMBERSHIP_LS_UPDATE | SEGMENT_UPDATE | SPLIT_UPDATE | SPLIT_KILL | ControlType.STREAMING_RESET;
|
|
18
|
+
declare type IParsedData<T extends IPushEvent> = T extends MEMBERSHIP_MS_UPDATE ? IMembershipMSUpdateData : T extends MEMBERSHIP_LS_UPDATE ? IMembershipLSUpdateData : T extends SEGMENT_UPDATE ? ISegmentUpdateData : T extends SPLIT_UPDATE ? ISplitUpdateData : T extends SPLIT_KILL ? ISplitKillData : INotificationData;
|
|
19
19
|
/**
|
|
20
20
|
* EventEmitter used as Feedback Loop between the SyncManager and PushManager,
|
|
21
21
|
* where the latter pushes messages and the former consumes it
|
|
@@ -90,7 +90,7 @@ export declare type DROPPED = 1;
|
|
|
90
90
|
export declare type DEDUPED = 2;
|
|
91
91
|
export declare type ImpressionDataType = QUEUED | DROPPED | DEDUPED;
|
|
92
92
|
export declare type EventDataType = QUEUED | DROPPED;
|
|
93
|
-
export declare type UpdatesFromSSEEnum = SPLITS |
|
|
93
|
+
export declare type UpdatesFromSSEEnum = SPLITS | MEMBERSHIPS;
|
|
94
94
|
export declare type SPLITS = 'sp';
|
|
95
95
|
export declare type IMPRESSIONS = 'im';
|
|
96
96
|
export declare type IMPRESSIONS_COUNT = 'ic';
|
|
@@ -98,9 +98,8 @@ export declare type EVENTS = 'ev';
|
|
|
98
98
|
export declare type TELEMETRY = 'te';
|
|
99
99
|
export declare type TOKEN = 'to';
|
|
100
100
|
export declare type SEGMENT = 'se';
|
|
101
|
-
export declare type
|
|
102
|
-
export declare type
|
|
103
|
-
export declare type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MY_SEGMENT;
|
|
101
|
+
export declare type MEMBERSHIPS = 'ms';
|
|
102
|
+
export declare type OperationType = SPLITS | IMPRESSIONS | IMPRESSIONS_COUNT | EVENTS | TELEMETRY | TOKEN | SEGMENT | MEMBERSHIPS;
|
|
104
103
|
export declare type LastSync = Partial<Record<OperationType, number | undefined>>;
|
|
105
104
|
export declare type HttpErrors = Partial<Record<OperationType, {
|
|
106
105
|
[statusCode: string]: number;
|
|
@@ -52,8 +52,7 @@ export declare const EVENTS = "ev";
|
|
|
52
52
|
export declare const TELEMETRY = "te";
|
|
53
53
|
export declare const TOKEN = "to";
|
|
54
54
|
export declare const SEGMENT = "se";
|
|
55
|
-
export declare const
|
|
56
|
-
export declare const MY_LARGE_SEGMENT = "mls";
|
|
55
|
+
export declare const MEMBERSHIPS = "ms";
|
|
57
56
|
export declare const TREATMENT = "t";
|
|
58
57
|
export declare const TREATMENTS = "ts";
|
|
59
58
|
export declare const TREATMENT_WITH_CONFIG = "tc";
|