@splitsoftware/splitio-commons 1.17.0-rc.5 → 1.17.1-rc.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +6 -0
- package/cjs/evaluator/matchers/index.js +3 -1
- package/cjs/evaluator/matchers/large_segment.js +16 -0
- package/cjs/evaluator/matchers/matcherTypes.js +1 -0
- package/cjs/evaluator/matchersTransform/index.js +4 -1
- package/cjs/evaluator/matchersTransform/segment.js +3 -1
- package/cjs/logger/constants.js +2 -2
- package/cjs/logger/messages/info.js +1 -1
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/readiness/readinessManager.js +5 -6
- package/cjs/readiness/sdkReadinessManager.js +5 -6
- package/cjs/sdkClient/sdkClientMethodCS.js +2 -2
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +2 -2
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/services/splitApi.js +5 -5
- package/cjs/storages/AbstractSegmentsCacheSync.js +41 -12
- package/cjs/storages/AbstractSplitsCacheSync.js +2 -1
- package/cjs/storages/KeyBuilderCS.js +23 -5
- package/cjs/storages/dataLoader.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +29 -52
- package/cjs/storages/inLocalStorage/index.js +6 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +9 -40
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +8 -8
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +5 -8
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/pollingManagerCS.js +1 -1
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +15 -21
- package/cjs/sync/streaming/AuthClient/index.js +1 -1
- package/cjs/sync/streaming/SSEClient/index.js +2 -2
- package/cjs/sync/streaming/SSEHandler/index.js +3 -5
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +107 -48
- package/cjs/sync/streaming/constants.js +3 -3
- package/cjs/sync/streaming/parseUtils.js +14 -9
- package/cjs/sync/streaming/pushManager.js +69 -67
- package/cjs/utils/constants/index.js +5 -4
- package/cjs/utils/settingsValidation/index.js +2 -1
- package/esm/evaluator/matchers/index.js +3 -1
- package/esm/evaluator/matchers/large_segment.js +12 -0
- package/esm/evaluator/matchers/matcherTypes.js +1 -0
- package/esm/evaluator/matchersTransform/index.js +4 -1
- package/esm/evaluator/matchersTransform/segment.js +3 -1
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +1 -1
- package/esm/logger/messages/warn.js +1 -1
- package/esm/readiness/readinessManager.js +5 -6
- package/esm/readiness/sdkReadinessManager.js +5 -6
- package/esm/sdkClient/sdkClientMethodCS.js +2 -2
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +2 -2
- package/esm/sdkFactory/index.js +1 -1
- package/esm/services/splitApi.js +6 -6
- package/esm/storages/AbstractSegmentsCacheSync.js +41 -12
- package/esm/storages/AbstractSplitsCacheSync.js +3 -2
- package/esm/storages/KeyBuilderCS.js +21 -4
- package/esm/storages/dataLoader.js +1 -1
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +29 -52
- package/esm/storages/inLocalStorage/index.js +7 -3
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/esm/storages/inMemory/MySegmentsCacheInMemory.js +9 -40
- package/esm/storages/inMemory/SplitsCacheInMemory.js +8 -8
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +5 -8
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/esm/sync/polling/pollingManagerCS.js +1 -1
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +15 -21
- package/esm/sync/streaming/AuthClient/index.js +1 -1
- package/esm/sync/streaming/SSEClient/index.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +4 -6
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +108 -49
- package/esm/sync/streaming/constants.js +2 -2
- package/esm/sync/streaming/parseUtils.js +12 -8
- package/esm/sync/streaming/pushManager.js +72 -70
- package/esm/utils/constants/index.js +3 -2
- package/esm/utils/settingsValidation/index.js +2 -1
- package/package.json +1 -1
- package/src/dtos/types.ts +21 -7
- package/src/evaluator/matchers/index.ts +2 -0
- package/src/evaluator/matchers/large_segment.ts +18 -0
- package/src/evaluator/matchers/matcherTypes.ts +1 -0
- package/src/evaluator/matchersTransform/index.ts +4 -1
- package/src/evaluator/matchersTransform/segment.ts +5 -3
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +1 -1
- package/src/logger/messages/warn.ts +1 -1
- package/src/readiness/readinessManager.ts +7 -5
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +2 -2
- package/src/sdkClient/sdkClientMethodCS.ts +2 -2
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +2 -2
- package/src/sdkFactory/index.ts +1 -1
- package/src/services/splitApi.ts +7 -7
- package/src/services/splitHttpClient.ts +1 -1
- package/src/services/types.ts +2 -2
- package/src/storages/AbstractSegmentsCacheSync.ts +53 -12
- package/src/storages/AbstractSplitsCacheSync.ts +4 -3
- package/src/storages/KeyBuilderCS.ts +34 -5
- package/src/storages/dataLoader.ts +1 -1
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +29 -59
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -0
- package/src/storages/inMemory/MySegmentsCacheInMemory.ts +10 -44
- package/src/storages/inMemory/SplitsCacheInMemory.ts +7 -8
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +7 -11
- package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
- package/src/storages/types.ts +11 -7
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +8 -10
- package/src/sync/polling/fetchers/segmentChangesFetcher.ts +1 -1
- package/src/sync/polling/fetchers/types.ts +3 -2
- package/src/sync/polling/pollingManagerCS.ts +4 -4
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +4 -5
- package/src/sync/polling/types.ts +7 -6
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +19 -22
- package/src/sync/streaming/AuthClient/index.ts +1 -1
- package/src/sync/streaming/SSEClient/index.ts +6 -8
- package/src/sync/streaming/SSEHandler/index.ts +5 -8
- package/src/sync/streaming/SSEHandler/types.ts +15 -15
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +116 -49
- 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 +2 -2
- package/src/sync/streaming/parseUtils.ts +19 -11
- package/src/sync/streaming/pushManager.ts +73 -72
- package/src/sync/streaming/types.ts +10 -10
- package/src/sync/submitters/types.ts +8 -5
- package/src/utils/constants/index.ts +3 -2
- package/src/utils/settingsValidation/index.ts +3 -2
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +18 -7
- package/types/evaluator/matchersTransform/segment.d.ts +2 -2
- package/types/logger/constants.d.ts +1 -1
- package/types/readiness/readinessManager.d.ts +2 -2
- package/types/readiness/sdkReadinessManager.d.ts +2 -3
- package/types/readiness/types.d.ts +2 -2
- package/types/services/splitApi.d.ts +1 -1
- package/types/services/splitHttpClient.d.ts +1 -1
- package/types/services/types.d.ts +2 -2
- package/types/storages/AbstractSegmentsCacheSync.d.ts +9 -11
- package/types/storages/AbstractSplitsCacheSync.d.ts +1 -1
- package/types/storages/KeyBuilderCS.d.ts +9 -2
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +4 -14
- package/types/storages/inMemory/MySegmentsCacheInMemory.d.ts +3 -9
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +1 -1
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +4 -6
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
- package/types/storages/types.d.ts +7 -5
- package/types/sync/polling/fetchers/mySegmentsFetcher.d.ts +2 -2
- package/types/sync/polling/fetchers/types.d.ts +2 -2
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -2
- package/types/sync/polling/types.d.ts +7 -4
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +4 -3
- package/types/sync/streaming/SSEHandler/types.d.ts +16 -14
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +4 -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/constants.d.ts +2 -2
- package/types/sync/streaming/parseUtils.d.ts +4 -5
- package/types/sync/streaming/types.d.ts +8 -8
- package/types/sync/submitters/types.d.ts +7 -4
- package/types/utils/constants/index.d.ts +3 -2
- package/types/utils/settingsValidation/types.d.ts +1 -1
|
@@ -7,18 +7,19 @@ import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
|
|
|
7
7
|
export class MySegmentsCacheInMemory extends AbstractSegmentsCacheSync {
|
|
8
8
|
|
|
9
9
|
private segmentCache: Record<string, boolean> = {};
|
|
10
|
-
|
|
11
|
-
clear() {
|
|
12
|
-
this.segmentCache = {};
|
|
13
|
-
}
|
|
10
|
+
private cn?: number;
|
|
14
11
|
|
|
15
12
|
addToSegment(name: string): boolean {
|
|
13
|
+
if (this.segmentCache[name]) return false;
|
|
14
|
+
|
|
16
15
|
this.segmentCache[name] = true;
|
|
17
16
|
|
|
18
17
|
return true;
|
|
19
18
|
}
|
|
20
19
|
|
|
21
20
|
removeFromSegment(name: string): boolean {
|
|
21
|
+
if (!this.segmentCache[name]) return false;
|
|
22
|
+
|
|
22
23
|
delete this.segmentCache[name];
|
|
23
24
|
|
|
24
25
|
return true;
|
|
@@ -28,48 +29,13 @@ export class MySegmentsCacheInMemory extends AbstractSegmentsCacheSync {
|
|
|
28
29
|
return this.segmentCache[name] === true;
|
|
29
30
|
}
|
|
30
31
|
|
|
31
|
-
/**
|
|
32
|
-
* Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
|
|
33
|
-
* @NOTE based on the way we use segments in the browser, this way is the best option
|
|
34
|
-
*
|
|
35
|
-
* @param {string[]} names list of segment names
|
|
36
|
-
* @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
|
|
37
|
-
*/
|
|
38
|
-
resetSegments(names: string[]): boolean {
|
|
39
|
-
let isDiff = false;
|
|
40
|
-
let index;
|
|
41
|
-
|
|
42
|
-
const storedSegmentKeys = Object.keys(this.segmentCache);
|
|
43
32
|
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
// Quick path
|
|
49
|
-
if (storedSegmentKeys.length !== names.length) {
|
|
50
|
-
isDiff = true;
|
|
51
|
-
|
|
52
|
-
this.segmentCache = {};
|
|
53
|
-
names.forEach(s => {
|
|
54
|
-
this.addToSegment(s);
|
|
55
|
-
});
|
|
56
|
-
} else {
|
|
57
|
-
// Slowest path => we need to find at least 1 difference because
|
|
58
|
-
for (index = 0; index < names.length && this.isInSegment(names[index]); index++) {
|
|
59
|
-
// TODO: why empty statement?
|
|
60
|
-
}
|
|
61
|
-
|
|
62
|
-
if (index < names.length) {
|
|
63
|
-
isDiff = true;
|
|
64
|
-
|
|
65
|
-
this.segmentCache = {};
|
|
66
|
-
names.forEach(s => {
|
|
67
|
-
this.addToSegment(s);
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
}
|
|
33
|
+
setChangeNumber(name?: string, changeNumber?: number) {
|
|
34
|
+
this.cn = changeNumber;
|
|
35
|
+
}
|
|
71
36
|
|
|
72
|
-
|
|
37
|
+
getChangeNumber() {
|
|
38
|
+
return this.cn || -1;
|
|
73
39
|
}
|
|
74
40
|
|
|
75
41
|
getRegisteredSegments() {
|
|
@@ -13,7 +13,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
13
13
|
private splitsCache: Record<string, ISplit> = {};
|
|
14
14
|
private ttCache: Record<string, number> = {};
|
|
15
15
|
private changeNumber: number = -1;
|
|
16
|
-
private
|
|
16
|
+
private segmentsCount: number = 0;
|
|
17
17
|
private flagSetsCache: Record<string, ISet<string>> = {};
|
|
18
18
|
|
|
19
19
|
constructor(splitFiltersValidation?: ISplitFiltersValidation) {
|
|
@@ -25,7 +25,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
25
25
|
this.splitsCache = {};
|
|
26
26
|
this.ttCache = {};
|
|
27
27
|
this.changeNumber = -1;
|
|
28
|
-
this.
|
|
28
|
+
this.segmentsCount = 0;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
31
|
addSplit(name: string, split: ISplit): boolean {
|
|
@@ -38,9 +38,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
38
38
|
|
|
39
39
|
this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
|
|
40
40
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
}
|
|
41
|
+
// Subtract from segments count for the previous version of this Split
|
|
42
|
+
if (usesSegments(previousSplit)) this.segmentsCount--;
|
|
44
43
|
}
|
|
45
44
|
|
|
46
45
|
if (split) {
|
|
@@ -52,7 +51,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
52
51
|
this.addToFlagSets(split);
|
|
53
52
|
|
|
54
53
|
// Add to segments count for the new version of the Split
|
|
55
|
-
if (usesSegments(split)) this.
|
|
54
|
+
if (usesSegments(split)) this.segmentsCount++;
|
|
56
55
|
|
|
57
56
|
return true;
|
|
58
57
|
} else {
|
|
@@ -72,7 +71,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
72
71
|
this.removeFromFlagSets(split.name, split.sets);
|
|
73
72
|
|
|
74
73
|
// Update the segments count.
|
|
75
|
-
if (usesSegments(split)) this.
|
|
74
|
+
if (usesSegments(split)) this.segmentsCount--;
|
|
76
75
|
|
|
77
76
|
return true;
|
|
78
77
|
} else {
|
|
@@ -102,7 +101,7 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
102
101
|
}
|
|
103
102
|
|
|
104
103
|
usesSegments(): boolean {
|
|
105
|
-
return this.getChangeNumber() === -1 || this.
|
|
104
|
+
return this.getChangeNumber() === -1 || this.segmentsCount > 0;
|
|
106
105
|
}
|
|
107
106
|
|
|
108
107
|
getNamesByFlagSets(flagSets: string[]): ISet<string>[] {
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies, TelemetryUsageStatsPayload, UpdatesFromSSEEnum } from '../../sync/submitters/types';
|
|
1
|
+
import { ImpressionDataType, EventDataType, LastSync, HttpErrors, HttpLatencies, StreamingEvent, Method, OperationType, MethodExceptions, MethodLatencies, TelemetryUsageStatsPayload, UpdatesFromSSEEnum, UpdatesFromSSE } from '../../sync/submitters/types';
|
|
2
2
|
import { DEDUPED, DROPPED, LOCALHOST_MODE, QUEUED } from '../../utils/constants';
|
|
3
3
|
import { findLatencyIndex } from '../findLatencyIndex';
|
|
4
4
|
import { ISegmentsCacheSync, ISplitsCacheSync, IStorageFactoryParams, ITelemetryCacheSync } from '../types';
|
|
@@ -25,7 +25,7 @@ export function shouldRecordTelemetry({ settings }: IStorageFactoryParams) {
|
|
|
25
25
|
|
|
26
26
|
export class TelemetryCacheInMemory implements ITelemetryCacheSync {
|
|
27
27
|
|
|
28
|
-
constructor(private splits?: ISplitsCacheSync, private segments?: ISegmentsCacheSync) { }
|
|
28
|
+
constructor(private splits?: ISplitsCacheSync, private segments?: ISegmentsCacheSync, private largeSegments?: ISegmentsCacheSync) { }
|
|
29
29
|
|
|
30
30
|
// isEmpty flag
|
|
31
31
|
private e = true;
|
|
@@ -51,6 +51,8 @@ export class TelemetryCacheInMemory implements ITelemetryCacheSync {
|
|
|
51
51
|
spC: this.splits && this.splits.getSplitNames().length,
|
|
52
52
|
seC: this.segments && this.segments.getRegisteredSegments().length,
|
|
53
53
|
skC: this.segments && this.segments.getKeysCount(),
|
|
54
|
+
lsC: this.largeSegments && this.largeSegments.getRegisteredSegments().length,
|
|
55
|
+
lskC: this.largeSegments && this.largeSegments.getKeysCount(),
|
|
54
56
|
sL: this.getSessionLength(),
|
|
55
57
|
eQ: this.getEventStats(QUEUED),
|
|
56
58
|
eD: this.getEventStats(DROPPED),
|
|
@@ -245,22 +247,16 @@ export class TelemetryCacheInMemory implements ITelemetryCacheSync {
|
|
|
245
247
|
this.e = false;
|
|
246
248
|
}
|
|
247
249
|
|
|
248
|
-
private updatesFromSSE = {
|
|
249
|
-
sp: 0,
|
|
250
|
-
ms: 0
|
|
251
|
-
};
|
|
250
|
+
private updatesFromSSE: UpdatesFromSSE = {};
|
|
252
251
|
|
|
253
252
|
popUpdatesFromSSE() {
|
|
254
253
|
const result = this.updatesFromSSE;
|
|
255
|
-
this.updatesFromSSE = {
|
|
256
|
-
sp: 0,
|
|
257
|
-
ms: 0,
|
|
258
|
-
};
|
|
254
|
+
this.updatesFromSSE = {};
|
|
259
255
|
return result;
|
|
260
256
|
}
|
|
261
257
|
|
|
262
258
|
recordUpdatesFromSSE(type: UpdatesFromSSEEnum) {
|
|
263
|
-
this.updatesFromSSE[type]
|
|
259
|
+
this.updatesFromSSE[type] = (this.updatesFromSSE[type] || 0) + 1;
|
|
264
260
|
this.e = false;
|
|
265
261
|
}
|
|
266
262
|
|
|
@@ -7,7 +7,7 @@ import { ISet, setToArray, _Set } from '../../utils/lang/sets';
|
|
|
7
7
|
* The `_cache` property is the object were items are stored.
|
|
8
8
|
* Intended for testing purposes.
|
|
9
9
|
*
|
|
10
|
-
* @param connDelay delay in millis for `connect` resolve. If not provided, `connect` resolves
|
|
10
|
+
* @param connDelay delay in millis for `connect` resolve. If not provided, `connect` resolves immediately.
|
|
11
11
|
*/
|
|
12
12
|
export function inMemoryWrapperFactory(connDelay?: number): IPluggableStorageWrapper & { _cache: Record<string, string | string[] | ISet<string>>, _setConnDelay(connDelay: number): void } {
|
|
13
13
|
|
package/src/storages/types.ts
CHANGED
|
@@ -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';
|
|
@@ -204,7 +205,7 @@ export interface ISplitsCacheBase {
|
|
|
204
205
|
getSplitNames(): MaybeThenable<string[]>,
|
|
205
206
|
// should never reject or throw an exception. Instead return true by default, asssuming the TT might exist.
|
|
206
207
|
trafficTypeExists(trafficType: string): MaybeThenable<boolean>,
|
|
207
|
-
// only for Client-Side
|
|
208
|
+
// only for Client-Side. Returns true if the storage is not synchronized yet (getChangeNumber() === -1) or contains a FF using segments or large segments
|
|
208
209
|
usesSegments(): MaybeThenable<boolean>,
|
|
209
210
|
clear(): MaybeThenable<boolean | void>,
|
|
210
211
|
// should never reject or throw an exception. Instead return false by default, to avoid emitting SDK_READY_FROM_CACHE.
|
|
@@ -218,7 +219,7 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
218
219
|
removeSplits(names: string[]): boolean[],
|
|
219
220
|
getSplit(name: string): ISplit | null,
|
|
220
221
|
getSplits(names: string[]): Record<string, ISplit | null>,
|
|
221
|
-
setChangeNumber(changeNumber: number): boolean,
|
|
222
|
+
setChangeNumber(changeNumber: number): boolean | void,
|
|
222
223
|
getChangeNumber(): number,
|
|
223
224
|
getAll(): ISplit[],
|
|
224
225
|
getSplitNames(): string[],
|
|
@@ -268,9 +269,9 @@ export interface ISegmentsCacheSync extends ISegmentsCacheBase {
|
|
|
268
269
|
registerSegments(names: string[]): boolean
|
|
269
270
|
getRegisteredSegments(): string[]
|
|
270
271
|
getKeysCount(): number // only used for telemetry
|
|
271
|
-
setChangeNumber(name: string, changeNumber: number): boolean
|
|
272
|
-
getChangeNumber(name
|
|
273
|
-
resetSegments(
|
|
272
|
+
setChangeNumber(name: string, changeNumber: number): boolean | void
|
|
273
|
+
getChangeNumber(name?: string): number
|
|
274
|
+
resetSegments(segmentsData: MySegmentsData | IMySegmentsResponse): boolean // only for Sync Client-Side
|
|
274
275
|
clear(): void
|
|
275
276
|
}
|
|
276
277
|
|
|
@@ -477,7 +478,10 @@ export interface IStorageSync extends IStorageBase<
|
|
|
477
478
|
IEventsCacheSync,
|
|
478
479
|
ITelemetryCacheSync,
|
|
479
480
|
IUniqueKeysCacheSync
|
|
480
|
-
> {
|
|
481
|
+
> {
|
|
482
|
+
// Defined in client-side
|
|
483
|
+
largeSegments?: ISegmentsCacheSync,
|
|
484
|
+
}
|
|
481
485
|
|
|
482
486
|
export interface IStorageAsync extends IStorageBase<
|
|
483
487
|
ISplitsCacheAsync,
|
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
1
|
+
import { IFetchMemberships, IResponse } from '../../../services/types';
|
|
2
|
+
import { IMembershipsResponse } from '../../../dtos/types';
|
|
3
3
|
import { IMySegmentsFetcher } from './types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Factory of MySegments fetcher.
|
|
7
7
|
* MySegments fetcher is a wrapper around `mySegments` API service that parses the response and handle errors.
|
|
8
8
|
*/
|
|
9
|
-
export function mySegmentsFetcherFactory(
|
|
9
|
+
export function mySegmentsFetcherFactory(fetchMemberships: IFetchMemberships): IMySegmentsFetcher {
|
|
10
10
|
|
|
11
11
|
return function mySegmentsFetcher(
|
|
12
12
|
userMatchingKey: string,
|
|
13
13
|
noCache?: boolean,
|
|
14
|
-
|
|
14
|
+
till?: number,
|
|
15
|
+
// Optional decorator for `fetchMemberships` promise, such as timeout or time tracker
|
|
15
16
|
decorator?: (promise: Promise<IResponse>) => Promise<IResponse>
|
|
16
|
-
): Promise<
|
|
17
|
+
): Promise<IMembershipsResponse> {
|
|
17
18
|
|
|
18
|
-
let mySegmentsPromise =
|
|
19
|
+
let mySegmentsPromise = fetchMemberships(userMatchingKey, noCache, till);
|
|
19
20
|
if (decorator) mySegmentsPromise = decorator(mySegmentsPromise);
|
|
20
21
|
|
|
21
|
-
|
|
22
|
-
return mySegmentsPromise
|
|
23
|
-
.then(resp => resp.json())
|
|
24
|
-
.then(json => json.mySegments.map((segment: IMySegmentsResponseItem) => segment.name));
|
|
22
|
+
return mySegmentsPromise.then(resp => resp.json());
|
|
25
23
|
};
|
|
26
24
|
|
|
27
25
|
}
|
|
@@ -28,7 +28,7 @@ export function segmentChangesFetcherFactory(fetchSegmentChanges: IFetchSegmentC
|
|
|
28
28
|
segmentName: string,
|
|
29
29
|
noCache?: boolean,
|
|
30
30
|
till?: number,
|
|
31
|
-
// Optional decorator for `
|
|
31
|
+
// Optional decorator for `fetchSegmentChanges` promise, such as timeout or time tracker
|
|
32
32
|
decorator?: (promise: Promise<ISegmentChangesResponse[]>) => Promise<ISegmentChangesResponse[]>
|
|
33
33
|
): Promise<ISegmentChangesResponse[]> {
|
|
34
34
|
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { ISplitChangesResponse, ISegmentChangesResponse } from '../../../dtos/types';
|
|
1
|
+
import { ISplitChangesResponse, ISegmentChangesResponse, IMembershipsResponse } from '../../../dtos/types';
|
|
2
2
|
import { IResponse } from '../../../services/types';
|
|
3
3
|
|
|
4
4
|
export type ISplitChangesFetcher = (
|
|
@@ -19,5 +19,6 @@ export type ISegmentChangesFetcher = (
|
|
|
19
19
|
export type IMySegmentsFetcher = (
|
|
20
20
|
userMatchingKey: string,
|
|
21
21
|
noCache?: boolean,
|
|
22
|
+
till?: number,
|
|
22
23
|
decorator?: (promise: Promise<IResponse>) => Promise<IResponse>
|
|
23
|
-
) => Promise<
|
|
24
|
+
) => Promise<IMembershipsResponse>
|
|
@@ -29,13 +29,13 @@ export function pollingManagerCSFactory(
|
|
|
29
29
|
const mySegmentsSyncTask = add(matchingKey, readiness, storage);
|
|
30
30
|
|
|
31
31
|
function startMySegmentsSyncTasks() {
|
|
32
|
-
forOwn(mySegmentsSyncTasks,
|
|
32
|
+
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
|
|
33
33
|
mySegmentsSyncTask.start();
|
|
34
34
|
});
|
|
35
35
|
}
|
|
36
36
|
|
|
37
37
|
function stopMySegmentsSyncTasks() {
|
|
38
|
-
forOwn(mySegmentsSyncTasks,
|
|
38
|
+
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
|
|
39
39
|
if (mySegmentsSyncTask.isRunning()) mySegmentsSyncTask.stop();
|
|
40
40
|
});
|
|
41
41
|
}
|
|
@@ -55,7 +55,7 @@ export function pollingManagerCSFactory(
|
|
|
55
55
|
});
|
|
56
56
|
|
|
57
57
|
function add(matchingKey: string, readiness: IReadinessManager, storage: IStorageSync) {
|
|
58
|
-
const mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.
|
|
58
|
+
const mySegmentsSyncTask = mySegmentsSyncTaskFactory(splitApi.fetchMemberships, storage, readiness, settings, matchingKey);
|
|
59
59
|
|
|
60
60
|
// smart ready
|
|
61
61
|
function smartReady() {
|
|
@@ -94,7 +94,7 @@ export function pollingManagerCSFactory(
|
|
|
94
94
|
// fetch splits and segments
|
|
95
95
|
syncAll() {
|
|
96
96
|
const promises = [splitsSyncTask.execute()];
|
|
97
|
-
forOwn(mySegmentsSyncTasks,
|
|
97
|
+
forOwn(mySegmentsSyncTasks, (mySegmentsSyncTask) => {
|
|
98
98
|
promises.push(mySegmentsSyncTask.execute());
|
|
99
99
|
});
|
|
100
100
|
return Promise.all(promises);
|
|
@@ -2,7 +2,7 @@ import { IStorageSync } from '../../../storages/types';
|
|
|
2
2
|
import { IReadinessManager } from '../../../readiness/types';
|
|
3
3
|
import { syncTaskFactory } from '../../syncTask';
|
|
4
4
|
import { IMySegmentsSyncTask } from '../types';
|
|
5
|
-
import {
|
|
5
|
+
import { IFetchMemberships } from '../../../services/types';
|
|
6
6
|
import { mySegmentsFetcherFactory } from '../fetchers/mySegmentsFetcher';
|
|
7
7
|
import { ISettings } from '../../../types';
|
|
8
8
|
import { mySegmentsUpdaterFactory } from '../updaters/mySegmentsUpdater';
|
|
@@ -11,7 +11,7 @@ import { mySegmentsUpdaterFactory } from '../updaters/mySegmentsUpdater';
|
|
|
11
11
|
* Creates a sync task that periodically executes a `mySegmentsUpdater` task
|
|
12
12
|
*/
|
|
13
13
|
export function mySegmentsSyncTaskFactory(
|
|
14
|
-
|
|
14
|
+
fetchMemberships: IFetchMemberships,
|
|
15
15
|
storage: IStorageSync,
|
|
16
16
|
readiness: IReadinessManager,
|
|
17
17
|
settings: ISettings,
|
|
@@ -21,9 +21,8 @@ export function mySegmentsSyncTaskFactory(
|
|
|
21
21
|
settings.log,
|
|
22
22
|
mySegmentsUpdaterFactory(
|
|
23
23
|
settings.log,
|
|
24
|
-
mySegmentsFetcherFactory(
|
|
25
|
-
storage
|
|
26
|
-
storage.segments,
|
|
24
|
+
mySegmentsFetcherFactory(fetchMemberships),
|
|
25
|
+
storage,
|
|
27
26
|
readiness.segments,
|
|
28
27
|
settings.startup.requestTimeoutBeforeReady,
|
|
29
28
|
settings.startup.retriesOnFailureBeforeReady,
|
|
@@ -1,20 +1,21 @@
|
|
|
1
1
|
import { ISplit } from '../../dtos/types';
|
|
2
2
|
import { IReadinessManager } from '../../readiness/types';
|
|
3
3
|
import { IStorageSync } from '../../storages/types';
|
|
4
|
+
import { MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../streaming/types';
|
|
4
5
|
import { ITask, ISyncTask } from '../types';
|
|
5
6
|
|
|
6
7
|
export interface ISplitsSyncTask extends ISyncTask<[noCache?: boolean, till?: number, splitUpdateNotification?: { payload: ISplit, changeNumber: number }], boolean> { }
|
|
7
8
|
|
|
8
9
|
export interface ISegmentsSyncTask extends ISyncTask<[fetchOnlyNew?: boolean, segmentName?: string, noCache?: boolean, till?: number], boolean> { }
|
|
9
10
|
|
|
10
|
-
export type MySegmentsData =
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
11
|
+
export type MySegmentsData = {
|
|
12
|
+
type: MEMBERSHIPS_MS_UPDATE | MEMBERSHIPS_LS_UPDATE
|
|
13
|
+
cn: number
|
|
14
|
+
added: string[]
|
|
15
|
+
removed: string[]
|
|
15
16
|
}
|
|
16
17
|
|
|
17
|
-
export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean], boolean> { }
|
|
18
|
+
export interface IMySegmentsSyncTask extends ISyncTask<[segmentsData?: MySegmentsData, noCache?: boolean, till?: number], boolean> { }
|
|
18
19
|
|
|
19
20
|
export interface IPollingManager extends ITask {
|
|
20
21
|
syncAll(): Promise<any>
|
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
import { IMySegmentsFetcher } from '../fetchers/types';
|
|
2
|
-
import {
|
|
2
|
+
import { IStorageSync } from '../../../storages/types';
|
|
3
3
|
import { ISegmentsEventEmitter } from '../../../readiness/types';
|
|
4
4
|
import { timeout } from '../../../utils/promise/timeout';
|
|
5
5
|
import { SDK_SEGMENTS_ARRIVED } from '../../../readiness/constants';
|
|
6
6
|
import { ILogger } from '../../../logger/types';
|
|
7
7
|
import { SYNC_MYSEGMENTS_FETCH_RETRY } from '../../../logger/constants';
|
|
8
8
|
import { MySegmentsData } from '../types';
|
|
9
|
+
import { IMembershipsResponse } from '../../../dtos/types';
|
|
10
|
+
import { MEMBERSHIPS_LS_UPDATE } from '../../streaming/constants';
|
|
9
11
|
|
|
10
|
-
type IMySegmentsUpdater = (
|
|
12
|
+
type IMySegmentsUpdater = (segmentsData?: MySegmentsData, noCache?: boolean, till?: number) => Promise<boolean>
|
|
11
13
|
|
|
12
14
|
/**
|
|
13
15
|
* factory of MySegments updater, a task that:
|
|
@@ -18,14 +20,14 @@ type IMySegmentsUpdater = (segmentList?: string[], noCache?: boolean) => Promise
|
|
|
18
20
|
export function mySegmentsUpdaterFactory(
|
|
19
21
|
log: ILogger,
|
|
20
22
|
mySegmentsFetcher: IMySegmentsFetcher,
|
|
21
|
-
|
|
22
|
-
mySegmentsCache: ISegmentsCacheSync,
|
|
23
|
+
storage: IStorageSync,
|
|
23
24
|
segmentsEventEmitter: ISegmentsEventEmitter,
|
|
24
25
|
requestTimeoutBeforeReady: number,
|
|
25
26
|
retriesOnFailureBeforeReady: number,
|
|
26
27
|
matchingKey: string
|
|
27
28
|
): IMySegmentsUpdater {
|
|
28
29
|
|
|
30
|
+
const { splits, segments, largeSegments } = storage;
|
|
29
31
|
let readyOnAlreadyExistentState = true;
|
|
30
32
|
let startingUp = true;
|
|
31
33
|
|
|
@@ -36,37 +38,31 @@ export function mySegmentsUpdaterFactory(
|
|
|
36
38
|
}
|
|
37
39
|
|
|
38
40
|
// @TODO if allowing pluggable storages, handle async execution
|
|
39
|
-
function updateSegments(segmentsData: MySegmentsData) {
|
|
41
|
+
function updateSegments(segmentsData: IMembershipsResponse | MySegmentsData) {
|
|
40
42
|
|
|
41
43
|
let shouldNotifyUpdate;
|
|
42
|
-
if (
|
|
43
|
-
|
|
44
|
-
|
|
44
|
+
if ((segmentsData as MySegmentsData).type !== undefined) {
|
|
45
|
+
shouldNotifyUpdate = (segmentsData as MySegmentsData).type === MEMBERSHIPS_LS_UPDATE ?
|
|
46
|
+
largeSegments!.resetSegments(segmentsData as MySegmentsData) :
|
|
47
|
+
segments.resetSegments(segmentsData as MySegmentsData);
|
|
45
48
|
} else {
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
if (mySegmentsCache.isInSegment(name) !== add) {
|
|
49
|
-
shouldNotifyUpdate = true;
|
|
50
|
-
if (add) mySegmentsCache.addToSegment(name);
|
|
51
|
-
else mySegmentsCache.removeFromSegment(name);
|
|
52
|
-
} else {
|
|
53
|
-
shouldNotifyUpdate = false;
|
|
54
|
-
}
|
|
49
|
+
shouldNotifyUpdate = segments.resetSegments((segmentsData as IMembershipsResponse).ms || {});
|
|
50
|
+
shouldNotifyUpdate = largeSegments!.resetSegments((segmentsData as IMembershipsResponse).ls || {}) || shouldNotifyUpdate;
|
|
55
51
|
}
|
|
56
52
|
|
|
57
53
|
// Notify update if required
|
|
58
|
-
if (
|
|
54
|
+
if (splits.usesSegments() && (shouldNotifyUpdate || readyOnAlreadyExistentState)) {
|
|
59
55
|
readyOnAlreadyExistentState = false;
|
|
60
56
|
segmentsEventEmitter.emit(SDK_SEGMENTS_ARRIVED);
|
|
61
57
|
}
|
|
62
58
|
}
|
|
63
59
|
|
|
64
|
-
function _mySegmentsUpdater(retry: number, segmentsData?: MySegmentsData, noCache?: boolean): Promise<boolean> {
|
|
60
|
+
function _mySegmentsUpdater(retry: number, segmentsData?: MySegmentsData, noCache?: boolean, till?: number): Promise<boolean> {
|
|
65
61
|
const updaterPromise: Promise<boolean> = segmentsData ?
|
|
66
62
|
// If segmentsData is provided, there is no need to fetch mySegments
|
|
67
63
|
new Promise((res) => { updateSegments(segmentsData); res(true); }) :
|
|
68
64
|
// If not provided, fetch mySegments
|
|
69
|
-
mySegmentsFetcher(matchingKey, noCache, _promiseDecorator).then(segments => {
|
|
65
|
+
mySegmentsFetcher(matchingKey, noCache, till, _promiseDecorator).then(segments => {
|
|
70
66
|
// Only when we have downloaded segments completely, we should not keep retrying anymore
|
|
71
67
|
startingUp = false;
|
|
72
68
|
|
|
@@ -96,9 +92,10 @@ export function mySegmentsUpdaterFactory(
|
|
|
96
92
|
* (2) an object with a segment name and action (true: add, or false: delete) to update the storage,
|
|
97
93
|
* (3) or `undefined`, for which the updater will fetch mySegments in order to sync the storage.
|
|
98
94
|
* @param {boolean | undefined} noCache true to revalidate data to fetch
|
|
95
|
+
* @param {boolean | undefined} till query param to bypass CDN requests
|
|
99
96
|
*/
|
|
100
|
-
return function mySegmentsUpdater(segmentsData?: MySegmentsData, noCache?: boolean) {
|
|
101
|
-
return _mySegmentsUpdater(0, segmentsData, noCache);
|
|
97
|
+
return function mySegmentsUpdater(segmentsData?: MySegmentsData, noCache?: boolean, till?: number) {
|
|
98
|
+
return _mySegmentsUpdater(0, segmentsData, noCache, till);
|
|
102
99
|
};
|
|
103
100
|
|
|
104
101
|
}
|
|
@@ -14,7 +14,7 @@ export function authenticateFactory(fetchAuth: IFetchAuth): IAuthenticate {
|
|
|
14
14
|
|
|
15
15
|
/**
|
|
16
16
|
* Run authentication requests to Auth Server, and returns a promise that resolves with the decoded JTW token.
|
|
17
|
-
* @param {string[] | undefined} userKeys set of user Keys to track
|
|
17
|
+
* @param {string[] | undefined} userKeys set of user Keys to track membership updates. It is undefined for server-side API.
|
|
18
18
|
*/
|
|
19
19
|
return function authenticate(userKeys?: string[]): Promise<IAuthToken> {
|
|
20
20
|
return fetchAuth(userKeys)
|
|
@@ -71,24 +71,22 @@ export class SSEClient implements ISSEClient {
|
|
|
71
71
|
open(authToken: IAuthTokenPushEnabled) {
|
|
72
72
|
this.close(); // it closes connection if previously opened
|
|
73
73
|
|
|
74
|
-
const channelsQueryParam = Object.keys(authToken.channels).map(
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
}
|
|
79
|
-
).join(',');
|
|
74
|
+
const channelsQueryParam = Object.keys(authToken.channels).map((channel) => {
|
|
75
|
+
const params = CONTROL_CHANNEL_REGEX.test(channel) ? '[?occupancy=metrics.publishers]' : '';
|
|
76
|
+
return encodeURIComponent(params + channel);
|
|
77
|
+
}).join(',');
|
|
80
78
|
const url = `${this.settings.urls.streaming}/sse?channels=${channelsQueryParam}&accessToken=${authToken.token}&v=${ABLY_API_VERSION}&heartbeats=true`; // same results using `&heartbeats=false`
|
|
81
79
|
const isServerSide = !this.settings.core.key;
|
|
82
80
|
|
|
83
81
|
this.connection = new this.eventSource!(
|
|
84
82
|
// For client-side SDKs, metadata is passed as query param to avoid CORS issues and because native EventSource implementations in browsers do not support headers
|
|
85
83
|
isServerSide ? url : url + `&SplitSDKVersion=${this.headers.SplitSDKVersion}&SplitSDKClientKey=${this.headers.SplitSDKClientKey}`,
|
|
86
|
-
// For server-side SDKs, metadata is passed via headers
|
|
84
|
+
// For server-side SDKs, metadata is passed via headers
|
|
87
85
|
objectAssign(
|
|
88
86
|
isServerSide ?
|
|
89
87
|
{ headers: decorateHeaders(this.settings, this.headers) } :
|
|
90
88
|
this.settings.sync.requestOptions?.getHeaderOverrides ?
|
|
91
|
-
{ headers: decorateHeaders(this.settings, {}) } : //
|
|
89
|
+
{ headers: decorateHeaders(this.settings, {}) } : // User must provide a window.EventSource polyfill that supports headers
|
|
92
90
|
{},
|
|
93
91
|
this.options
|
|
94
92
|
)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { errorParser, messageParser } from './NotificationParser';
|
|
2
2
|
import { notificationKeeperFactory } from './NotificationKeeper';
|
|
3
|
-
import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL,
|
|
3
|
+
import { PUSH_RETRYABLE_ERROR, PUSH_NONRETRYABLE_ERROR, OCCUPANCY, CONTROL, SEGMENT_UPDATE, SPLIT_KILL, SPLIT_UPDATE, MEMBERSHIPS_MS_UPDATE, MEMBERSHIPS_LS_UPDATE } from '../constants';
|
|
4
4
|
import { IPushEventEmitter } from '../types';
|
|
5
5
|
import { ISseEventHandler } from '../SSEClient/types';
|
|
6
6
|
import { INotificationError, INotificationMessage } from './types';
|
|
@@ -74,21 +74,18 @@ export function SSEHandlerFactory(log: ILogger, pushEmitter: IPushEventEmitter,
|
|
|
74
74
|
const { parsedData, data, channel, timestamp } = messageWithParsedData;
|
|
75
75
|
log.debug(STREAMING_NEW_MESSAGE, [data]);
|
|
76
76
|
|
|
77
|
-
// we only handle update events if streaming is up
|
|
78
|
-
if (!notificationKeeper.isStreamingUp() && [OCCUPANCY, CONTROL].indexOf(parsedData.type) === -1)
|
|
79
|
-
return;
|
|
77
|
+
// we only handle update events if streaming is up
|
|
78
|
+
if (!notificationKeeper.isStreamingUp() && [OCCUPANCY, CONTROL].indexOf(parsedData.type) === -1) return;
|
|
80
79
|
|
|
81
80
|
switch (parsedData.type) {
|
|
82
81
|
/* update events */
|
|
83
82
|
case SPLIT_UPDATE:
|
|
84
83
|
case SEGMENT_UPDATE:
|
|
85
|
-
case
|
|
84
|
+
case MEMBERSHIPS_MS_UPDATE:
|
|
85
|
+
case MEMBERSHIPS_LS_UPDATE:
|
|
86
86
|
case SPLIT_KILL:
|
|
87
87
|
pushEmitter.emit(parsedData.type, parsedData);
|
|
88
88
|
break;
|
|
89
|
-
case MY_SEGMENTS_UPDATE:
|
|
90
|
-
pushEmitter.emit(parsedData.type, parsedData, channel);
|
|
91
|
-
break;
|
|
92
89
|
|
|
93
90
|
/* occupancy & control events, handled by NotificationManagerKeeper */
|
|
94
91
|
case OCCUPANCY:
|
|
@@ -1,12 +1,5 @@
|
|
|
1
1
|
import { ControlType } from '../constants';
|
|
2
|
-
import {
|
|
3
|
-
|
|
4
|
-
export interface IMySegmentsUpdateData {
|
|
5
|
-
type: MY_SEGMENTS_UPDATE,
|
|
6
|
-
changeNumber: number,
|
|
7
|
-
includesPayload: boolean,
|
|
8
|
-
segmentList?: string[]
|
|
9
|
-
}
|
|
2
|
+
import { SEGMENT_UPDATE, SPLIT_UPDATE, SPLIT_KILL, CONTROL, OCCUPANCY, MEMBERSHIPS_LS_UPDATE, MEMBERSHIPS_MS_UPDATE } from '../types';
|
|
10
3
|
|
|
11
4
|
export enum Compression {
|
|
12
5
|
None = 0,
|
|
@@ -26,15 +19,22 @@ export interface KeyList {
|
|
|
26
19
|
r?: string[], // decimal hash64 of user keys
|
|
27
20
|
}
|
|
28
21
|
|
|
29
|
-
|
|
30
|
-
type:
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
c
|
|
34
|
-
d
|
|
22
|
+
interface IMembershipUpdateData<T extends string> {
|
|
23
|
+
type: T,
|
|
24
|
+
cn: number,
|
|
25
|
+
n?: string[],
|
|
26
|
+
c?: Compression,
|
|
27
|
+
d?: string,
|
|
35
28
|
u: UpdateStrategy,
|
|
29
|
+
i?: number, // time interval in millis
|
|
30
|
+
h?: number, // hash function
|
|
31
|
+
s?: number, // seed for hash function
|
|
36
32
|
}
|
|
37
33
|
|
|
34
|
+
export interface IMembershipMSUpdateData extends IMembershipUpdateData<MEMBERSHIPS_MS_UPDATE> { }
|
|
35
|
+
|
|
36
|
+
export interface IMembershipLSUpdateData extends IMembershipUpdateData<MEMBERSHIPS_LS_UPDATE> { }
|
|
37
|
+
|
|
38
38
|
export interface ISegmentUpdateData {
|
|
39
39
|
type: SEGMENT_UPDATE,
|
|
40
40
|
changeNumber: number,
|
|
@@ -68,6 +68,6 @@ export interface IOccupancyData {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
|
|
71
|
-
export type INotificationData =
|
|
71
|
+
export type INotificationData = IMembershipMSUpdateData | IMembershipLSUpdateData | ISegmentUpdateData | ISplitUpdateData | ISplitKillData | IControlData | IOccupancyData
|
|
72
72
|
export type INotificationMessage = { parsedData: INotificationData, channel: string, timestamp: number, data: string }
|
|
73
73
|
export type INotificationError = Event & { parsedData?: any, message?: string }
|