@splitsoftware/splitio-commons 1.16.0 → 1.16.1-rc.1
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 +3 -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 +1 -1
- package/cjs/logger/constants.js +4 -4
- package/cjs/logger/messages/info.js +0 -1
- package/cjs/readiness/readinessManager.js +14 -10
- package/cjs/readiness/sdkReadinessManager.js +5 -6
- package/cjs/sdkClient/sdkClientMethodCS.js +3 -4
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +4 -5
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/services/splitApi.js +4 -0
- package/cjs/storages/AbstractSplitsCacheAsync.js +2 -2
- package/cjs/storages/AbstractSplitsCacheSync.js +5 -5
- package/cjs/storages/KeyBuilder.js +3 -0
- package/cjs/storages/KeyBuilderCS.js +17 -5
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +16 -4
- package/cjs/storages/inLocalStorage/index.js +6 -2
- package/cjs/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +20 -11
- package/cjs/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/cjs/storages/pluggable/inMemoryWrapper.js +1 -1
- package/cjs/sync/polling/fetchers/mySegmentsFetcher.js +5 -1
- package/cjs/sync/polling/pollingManagerCS.js +51 -33
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +5 -6
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/cjs/sync/streaming/SSEHandler/index.js +1 -0
- package/cjs/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -5
- package/cjs/sync/streaming/constants.js +2 -1
- package/cjs/sync/streaming/pushManager.js +95 -64
- package/cjs/sync/submitters/telemetrySubmitter.js +2 -0
- package/cjs/sync/syncManagerOnline.js +24 -14
- package/cjs/utils/constants/index.js +5 -1
- package/cjs/utils/settingsValidation/index.js +9 -4
- 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 +1 -1
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +0 -1
- package/esm/readiness/readinessManager.js +14 -10
- package/esm/readiness/sdkReadinessManager.js +5 -6
- package/esm/sdkClient/sdkClientMethodCS.js +4 -5
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +5 -6
- package/esm/sdkFactory/index.js +1 -1
- package/esm/services/splitApi.js +5 -1
- package/esm/storages/AbstractSplitsCacheAsync.js +2 -2
- package/esm/storages/AbstractSplitsCacheSync.js +3 -3
- package/esm/storages/KeyBuilder.js +3 -0
- package/esm/storages/KeyBuilderCS.js +15 -4
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +17 -5
- package/esm/storages/inLocalStorage/index.js +7 -3
- package/esm/storages/inMemory/InMemoryStorageCS.js +5 -0
- package/esm/storages/inMemory/SplitsCacheInMemory.js +21 -12
- package/esm/storages/inMemory/TelemetryCacheInMemory.js +7 -10
- package/esm/storages/pluggable/inMemoryWrapper.js +1 -1
- package/esm/sync/polling/fetchers/mySegmentsFetcher.js +5 -1
- package/esm/sync/polling/pollingManagerCS.js +52 -34
- package/esm/sync/polling/syncTasks/mySegmentsSyncTask.js +2 -2
- package/esm/sync/polling/updaters/mySegmentsUpdater.js +3 -4
- package/esm/sync/polling/updaters/splitChangesUpdater.js +2 -1
- package/esm/sync/streaming/SSEHandler/index.js +2 -1
- package/esm/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.js +15 -5
- package/esm/sync/streaming/constants.js +1 -0
- package/esm/sync/streaming/pushManager.js +95 -65
- package/esm/sync/submitters/telemetrySubmitter.js +2 -0
- package/esm/sync/syncManagerOnline.js +25 -15
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/settingsValidation/index.js +10 -5
- package/package.json +1 -1
- package/src/dtos/types.ts +17 -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 +1 -1
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +0 -1
- package/src/readiness/readinessManager.ts +13 -9
- package/src/readiness/sdkReadinessManager.ts +7 -7
- package/src/readiness/types.ts +3 -2
- package/src/sdkClient/sdkClientMethodCS.ts +4 -6
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +5 -7
- package/src/sdkFactory/index.ts +1 -1
- package/src/services/splitApi.ts +6 -1
- package/src/services/types.ts +1 -0
- package/src/storages/AbstractSplitsCacheAsync.ts +2 -2
- package/src/storages/AbstractSplitsCacheSync.ts +4 -4
- package/src/storages/KeyBuilder.ts +3 -0
- package/src/storages/KeyBuilderCS.ts +25 -5
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +3 -3
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +20 -5
- package/src/storages/inLocalStorage/index.ts +8 -4
- package/src/storages/inMemory/InMemoryStorageCS.ts +5 -0
- package/src/storages/inMemory/SplitsCacheInMemory.ts +15 -10
- package/src/storages/inMemory/TelemetryCacheInMemory.ts +7 -11
- package/src/storages/pluggable/inMemoryWrapper.ts +1 -1
- package/src/storages/types.ts +7 -5
- package/src/sync/polling/fetchers/mySegmentsFetcher.ts +6 -2
- package/src/sync/polling/pollingManagerCS.ts +61 -29
- package/src/sync/polling/syncTasks/mySegmentsSyncTask.ts +10 -10
- package/src/sync/polling/types.ts +3 -2
- package/src/sync/polling/updaters/mySegmentsUpdater.ts +5 -8
- package/src/sync/polling/updaters/splitChangesUpdater.ts +4 -3
- package/src/sync/streaming/SSEHandler/index.ts +2 -1
- package/src/sync/streaming/SSEHandler/types.ts +14 -2
- package/src/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.ts +17 -5
- package/src/sync/streaming/constants.ts +1 -0
- package/src/sync/streaming/pushManager.ts +100 -63
- package/src/sync/streaming/types.ts +5 -3
- package/src/sync/submitters/telemetrySubmitter.ts +2 -0
- package/src/sync/submitters/types.ts +10 -4
- package/src/sync/syncManagerOnline.ts +19 -11
- package/src/types.ts +26 -1
- package/src/utils/constants/index.ts +5 -0
- package/src/utils/settingsValidation/index.ts +11 -6
- package/src/utils/settingsValidation/types.ts +1 -1
- package/types/dtos/types.d.ts +14 -6
- package/types/evaluator/matchers/large_segment.d.ts +5 -0
- 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 +3 -2
- package/types/services/types.d.ts +1 -0
- package/types/storages/AbstractSplitsCacheAsync.d.ts +1 -1
- package/types/storages/AbstractSplitsCacheSync.d.ts +3 -3
- package/types/storages/KeyBuilder.d.ts +1 -0
- package/types/storages/KeyBuilderCS.d.ts +7 -2
- package/types/storages/inLocalStorage/MySegmentsCacheInLocal.d.ts +2 -2
- package/types/storages/inLocalStorage/SplitsCacheInLocal.d.ts +1 -1
- package/types/storages/inMemory/SplitsCacheInMemory.d.ts +3 -2
- package/types/storages/inMemory/TelemetryCacheInMemory.d.ts +4 -6
- package/types/storages/pluggable/inMemoryWrapper.d.ts +1 -1
- package/types/storages/types.d.ts +4 -3
- package/types/sync/polling/syncTasks/mySegmentsSyncTask.d.ts +2 -3
- package/types/sync/polling/types.d.ts +9 -2
- package/types/sync/polling/updaters/mySegmentsUpdater.d.ts +4 -4
- package/types/sync/streaming/SSEHandler/types.d.ts +13 -2
- package/types/sync/streaming/UpdateWorkers/MySegmentsUpdateWorker.d.ts +2 -1
- package/types/sync/streaming/constants.d.ts +1 -0
- package/types/sync/streaming/pushManager.d.ts +2 -0
- package/types/sync/streaming/types.d.ts +5 -4
- package/types/sync/submitters/types.d.ts +9 -3
- package/types/types.d.ts +25 -0
- package/types/utils/constants/index.d.ts +3 -0
- package/types/utils/settingsValidation/index.d.ts +2 -0
- package/types/utils/settingsValidation/types.d.ts +1 -1
package/src/readiness/types.ts
CHANGED
|
@@ -45,6 +45,7 @@ export interface IReadinessManager {
|
|
|
45
45
|
/** Event emitters */
|
|
46
46
|
splits: ISplitsEventEmitter,
|
|
47
47
|
segments: ISegmentsEventEmitter,
|
|
48
|
+
largeSegments?: ISegmentsEventEmitter, // Undefined if largeSegmentsEnabled or waitForLargeSegments are false
|
|
48
49
|
gate: IReadinessEventEmitter,
|
|
49
50
|
|
|
50
51
|
/** Readiness status */
|
|
@@ -59,7 +60,7 @@ export interface IReadinessManager {
|
|
|
59
60
|
destroy(): void,
|
|
60
61
|
|
|
61
62
|
/** for client-side */
|
|
62
|
-
shared(
|
|
63
|
+
shared(): IReadinessManager,
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
/** SDK readiness manager */
|
|
@@ -75,5 +76,5 @@ export interface ISdkReadinessManager {
|
|
|
75
76
|
incInternalReadyCbCount(): void
|
|
76
77
|
|
|
77
78
|
/** for client-side */
|
|
78
|
-
shared(
|
|
79
|
+
shared(): ISdkReadinessManager
|
|
79
80
|
}
|
|
@@ -5,7 +5,7 @@ import { getMatching, keyParser } from '../utils/key';
|
|
|
5
5
|
import { sdkClientFactory } from './sdkClient';
|
|
6
6
|
import { ISyncManagerCS } from '../sync/types';
|
|
7
7
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
8
|
-
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
|
|
8
|
+
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
|
|
9
9
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
10
10
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
11
11
|
|
|
@@ -14,14 +14,12 @@ function buildInstanceId(key: SplitIO.SplitKey) {
|
|
|
14
14
|
return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-`;
|
|
15
15
|
}
|
|
16
16
|
|
|
17
|
-
const method = 'Client instantiation';
|
|
18
|
-
|
|
19
17
|
/**
|
|
20
18
|
* Factory of client method for the client-side API variant where TT is ignored.
|
|
21
19
|
* Therefore, clients don't have a bound TT for the track method.
|
|
22
20
|
*/
|
|
23
21
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
|
|
24
|
-
const { storage, syncManager, sdkReadinessManager, settings: { core: { key },
|
|
22
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, log } } = params;
|
|
25
23
|
|
|
26
24
|
const mainClientInstance = clientCSDecorator(
|
|
27
25
|
log,
|
|
@@ -43,7 +41,7 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
43
41
|
}
|
|
44
42
|
|
|
45
43
|
// Validate the key value. The trafficType (2nd argument) is ignored
|
|
46
|
-
const validKey = validateKey(log, key,
|
|
44
|
+
const validKey = validateKey(log, key, LOG_PREFIX_CLIENT_INSTANTIATION);
|
|
47
45
|
if (validKey === false) {
|
|
48
46
|
throw new Error('Shared Client needs a valid key.');
|
|
49
47
|
}
|
|
@@ -53,7 +51,7 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
53
51
|
if (!clientInstances[instanceId]) {
|
|
54
52
|
const matchingKey = getMatching(validKey);
|
|
55
53
|
|
|
56
|
-
const sharedSdkReadiness = sdkReadinessManager.shared(
|
|
54
|
+
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
57
55
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
58
56
|
if (err) {
|
|
59
57
|
sharedSdkReadiness.readinessManager.timeout();
|
|
@@ -6,7 +6,7 @@ import { getMatching, keyParser } from '../utils/key';
|
|
|
6
6
|
import { sdkClientFactory } from './sdkClient';
|
|
7
7
|
import { ISyncManagerCS } from '../sync/types';
|
|
8
8
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
9
|
-
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING } from '../logger/constants';
|
|
9
|
+
import { RETRIEVE_CLIENT_DEFAULT, NEW_SHARED_CLIENT, RETRIEVE_CLIENT_EXISTING, LOG_PREFIX_CLIENT_INSTANTIATION } from '../logger/constants';
|
|
10
10
|
import { SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
11
11
|
import { ISdkFactoryContext } from '../sdkFactory/types';
|
|
12
12
|
|
|
@@ -15,15 +15,13 @@ function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
|
|
|
15
15
|
return `${key.matchingKey ? key.matchingKey : key}-${key.bucketingKey ? key.bucketingKey : key}-${trafficType !== undefined ? trafficType : ''}`;
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
-
const method = 'Client instantiation';
|
|
19
|
-
|
|
20
18
|
/**
|
|
21
19
|
* Factory of client method for the client-side (browser) variant of the Isomorphic JS SDK,
|
|
22
20
|
* where clients can have a bound TT for the track method, which is provided via the settings
|
|
23
21
|
* (default client) or the client method (shared clients).
|
|
24
22
|
*/
|
|
25
23
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
|
|
26
|
-
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType },
|
|
24
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, log } } = params;
|
|
27
25
|
|
|
28
26
|
const mainClientInstance = clientCSDecorator(
|
|
29
27
|
log,
|
|
@@ -46,14 +44,14 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
46
44
|
}
|
|
47
45
|
|
|
48
46
|
// Validate the key value
|
|
49
|
-
const validKey = validateKey(log, key,
|
|
47
|
+
const validKey = validateKey(log, key, LOG_PREFIX_CLIENT_INSTANTIATION);
|
|
50
48
|
if (validKey === false) {
|
|
51
49
|
throw new Error('Shared Client needs a valid key.');
|
|
52
50
|
}
|
|
53
51
|
|
|
54
52
|
let validTrafficType;
|
|
55
53
|
if (trafficType !== undefined) {
|
|
56
|
-
validTrafficType = validateTrafficType(log, trafficType,
|
|
54
|
+
validTrafficType = validateTrafficType(log, trafficType, LOG_PREFIX_CLIENT_INSTANTIATION);
|
|
57
55
|
if (validTrafficType === false) {
|
|
58
56
|
throw new Error('Shared Client needs a valid traffic type or no traffic type at all.');
|
|
59
57
|
}
|
|
@@ -63,7 +61,7 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
63
61
|
if (!clientInstances[instanceId]) {
|
|
64
62
|
const matchingKey = getMatching(validKey);
|
|
65
63
|
|
|
66
|
-
const sharedSdkReadiness = sdkReadinessManager.shared(
|
|
64
|
+
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
67
65
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
68
66
|
if (err) {
|
|
69
67
|
sharedSdkReadiness.readinessManager.timeout();
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -32,7 +32,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
32
32
|
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
33
33
|
validateAndTrackApiKey(log, settings.core.authorizationKey);
|
|
34
34
|
|
|
35
|
-
const sdkReadinessManager = sdkReadinessManagerFactory(
|
|
35
|
+
const sdkReadinessManager = sdkReadinessManagerFactory(platform.EventEmitter, settings);
|
|
36
36
|
const readiness = sdkReadinessManager.readinessManager;
|
|
37
37
|
|
|
38
38
|
const storage = storageFactory({
|
package/src/services/splitApi.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { splitHttpClientFactory } from './splitHttpClient';
|
|
|
4
4
|
import { ISplitApi } from './types';
|
|
5
5
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
6
6
|
import { ITelemetryTracker } from '../trackers/types';
|
|
7
|
-
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT } from '../utils/constants';
|
|
7
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MY_SEGMENT, MY_LARGE_SEGMENT } from '../utils/constants';
|
|
8
8
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
9
9
|
|
|
10
10
|
const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
@@ -78,6 +78,11 @@ export function splitApiFactory(
|
|
|
78
78
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MY_SEGMENT));
|
|
79
79
|
},
|
|
80
80
|
|
|
81
|
+
fetchMyLargeSegments(userMatchingKey: string, noCache?: boolean) {
|
|
82
|
+
const url = `${urls.sdk}/myLargeSegments/${encodeURIComponent(userMatchingKey)}`;
|
|
83
|
+
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MY_LARGE_SEGMENT));
|
|
84
|
+
},
|
|
85
|
+
|
|
81
86
|
/**
|
|
82
87
|
* Post events.
|
|
83
88
|
*
|
package/src/services/types.ts
CHANGED
|
@@ -62,6 +62,7 @@ export interface ISplitApi {
|
|
|
62
62
|
fetchSplitChanges: IFetchSplitChanges
|
|
63
63
|
fetchSegmentChanges: IFetchSegmentChanges
|
|
64
64
|
fetchMySegments: IFetchMySegments
|
|
65
|
+
fetchMyLargeSegments: IFetchMySegments
|
|
65
66
|
postEventsBulk: IPostEventsBulk
|
|
66
67
|
postUniqueKeysBulkCs: IPostUniqueKeysBulkCs
|
|
67
68
|
postUniqueKeysBulkSs: IPostUniqueKeysBulkSs
|
|
@@ -22,9 +22,9 @@ export abstract class AbstractSplitsCacheAsync implements ISplitsCacheAsync {
|
|
|
22
22
|
abstract trafficTypeExists(trafficType: string): Promise<boolean>
|
|
23
23
|
abstract clear(): Promise<boolean | void>
|
|
24
24
|
|
|
25
|
-
// @TODO revisit segment-related methods ('
|
|
25
|
+
// @TODO revisit segment-related methods ('usesMatcher', 'getRegisteredSegments', 'registerSegments')
|
|
26
26
|
// noop, just keeping the interface. This is used by standalone client-side API only, and so only implemented by InMemory and InLocalStorage.
|
|
27
|
-
|
|
27
|
+
usesMatcher(): Promise<boolean> {
|
|
28
28
|
return Promise.resolve(true);
|
|
29
29
|
}
|
|
30
30
|
|
|
@@ -43,7 +43,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
43
43
|
|
|
44
44
|
abstract trafficTypeExists(trafficType: string): boolean
|
|
45
45
|
|
|
46
|
-
abstract
|
|
46
|
+
abstract usesMatcher(matcherType: string): boolean
|
|
47
47
|
|
|
48
48
|
abstract clear(): void
|
|
49
49
|
|
|
@@ -85,15 +85,15 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
85
85
|
|
|
86
86
|
/**
|
|
87
87
|
* Given a parsed split, it returns a boolean flagging if its conditions use segments matchers (rules & whitelists).
|
|
88
|
-
* This util is intended to simplify the implementation of `splitsCache::
|
|
88
|
+
* This util is intended to simplify the implementation of `splitsCache::usesMatcher` method
|
|
89
89
|
*/
|
|
90
|
-
export function
|
|
90
|
+
export function usesMatcher(split: ISplit, matcherType: string) {
|
|
91
91
|
const conditions = split.conditions || [];
|
|
92
92
|
for (let i = 0; i < conditions.length; i++) {
|
|
93
93
|
const matchers = conditions[i].matcherGroup.matchers;
|
|
94
94
|
|
|
95
95
|
for (let j = 0; j < matchers.length; j++) {
|
|
96
|
-
if (matchers[j].matcherType ===
|
|
96
|
+
if (matchers[j].matcherType === matcherType) return true;
|
|
97
97
|
}
|
|
98
98
|
}
|
|
99
99
|
|
|
@@ -51,6 +51,9 @@ export class KeyBuilder {
|
|
|
51
51
|
buildSplitsWithSegmentCountKey() {
|
|
52
52
|
return `${this.prefix}.splits.usingSegments`;
|
|
53
53
|
}
|
|
54
|
+
buildSplitsWithLargeSegmentCountKey() {
|
|
55
|
+
return `${this.prefix}.splits.usingLargeSegments`;
|
|
56
|
+
}
|
|
54
57
|
|
|
55
58
|
buildSegmentNameKey(segmentName: string) {
|
|
56
59
|
return `${this.prefix}.segment.${segmentName}`;
|
|
@@ -1,7 +1,13 @@
|
|
|
1
1
|
import { startsWith } from '../utils/lang';
|
|
2
2
|
import { KeyBuilder } from './KeyBuilder';
|
|
3
3
|
|
|
4
|
-
export
|
|
4
|
+
export interface MySegmentsKeyBuilder {
|
|
5
|
+
buildSegmentNameKey(segmentName: string): string;
|
|
6
|
+
extractSegmentName(builtSegmentKeyName: string): string | undefined;
|
|
7
|
+
extractOldSegmentKey(builtSegmentKeyName: string): string | undefined;
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
|
|
5
11
|
|
|
6
12
|
protected readonly regexSplitsCacheKey: RegExp;
|
|
7
13
|
protected readonly matchingKey: string;
|
|
@@ -26,10 +32,6 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
26
32
|
return builtSegmentKeyName.substr(prefix.length);
|
|
27
33
|
}
|
|
28
34
|
|
|
29
|
-
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
30
|
-
buildOldSegmentNameKey(segmentName: string) {
|
|
31
|
-
return `${this.matchingKey}.${this.prefix}.segment.${segmentName}`;
|
|
32
|
-
}
|
|
33
35
|
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
34
36
|
extractOldSegmentKey(builtSegmentKeyName: string) {
|
|
35
37
|
const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
|
|
@@ -46,3 +48,21 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
46
48
|
return this.regexSplitsCacheKey.test(key);
|
|
47
49
|
}
|
|
48
50
|
}
|
|
51
|
+
|
|
52
|
+
export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string): MySegmentsKeyBuilder {
|
|
53
|
+
return {
|
|
54
|
+
buildSegmentNameKey(segmentName: string) {
|
|
55
|
+
return `${prefix}.${matchingKey}.largeSegment.${segmentName}`;
|
|
56
|
+
},
|
|
57
|
+
|
|
58
|
+
extractSegmentName(builtSegmentKeyName: string) {
|
|
59
|
+
const p = `${prefix}.${matchingKey}.largeSegment.`;
|
|
60
|
+
|
|
61
|
+
if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.substr(p.length);
|
|
62
|
+
},
|
|
63
|
+
|
|
64
|
+
extractOldSegmentKey() {
|
|
65
|
+
return undefined;
|
|
66
|
+
}
|
|
67
|
+
};
|
|
68
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
import { ILogger } from '../../logger/types';
|
|
2
2
|
import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
|
|
3
|
-
import {
|
|
3
|
+
import type { MySegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
4
4
|
import { LOG_PREFIX, DEFINED } from './constants';
|
|
5
5
|
|
|
6
6
|
export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
7
7
|
|
|
8
|
-
private readonly keys:
|
|
8
|
+
private readonly keys: MySegmentsKeyBuilder;
|
|
9
9
|
private readonly log: ILogger;
|
|
10
10
|
|
|
11
|
-
constructor(log: ILogger, keys:
|
|
11
|
+
constructor(log: ILogger, keys: MySegmentsKeyBuilder) {
|
|
12
12
|
super();
|
|
13
13
|
this.log = log;
|
|
14
14
|
this.keys = keys;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { ISplit } from '../../dtos/types';
|
|
2
|
-
import { AbstractSplitsCacheSync,
|
|
2
|
+
import { AbstractSplitsCacheSync, usesMatcher } from '../AbstractSplitsCacheSync';
|
|
3
3
|
import { isFiniteNumber, toNumber, isNaNNumber } from '../../utils/lang';
|
|
4
4
|
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
5
5
|
import { ILogger } from '../../logger/types';
|
|
@@ -7,6 +7,7 @@ import { LOG_PREFIX } from './constants';
|
|
|
7
7
|
import { ISet, _Set, setToArray } from '../../utils/lang/sets';
|
|
8
8
|
import { ISettings } from '../../types';
|
|
9
9
|
import { getStorageHash } from '../KeyBuilder';
|
|
10
|
+
import { IN_LARGE_SEGMENT, IN_SEGMENT } from '../../utils/constants';
|
|
10
11
|
|
|
11
12
|
/**
|
|
12
13
|
* ISplitsCacheSync implementation that stores split definitions in browser LocalStorage.
|
|
@@ -50,10 +51,15 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
50
51
|
const ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
51
52
|
this._decrementCount(ttKey);
|
|
52
53
|
|
|
53
|
-
if (
|
|
54
|
+
if (usesMatcher(split, IN_SEGMENT)) {
|
|
54
55
|
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
55
56
|
this._decrementCount(segmentsCountKey);
|
|
56
57
|
}
|
|
58
|
+
|
|
59
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT)) {
|
|
60
|
+
const segmentsCountKey = this.keys.buildSplitsWithLargeSegmentCountKey();
|
|
61
|
+
this._decrementCount(segmentsCountKey);
|
|
62
|
+
}
|
|
57
63
|
}
|
|
58
64
|
} catch (e) {
|
|
59
65
|
this.log.error(LOG_PREFIX + e);
|
|
@@ -67,11 +73,17 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
67
73
|
// @ts-expect-error
|
|
68
74
|
localStorage.setItem(ttKey, toNumber(localStorage.getItem(ttKey)) + 1);
|
|
69
75
|
|
|
70
|
-
if (
|
|
76
|
+
if (usesMatcher(split, IN_SEGMENT)) {
|
|
71
77
|
const segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
72
78
|
// @ts-expect-error
|
|
73
79
|
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
74
80
|
}
|
|
81
|
+
|
|
82
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT)) {
|
|
83
|
+
const segmentsCountKey = this.keys.buildSplitsWithLargeSegmentCountKey();
|
|
84
|
+
// @ts-expect-error
|
|
85
|
+
localStorage.setItem(segmentsCountKey, toNumber(localStorage.getItem(segmentsCountKey)) + 1);
|
|
86
|
+
}
|
|
75
87
|
}
|
|
76
88
|
} catch (e) {
|
|
77
89
|
this.log.error(LOG_PREFIX + e);
|
|
@@ -203,11 +215,14 @@ export class SplitsCacheInLocal extends AbstractSplitsCacheSync {
|
|
|
203
215
|
return isFiniteNumber(ttCount) && ttCount > 0;
|
|
204
216
|
}
|
|
205
217
|
|
|
206
|
-
|
|
218
|
+
usesMatcher(matcherType: string) {
|
|
207
219
|
// If cache hasn't been synchronized with the cloud, assume we need them.
|
|
208
220
|
if (!this.hasSync) return true;
|
|
209
221
|
|
|
210
|
-
const storedCount = localStorage.getItem(
|
|
222
|
+
const storedCount = localStorage.getItem(matcherType === IN_SEGMENT ?
|
|
223
|
+
this.keys.buildSplitsWithSegmentCountKey() :
|
|
224
|
+
this.keys.buildSplitsWithLargeSegmentCountKey()
|
|
225
|
+
);
|
|
211
226
|
const splitsWithSegmentsCount = storedCount === null ? 0 : toNumber(storedCount);
|
|
212
227
|
|
|
213
228
|
if (isFiniteNumber(splitsWithSegmentsCount)) {
|
|
@@ -3,7 +3,7 @@ import { ImpressionCountsCacheInMemory } from '../inMemory/ImpressionCountsCache
|
|
|
3
3
|
import { EventsCacheInMemory } from '../inMemory/EventsCacheInMemory';
|
|
4
4
|
import { IStorageFactoryParams, IStorageSync, IStorageSyncFactory } from '../types';
|
|
5
5
|
import { validatePrefix } from '../KeyBuilder';
|
|
6
|
-
import { KeyBuilderCS } from '../KeyBuilderCS';
|
|
6
|
+
import { KeyBuilderCS, myLargeSegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
7
7
|
import { isLocalStorageAvailable } from '../../utils/env/isLocalStorageAvailable';
|
|
8
8
|
import { SplitsCacheInLocal } from './SplitsCacheInLocal';
|
|
9
9
|
import { MySegmentsCacheInLocal } from './MySegmentsCacheInLocal';
|
|
@@ -38,15 +38,17 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
38
38
|
|
|
39
39
|
const { settings, settings: { log, scheduler: { impressionsQueueSize, eventsQueueSize, }, sync: { impressionsMode, __splitFiltersValidation } } } = params;
|
|
40
40
|
const matchingKey = getMatching(settings.core.key);
|
|
41
|
-
const keys = new KeyBuilderCS(prefix, matchingKey
|
|
41
|
+
const keys = new KeyBuilderCS(prefix, matchingKey);
|
|
42
42
|
const expirationTimestamp = Date.now() - DEFAULT_CACHE_EXPIRATION_IN_MILLIS;
|
|
43
43
|
|
|
44
44
|
const splits = new SplitsCacheInLocal(settings, keys, expirationTimestamp);
|
|
45
45
|
const segments = new MySegmentsCacheInLocal(log, keys);
|
|
46
|
+
const largeSegments = new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey));
|
|
46
47
|
|
|
47
48
|
return {
|
|
48
49
|
splits,
|
|
49
50
|
segments,
|
|
51
|
+
largeSegments,
|
|
50
52
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
51
53
|
impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
|
|
52
54
|
events: new EventsCacheInMemory(eventsQueueSize),
|
|
@@ -56,6 +58,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
56
58
|
destroy() {
|
|
57
59
|
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
58
60
|
this.segments = new MySegmentsCacheInMemory();
|
|
61
|
+
this.largeSegments = new MySegmentsCacheInMemory();
|
|
59
62
|
this.impressions.clear();
|
|
60
63
|
this.impressionCounts && this.impressionCounts.clear();
|
|
61
64
|
this.events.clear();
|
|
@@ -64,11 +67,11 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
64
67
|
|
|
65
68
|
// When using shared instanciation with MEMORY we reuse everything but segments (they are customer per key).
|
|
66
69
|
shared(matchingKey: string) {
|
|
67
|
-
const childKeysBuilder = new KeyBuilderCS(prefix, matchingKey);
|
|
68
70
|
|
|
69
71
|
return {
|
|
70
72
|
splits: this.splits,
|
|
71
|
-
segments: new MySegmentsCacheInLocal(log,
|
|
73
|
+
segments: new MySegmentsCacheInLocal(log, new KeyBuilderCS(prefix, matchingKey)),
|
|
74
|
+
largeSegments: new MySegmentsCacheInLocal(log, myLargeSegmentsKeyBuilder(prefix, matchingKey)),
|
|
72
75
|
impressions: this.impressions,
|
|
73
76
|
impressionCounts: this.impressionCounts,
|
|
74
77
|
events: this.events,
|
|
@@ -77,6 +80,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
77
80
|
destroy() {
|
|
78
81
|
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
79
82
|
this.segments = new MySegmentsCacheInMemory();
|
|
83
|
+
this.largeSegments = new MySegmentsCacheInMemory();
|
|
80
84
|
}
|
|
81
85
|
};
|
|
82
86
|
},
|
|
@@ -18,10 +18,12 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
18
18
|
|
|
19
19
|
const splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
20
20
|
const segments = new MySegmentsCacheInMemory();
|
|
21
|
+
const largeSegments = new MySegmentsCacheInMemory();
|
|
21
22
|
|
|
22
23
|
const storage = {
|
|
23
24
|
splits,
|
|
24
25
|
segments,
|
|
26
|
+
largeSegments,
|
|
25
27
|
impressions: new ImpressionsCacheInMemory(impressionsQueueSize),
|
|
26
28
|
impressionCounts: impressionsMode !== DEBUG ? new ImpressionCountsCacheInMemory() : undefined,
|
|
27
29
|
events: new EventsCacheInMemory(eventsQueueSize),
|
|
@@ -32,6 +34,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
32
34
|
destroy() {
|
|
33
35
|
this.splits.clear();
|
|
34
36
|
this.segments.clear();
|
|
37
|
+
this.largeSegments.clear();
|
|
35
38
|
this.impressions.clear();
|
|
36
39
|
this.impressionCounts && this.impressionCounts.clear();
|
|
37
40
|
this.events.clear();
|
|
@@ -43,6 +46,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
43
46
|
return {
|
|
44
47
|
splits: this.splits,
|
|
45
48
|
segments: new MySegmentsCacheInMemory(),
|
|
49
|
+
largeSegments: new MySegmentsCacheInMemory(),
|
|
46
50
|
impressions: this.impressions,
|
|
47
51
|
impressionCounts: this.impressionCounts,
|
|
48
52
|
events: this.events,
|
|
@@ -52,6 +56,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
52
56
|
destroy() {
|
|
53
57
|
this.splits = new SplitsCacheInMemory(__splitFiltersValidation);
|
|
54
58
|
this.segments.clear();
|
|
59
|
+
this.largeSegments.clear();
|
|
55
60
|
}
|
|
56
61
|
};
|
|
57
62
|
},
|
|
@@ -1,7 +1,8 @@
|
|
|
1
1
|
import { ISplit, ISplitFiltersValidation } from '../../dtos/types';
|
|
2
|
-
import { AbstractSplitsCacheSync,
|
|
2
|
+
import { AbstractSplitsCacheSync, usesMatcher } from '../AbstractSplitsCacheSync';
|
|
3
3
|
import { isFiniteNumber } from '../../utils/lang';
|
|
4
4
|
import { ISet, _Set } from '../../utils/lang/sets';
|
|
5
|
+
import { IN_LARGE_SEGMENT, IN_SEGMENT } from '../../utils/constants';
|
|
5
6
|
|
|
6
7
|
/**
|
|
7
8
|
* Default ISplitsCacheSync implementation that stores split definitions in memory.
|
|
@@ -13,7 +14,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
13
14
|
private splitsCache: Record<string, ISplit> = {};
|
|
14
15
|
private ttCache: Record<string, number> = {};
|
|
15
16
|
private changeNumber: number = -1;
|
|
16
|
-
private
|
|
17
|
+
private segmentsCount: number = 0;
|
|
18
|
+
private largeSegmentsCount: number = 0;
|
|
17
19
|
private flagSetsCache: Record<string, ISet<string>> = {};
|
|
18
20
|
|
|
19
21
|
constructor(splitFiltersValidation?: ISplitFiltersValidation) {
|
|
@@ -25,7 +27,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
25
27
|
this.splitsCache = {};
|
|
26
28
|
this.ttCache = {};
|
|
27
29
|
this.changeNumber = -1;
|
|
28
|
-
this.
|
|
30
|
+
this.segmentsCount = 0;
|
|
31
|
+
this.largeSegmentsCount = 0;
|
|
29
32
|
}
|
|
30
33
|
|
|
31
34
|
addSplit(name: string, split: ISplit): boolean {
|
|
@@ -38,9 +41,9 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
38
41
|
|
|
39
42
|
this.removeFromFlagSets(previousSplit.name, previousSplit.sets);
|
|
40
43
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
// Substract from segments count for the previous version of this Split.
|
|
45
|
+
if (usesMatcher(previousSplit, IN_SEGMENT)) this.segmentsCount--;
|
|
46
|
+
if (usesMatcher(previousSplit, IN_LARGE_SEGMENT)) this.largeSegmentsCount--;
|
|
44
47
|
}
|
|
45
48
|
|
|
46
49
|
if (split) {
|
|
@@ -52,7 +55,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
52
55
|
this.addToFlagSets(split);
|
|
53
56
|
|
|
54
57
|
// Add to segments count for the new version of the Split
|
|
55
|
-
if (
|
|
58
|
+
if (usesMatcher(split, IN_SEGMENT)) this.segmentsCount++;
|
|
59
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT)) this.largeSegmentsCount++;
|
|
56
60
|
|
|
57
61
|
return true;
|
|
58
62
|
} else {
|
|
@@ -72,7 +76,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
72
76
|
this.removeFromFlagSets(split.name, split.sets);
|
|
73
77
|
|
|
74
78
|
// Update the segments count.
|
|
75
|
-
if (
|
|
79
|
+
if (usesMatcher(split, IN_SEGMENT)) this.segmentsCount--;
|
|
80
|
+
if (usesMatcher(split, IN_LARGE_SEGMENT)) this.largeSegmentsCount--;
|
|
76
81
|
|
|
77
82
|
return true;
|
|
78
83
|
} else {
|
|
@@ -101,8 +106,8 @@ export class SplitsCacheInMemory extends AbstractSplitsCacheSync {
|
|
|
101
106
|
return isFiniteNumber(this.ttCache[trafficType]) && this.ttCache[trafficType] > 0;
|
|
102
107
|
}
|
|
103
108
|
|
|
104
|
-
|
|
105
|
-
return this.getChangeNumber() === -1 || this.
|
|
109
|
+
usesMatcher(matcherType: string): boolean {
|
|
110
|
+
return this.getChangeNumber() === -1 || (matcherType === IN_SEGMENT ? this.segmentsCount > 0 : this.largeSegmentsCount > 0);
|
|
106
111
|
}
|
|
107
112
|
|
|
108
113
|
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
|
+
lseC: 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
|
@@ -204,8 +204,8 @@ export interface ISplitsCacheBase {
|
|
|
204
204
|
getSplitNames(): MaybeThenable<string[]>,
|
|
205
205
|
// should never reject or throw an exception. Instead return true by default, asssuming the TT might exist.
|
|
206
206
|
trafficTypeExists(trafficType: string): MaybeThenable<boolean>,
|
|
207
|
-
// only for Client-Side
|
|
208
|
-
|
|
207
|
+
// only for Client-Side. Returns true if the storage is not synchronized yet (getChangeNumber() === 1) or contains a FF using the given matcher
|
|
208
|
+
usesMatcher(matcherType: string): MaybeThenable<boolean>,
|
|
209
209
|
clear(): MaybeThenable<boolean | void>,
|
|
210
210
|
// should never reject or throw an exception. Instead return false by default, to avoid emitting SDK_READY_FROM_CACHE.
|
|
211
211
|
checkCache(): MaybeThenable<boolean>,
|
|
@@ -223,7 +223,7 @@ export interface ISplitsCacheSync extends ISplitsCacheBase {
|
|
|
223
223
|
getAll(): ISplit[],
|
|
224
224
|
getSplitNames(): string[],
|
|
225
225
|
trafficTypeExists(trafficType: string): boolean,
|
|
226
|
-
|
|
226
|
+
usesMatcher(matcherType: string): boolean,
|
|
227
227
|
clear(): void,
|
|
228
228
|
checkCache(): boolean,
|
|
229
229
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): boolean,
|
|
@@ -240,7 +240,7 @@ export interface ISplitsCacheAsync extends ISplitsCacheBase {
|
|
|
240
240
|
getAll(): Promise<ISplit[]>,
|
|
241
241
|
getSplitNames(): Promise<string[]>,
|
|
242
242
|
trafficTypeExists(trafficType: string): Promise<boolean>,
|
|
243
|
-
|
|
243
|
+
usesMatcher(matcherType: string): Promise<boolean>,
|
|
244
244
|
clear(): Promise<boolean | void>,
|
|
245
245
|
checkCache(): Promise<boolean>,
|
|
246
246
|
killLocally(name: string, defaultTreatment: string, changeNumber: number): Promise<boolean>,
|
|
@@ -477,7 +477,9 @@ export interface IStorageSync extends IStorageBase<
|
|
|
477
477
|
IEventsCacheSync,
|
|
478
478
|
ITelemetryCacheSync,
|
|
479
479
|
IUniqueKeysCacheSync
|
|
480
|
-
> {
|
|
480
|
+
> {
|
|
481
|
+
largeSegments?: ISegmentsCacheSync,
|
|
482
|
+
}
|
|
481
483
|
|
|
482
484
|
export interface IStorageAsync extends IStorageBase<
|
|
483
485
|
ISplitsCacheAsync,
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { IFetchMySegments, IResponse } from '../../../services/types';
|
|
2
|
-
import {
|
|
2
|
+
import { IMySegmentsResponse, IMyLargeSegmentsResponse } from '../../../dtos/types';
|
|
3
3
|
import { IMySegmentsFetcher } from './types';
|
|
4
4
|
|
|
5
5
|
/**
|
|
@@ -21,7 +21,11 @@ export function mySegmentsFetcherFactory(fetchMySegments: IFetchMySegments): IMy
|
|
|
21
21
|
// Extract segment names
|
|
22
22
|
return mySegmentsPromise
|
|
23
23
|
.then(resp => resp.json())
|
|
24
|
-
.then(json
|
|
24
|
+
.then((json: IMySegmentsResponse | IMyLargeSegmentsResponse) => {
|
|
25
|
+
return (json as IMySegmentsResponse).mySegments ?
|
|
26
|
+
(json as IMySegmentsResponse).mySegments.map((segment) => segment.name) :
|
|
27
|
+
(json as IMyLargeSegmentsResponse).myLargeSegments;
|
|
28
|
+
});
|
|
25
29
|
};
|
|
26
30
|
|
|
27
31
|
}
|