@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
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
|
-
import { IEventEmitter } from '../types';
|
|
2
|
+
import { IEventEmitter, ISettings } from '../types';
|
|
3
3
|
import { SDK_SPLITS_ARRIVED, SDK_SPLITS_CACHE_LOADED, SDK_SEGMENTS_ARRIVED, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE, SDK_READY } from './constants';
|
|
4
4
|
import { IReadinessEventEmitter, IReadinessManager, ISegmentsEventEmitter, ISplitsEventEmitter } from './types';
|
|
5
5
|
|
|
@@ -10,7 +10,7 @@ function splitsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISpli
|
|
|
10
10
|
});
|
|
11
11
|
|
|
12
12
|
// `isSplitKill` condition avoids an edge-case of wrongly emitting SDK_READY if:
|
|
13
|
-
// - `/
|
|
13
|
+
// - `/memberships` fetch and SPLIT_KILL occurs before `/splitChanges` fetch, and
|
|
14
14
|
// - storage has cached splits (for which case `splitsStorage.killLocally` can return true)
|
|
15
15
|
splitsEventEmitter.on(SDK_SPLITS_ARRIVED, (isSplitKill: boolean) => { if (!isSplitKill) splitsEventEmitter.splitsArrived = true; });
|
|
16
16
|
splitsEventEmitter.once(SDK_SPLITS_CACHE_LOADED, () => { splitsEventEmitter.splitsCacheLoaded = true; });
|
|
@@ -33,9 +33,11 @@ function segmentsEventEmitterFactory(EventEmitter: new () => IEventEmitter): ISe
|
|
|
33
33
|
*/
|
|
34
34
|
export function readinessManagerFactory(
|
|
35
35
|
EventEmitter: new () => IEventEmitter,
|
|
36
|
-
|
|
36
|
+
settings: ISettings,
|
|
37
37
|
splits: ISplitsEventEmitter = splitsEventEmitterFactory(EventEmitter)): IReadinessManager {
|
|
38
38
|
|
|
39
|
+
const readyTimeout = settings.startup.readyTimeout;
|
|
40
|
+
|
|
39
41
|
const segments: ISegmentsEventEmitter = segmentsEventEmitterFactory(EventEmitter);
|
|
40
42
|
const gate: IReadinessEventEmitter = new EventEmitter();
|
|
41
43
|
|
|
@@ -118,9 +120,9 @@ export function readinessManagerFactory(
|
|
|
118
120
|
segments,
|
|
119
121
|
gate,
|
|
120
122
|
|
|
121
|
-
shared(
|
|
123
|
+
shared() {
|
|
122
124
|
refCount++;
|
|
123
|
-
return readinessManagerFactory(EventEmitter,
|
|
125
|
+
return readinessManagerFactory(EventEmitter, settings, splits);
|
|
124
126
|
},
|
|
125
127
|
|
|
126
128
|
// @TODO review/remove next methods when non-recoverable errors are reworked
|
|
@@ -2,9 +2,8 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
2
2
|
import { promiseWrapper } from '../utils/promise/wrapper';
|
|
3
3
|
import { readinessManagerFactory } from './readinessManager';
|
|
4
4
|
import { ISdkReadinessManager } from './types';
|
|
5
|
-
import { IEventEmitter } from '../types';
|
|
5
|
+
import { IEventEmitter, ISettings } from '../types';
|
|
6
6
|
import { SDK_READY, SDK_READY_TIMED_OUT, SDK_READY_FROM_CACHE, SDK_UPDATE } from './constants';
|
|
7
|
-
import { ILogger } from '../logger/types';
|
|
8
7
|
import { ERROR_CLIENT_LISTENER, CLIENT_READY_FROM_CACHE, CLIENT_READY, CLIENT_NO_LISTENER } from '../logger/constants';
|
|
9
8
|
|
|
10
9
|
const NEW_LISTENER_EVENT = 'newListener';
|
|
@@ -18,10 +17,11 @@ const REMOVE_LISTENER_EVENT = 'removeListener';
|
|
|
18
17
|
* @param readinessManager optional readinessManager to use. only used internally for `shared` method
|
|
19
18
|
*/
|
|
20
19
|
export function sdkReadinessManagerFactory(
|
|
21
|
-
log: ILogger,
|
|
22
20
|
EventEmitter: new () => IEventEmitter,
|
|
23
|
-
|
|
24
|
-
readinessManager = readinessManagerFactory(EventEmitter,
|
|
21
|
+
settings: ISettings,
|
|
22
|
+
readinessManager = readinessManagerFactory(EventEmitter, settings)): ISdkReadinessManager {
|
|
23
|
+
|
|
24
|
+
const log = settings.log;
|
|
25
25
|
|
|
26
26
|
/** Ready callback warning */
|
|
27
27
|
let internalReadyCbCount = 0;
|
|
@@ -72,8 +72,8 @@ export function sdkReadinessManagerFactory(
|
|
|
72
72
|
return {
|
|
73
73
|
readinessManager,
|
|
74
74
|
|
|
75
|
-
shared(
|
|
76
|
-
return sdkReadinessManagerFactory(
|
|
75
|
+
shared() {
|
|
76
|
+
return sdkReadinessManagerFactory(EventEmitter, settings, readinessManager.shared());
|
|
77
77
|
},
|
|
78
78
|
|
|
79
79
|
incInternalReadyCbCount() {
|
package/src/readiness/types.ts
CHANGED
|
@@ -61,7 +61,7 @@ export interface IReadinessManager {
|
|
|
61
61
|
destroy(): void,
|
|
62
62
|
|
|
63
63
|
/** for client-side */
|
|
64
|
-
shared(
|
|
64
|
+
shared(): IReadinessManager,
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
/** SDK readiness manager */
|
|
@@ -77,5 +77,5 @@ export interface ISdkReadinessManager {
|
|
|
77
77
|
incInternalReadyCbCount(): void
|
|
78
78
|
|
|
79
79
|
/** for client-side */
|
|
80
|
-
shared(
|
|
80
|
+
shared(): ISdkReadinessManager
|
|
81
81
|
}
|
|
@@ -19,7 +19,7 @@ function buildInstanceId(key: SplitIO.SplitKey) {
|
|
|
19
19
|
* Therefore, clients don't have a bound TT for the track method.
|
|
20
20
|
*/
|
|
21
21
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey) => SplitIO.ICsClient {
|
|
22
|
-
const { storage, syncManager, sdkReadinessManager, settings: { core: { key },
|
|
22
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key }, log } } = params;
|
|
23
23
|
|
|
24
24
|
const mainClientInstance = clientCSDecorator(
|
|
25
25
|
log,
|
|
@@ -51,7 +51,7 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
51
51
|
if (!clientInstances[instanceId]) {
|
|
52
52
|
const matchingKey = getMatching(validKey);
|
|
53
53
|
|
|
54
|
-
const sharedSdkReadiness = sdkReadinessManager.shared(
|
|
54
|
+
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
55
55
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
56
56
|
if (err) {
|
|
57
57
|
sharedSdkReadiness.readinessManager.timeout();
|
|
@@ -21,7 +21,7 @@ function buildInstanceId(key: SplitIO.SplitKey, trafficType?: string) {
|
|
|
21
21
|
* (default client) or the client method (shared clients).
|
|
22
22
|
*/
|
|
23
23
|
export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: SplitIO.SplitKey, trafficType?: string) => SplitIO.ICsClient {
|
|
24
|
-
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType },
|
|
24
|
+
const { storage, syncManager, sdkReadinessManager, settings: { core: { key, trafficType }, log } } = params;
|
|
25
25
|
|
|
26
26
|
const mainClientInstance = clientCSDecorator(
|
|
27
27
|
log,
|
|
@@ -61,7 +61,7 @@ export function sdkClientMethodCSFactory(params: ISdkFactoryContext): (key?: Spl
|
|
|
61
61
|
if (!clientInstances[instanceId]) {
|
|
62
62
|
const matchingKey = getMatching(validKey);
|
|
63
63
|
|
|
64
|
-
const sharedSdkReadiness = sdkReadinessManager.shared(
|
|
64
|
+
const sharedSdkReadiness = sdkReadinessManager.shared();
|
|
65
65
|
const sharedStorage = storage.shared && storage.shared(matchingKey, (err) => {
|
|
66
66
|
if (err) {
|
|
67
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,
|
|
7
|
+
import { SPLITS, IMPRESSIONS, IMPRESSIONS_COUNT, EVENTS, TELEMETRY, TOKEN, SEGMENT, MEMBERSHIPS } from '../utils/constants';
|
|
8
8
|
import { ERROR_TOO_MANY_SETS } from '../logger/constants';
|
|
9
9
|
|
|
10
10
|
const noCacheHeaderOptions = { headers: { 'Cache-Control': 'no-cache' } };
|
|
@@ -22,7 +22,7 @@ function userKeyToQueryParam(userKey: string) {
|
|
|
22
22
|
*/
|
|
23
23
|
export function splitApiFactory(
|
|
24
24
|
settings: ISettings,
|
|
25
|
-
platform: IPlatform,
|
|
25
|
+
platform: Pick<IPlatform, 'getOptions' | 'getFetch'>,
|
|
26
26
|
telemetryTracker: ITelemetryTracker
|
|
27
27
|
): ISplitApi {
|
|
28
28
|
|
|
@@ -67,15 +67,15 @@ export function splitApiFactory(
|
|
|
67
67
|
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(SEGMENT));
|
|
68
68
|
},
|
|
69
69
|
|
|
70
|
-
|
|
70
|
+
fetchMemberships(userMatchingKey: string, noCache?: boolean, till?: number) {
|
|
71
71
|
/**
|
|
72
72
|
* URI encoding of user keys in order to:
|
|
73
|
-
* - avoid 400 responses (due to URI malformed). E.g.: '/api/
|
|
74
|
-
* - avoid 404 responses. E.g.: '/api/
|
|
73
|
+
* - avoid 400 responses (due to URI malformed). E.g.: '/api/memberships/%'
|
|
74
|
+
* - avoid 404 responses. E.g.: '/api/memberships/foo/bar'
|
|
75
75
|
* - match user keys with special characters. E.g.: 'foo%bar', 'foo/bar'
|
|
76
76
|
*/
|
|
77
|
-
const url = `${urls.sdk}/
|
|
78
|
-
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(
|
|
77
|
+
const url = `${urls.sdk}/memberships/${encodeURIComponent(userMatchingKey)}${till ? '?till=' + till : ''}`;
|
|
78
|
+
return splitHttpClient(url, noCache ? noCacheHeaderOptions : undefined, telemetryTracker.trackHttp(MEMBERSHIPS));
|
|
79
79
|
},
|
|
80
80
|
|
|
81
81
|
/**
|
|
@@ -13,7 +13,7 @@ const messageNoFetch = 'Global fetch API is not available.';
|
|
|
13
13
|
* @param settings SDK settings, used to access authorizationKey, logger instance and metadata (SDK version, ip and hostname) to set additional headers
|
|
14
14
|
* @param platform object containing environment-specific dependencies
|
|
15
15
|
*/
|
|
16
|
-
export function splitHttpClientFactory(settings: ISettings, { getOptions, getFetch }: IPlatform): ISplitHttpClient {
|
|
16
|
+
export function splitHttpClientFactory(settings: ISettings, { getOptions, getFetch }: Pick<IPlatform, 'getOptions' | 'getFetch'>): ISplitHttpClient {
|
|
17
17
|
|
|
18
18
|
const { log, core: { authorizationKey }, version, runtime: { ip, hostname } } = settings;
|
|
19
19
|
const options = getOptions && getOptions(settings);
|
package/src/services/types.ts
CHANGED
|
@@ -39,7 +39,7 @@ export type IFetchSplitChanges = (since: number, noCache?: boolean, till?: numbe
|
|
|
39
39
|
|
|
40
40
|
export type IFetchSegmentChanges = (since: number, segmentName: string, noCache?: boolean, till?: number) => Promise<IResponse>
|
|
41
41
|
|
|
42
|
-
export type
|
|
42
|
+
export type IFetchMemberships = (userMatchingKey: string, noCache?: boolean, till?: number) => Promise<IResponse>
|
|
43
43
|
|
|
44
44
|
export type IPostEventsBulk = (body: string, headers?: Record<string, string>) => Promise<IResponse>
|
|
45
45
|
|
|
@@ -61,7 +61,7 @@ export interface ISplitApi {
|
|
|
61
61
|
fetchAuth: IFetchAuth
|
|
62
62
|
fetchSplitChanges: IFetchSplitChanges
|
|
63
63
|
fetchSegmentChanges: IFetchSegmentChanges
|
|
64
|
-
|
|
64
|
+
fetchMemberships: IFetchMemberships
|
|
65
65
|
postEventsBulk: IPostEventsBulk
|
|
66
66
|
postUniqueKeysBulkCs: IPostUniqueKeysBulkCs
|
|
67
67
|
postUniqueKeysBulkSs: IPostUniqueKeysBulkSs
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
|
2
2
|
/* eslint-disable no-unused-vars */
|
|
3
|
+
import { IMySegmentsResponse } from '../dtos/types';
|
|
4
|
+
import { MySegmentsData } from '../sync/polling/types';
|
|
3
5
|
import { ISegmentsCacheSync } from './types';
|
|
4
6
|
|
|
5
7
|
/**
|
|
@@ -28,7 +30,9 @@ export abstract class AbstractSegmentsCacheSync implements ISegmentsCacheSync {
|
|
|
28
30
|
/**
|
|
29
31
|
* clear the cache.
|
|
30
32
|
*/
|
|
31
|
-
|
|
33
|
+
clear() {
|
|
34
|
+
this.resetSegments({});
|
|
35
|
+
}
|
|
32
36
|
|
|
33
37
|
/**
|
|
34
38
|
* 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.
|
|
@@ -49,20 +53,57 @@ export abstract class AbstractSegmentsCacheSync implements ISegmentsCacheSync {
|
|
|
49
53
|
abstract getKeysCount(): number
|
|
50
54
|
|
|
51
55
|
/**
|
|
52
|
-
* For server-side synchronizer:
|
|
53
|
-
* For client-side synchronizer:
|
|
54
|
-
*/
|
|
55
|
-
setChangeNumber(name: string, changeNumber: number): boolean { return true; }
|
|
56
|
-
|
|
57
|
-
/**
|
|
58
|
-
* For server-side synchronizer: get the change number of `name` segment.
|
|
59
|
-
* For client-side synchronizer: the method is not used.
|
|
56
|
+
* For server-side synchronizer: change number of `name` segment.
|
|
57
|
+
* For client-side synchronizer: change number of mySegments.
|
|
60
58
|
*/
|
|
61
|
-
|
|
59
|
+
abstract setChangeNumber(name?: string, changeNumber?: number): boolean | void
|
|
60
|
+
abstract getChangeNumber(name: string): number
|
|
62
61
|
|
|
63
62
|
/**
|
|
64
63
|
* For server-side synchronizer: the method is not used.
|
|
65
|
-
* For client-side synchronizer:
|
|
64
|
+
* For client-side synchronizer: it resets or updates the cache.
|
|
66
65
|
*/
|
|
67
|
-
resetSegments(
|
|
66
|
+
resetSegments(segmentsData: MySegmentsData | IMySegmentsResponse): boolean {
|
|
67
|
+
this.setChangeNumber(undefined, segmentsData.cn);
|
|
68
|
+
|
|
69
|
+
const { added, removed } = segmentsData as MySegmentsData;
|
|
70
|
+
|
|
71
|
+
if (added && removed) {
|
|
72
|
+
let isDiff = false;
|
|
73
|
+
|
|
74
|
+
added.forEach(segment => {
|
|
75
|
+
isDiff = this.addToSegment(segment) || isDiff;
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
removed.forEach(segment => {
|
|
79
|
+
isDiff = this.removeFromSegment(segment) || isDiff;
|
|
80
|
+
});
|
|
81
|
+
|
|
82
|
+
return isDiff;
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
const names = ((segmentsData as IMySegmentsResponse).k || []).map(s => s.n).sort();
|
|
86
|
+
const storedSegmentKeys = this.getRegisteredSegments().sort();
|
|
87
|
+
|
|
88
|
+
// Extreme fast => everything is empty
|
|
89
|
+
if (!names.length && !storedSegmentKeys.length) return false;
|
|
90
|
+
|
|
91
|
+
let index = 0;
|
|
92
|
+
|
|
93
|
+
while (index < names.length && index < storedSegmentKeys.length && names[index] === storedSegmentKeys[index]) index++;
|
|
94
|
+
|
|
95
|
+
// Quick path => no changes
|
|
96
|
+
if (index === names.length && index === storedSegmentKeys.length) return false;
|
|
97
|
+
|
|
98
|
+
// Slowest path => add and/or remove segments
|
|
99
|
+
for (let removeIndex = index; removeIndex < storedSegmentKeys.length; removeIndex++) {
|
|
100
|
+
this.removeFromSegment(storedSegmentKeys[removeIndex]);
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
for (let addIndex = index; addIndex < names.length; addIndex++) {
|
|
104
|
+
this.addToSegment(names[addIndex]);
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
return true;
|
|
108
|
+
}
|
|
68
109
|
}
|
|
@@ -2,7 +2,7 @@ import { ISplitsCacheSync } from './types';
|
|
|
2
2
|
import { ISplit } from '../dtos/types';
|
|
3
3
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
4
4
|
import { ISet } from '../utils/lang/sets';
|
|
5
|
-
import { IN_SEGMENT } from '../utils/constants';
|
|
5
|
+
import { IN_SEGMENT, IN_LARGE_SEGMENT } from '../utils/constants';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
8
|
* This class provides a skeletal implementation of the ISplitsCacheSync interface
|
|
@@ -32,7 +32,7 @@ export abstract class AbstractSplitsCacheSync implements ISplitsCacheSync {
|
|
|
32
32
|
return splits;
|
|
33
33
|
}
|
|
34
34
|
|
|
35
|
-
abstract setChangeNumber(changeNumber: number): boolean
|
|
35
|
+
abstract setChangeNumber(changeNumber: number): boolean | void
|
|
36
36
|
|
|
37
37
|
abstract getChangeNumber(): number
|
|
38
38
|
|
|
@@ -94,7 +94,8 @@ export function usesSegments(split: ISplit) {
|
|
|
94
94
|
const matchers = conditions[i].matcherGroup.matchers;
|
|
95
95
|
|
|
96
96
|
for (let j = 0; j < matchers.length; j++) {
|
|
97
|
-
|
|
97
|
+
const matcher = matchers[j].matcherType;
|
|
98
|
+
if (matcher === IN_SEGMENT || matcher === IN_LARGE_SEGMENT) return true;
|
|
98
99
|
}
|
|
99
100
|
}
|
|
100
101
|
|
|
@@ -1,7 +1,14 @@
|
|
|
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
|
+
buildTillKey(): string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export class KeyBuilderCS extends KeyBuilder implements MySegmentsKeyBuilder {
|
|
5
12
|
|
|
6
13
|
protected readonly regexSplitsCacheKey: RegExp;
|
|
7
14
|
protected readonly matchingKey: string;
|
|
@@ -26,10 +33,6 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
26
33
|
return builtSegmentKeyName.substr(prefix.length);
|
|
27
34
|
}
|
|
28
35
|
|
|
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
36
|
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
34
37
|
extractOldSegmentKey(builtSegmentKeyName: string) {
|
|
35
38
|
const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
|
|
@@ -45,4 +48,30 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
45
48
|
isSplitsCacheKey(key: string) {
|
|
46
49
|
return this.regexSplitsCacheKey.test(key);
|
|
47
50
|
}
|
|
51
|
+
|
|
52
|
+
buildTillKey() {
|
|
53
|
+
return `${this.prefix}.${this.matchingKey}.segments.till`;
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
export function myLargeSegmentsKeyBuilder(prefix: string, matchingKey: string): MySegmentsKeyBuilder {
|
|
58
|
+
return {
|
|
59
|
+
buildSegmentNameKey(segmentName: string) {
|
|
60
|
+
return `${prefix}.${matchingKey}.largeSegment.${segmentName}`;
|
|
61
|
+
},
|
|
62
|
+
|
|
63
|
+
extractSegmentName(builtSegmentKeyName: string) {
|
|
64
|
+
const p = `${prefix}.${matchingKey}.largeSegment.`;
|
|
65
|
+
|
|
66
|
+
if (startsWith(builtSegmentKeyName, p)) return builtSegmentKeyName.substr(p.length);
|
|
67
|
+
},
|
|
68
|
+
|
|
69
|
+
extractOldSegmentKey() {
|
|
70
|
+
return undefined;
|
|
71
|
+
},
|
|
72
|
+
|
|
73
|
+
buildTillKey() {
|
|
74
|
+
return `${prefix}.${matchingKey}.largeSegments.till`;
|
|
75
|
+
}
|
|
76
|
+
};
|
|
48
77
|
}
|
|
@@ -50,6 +50,6 @@ export function dataLoaderFactory(preloadedData: SplitIO.PreloadedData): DataLoa
|
|
|
50
50
|
return Array.isArray(userIds) && userIds.indexOf(userId) > -1;
|
|
51
51
|
});
|
|
52
52
|
}
|
|
53
|
-
storage.segments.resetSegments(mySegmentsData);
|
|
53
|
+
storage.segments.resetSegments({ k: mySegmentsData.map(s => ({ n: s })) });
|
|
54
54
|
};
|
|
55
55
|
}
|
|
@@ -1,36 +1,26 @@
|
|
|
1
1
|
import { ILogger } from '../../logger/types';
|
|
2
|
+
import { isNaNNumber } from '../../utils/lang';
|
|
2
3
|
import { AbstractSegmentsCacheSync } from '../AbstractSegmentsCacheSync';
|
|
3
|
-
import {
|
|
4
|
+
import type { MySegmentsKeyBuilder } from '../KeyBuilderCS';
|
|
4
5
|
import { LOG_PREFIX, DEFINED } from './constants';
|
|
5
6
|
|
|
6
7
|
export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
7
8
|
|
|
8
|
-
private readonly keys:
|
|
9
|
+
private readonly keys: MySegmentsKeyBuilder;
|
|
9
10
|
private readonly log: ILogger;
|
|
10
11
|
|
|
11
|
-
constructor(log: ILogger, keys:
|
|
12
|
+
constructor(log: ILogger, keys: MySegmentsKeyBuilder) {
|
|
12
13
|
super();
|
|
13
14
|
this.log = log;
|
|
14
15
|
this.keys = keys;
|
|
15
16
|
// There is not need to flush segments cache like splits cache, since resetSegments receives the up-to-date list of active segments
|
|
16
17
|
}
|
|
17
18
|
|
|
18
|
-
/**
|
|
19
|
-
* Removes list of segments from localStorage
|
|
20
|
-
* @NOTE this method is not being used at the moment.
|
|
21
|
-
*/
|
|
22
|
-
clear() {
|
|
23
|
-
this.log.info(LOG_PREFIX + 'Flushing MySegments data from localStorage');
|
|
24
|
-
|
|
25
|
-
// We cannot simply call `localStorage.clear()` since that implies removing user items from the storage
|
|
26
|
-
// We could optimize next sentence, since it implies iterating over all localStorage items
|
|
27
|
-
this.resetSegments([]);
|
|
28
|
-
}
|
|
29
|
-
|
|
30
19
|
addToSegment(name: string): boolean {
|
|
31
20
|
const segmentKey = this.keys.buildSegmentNameKey(name);
|
|
32
21
|
|
|
33
22
|
try {
|
|
23
|
+
if (localStorage.getItem(segmentKey) === DEFINED) return false;
|
|
34
24
|
localStorage.setItem(segmentKey, DEFINED);
|
|
35
25
|
return true;
|
|
36
26
|
} catch (e) {
|
|
@@ -43,6 +33,7 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
|
43
33
|
const segmentKey = this.keys.buildSegmentNameKey(name);
|
|
44
34
|
|
|
45
35
|
try {
|
|
36
|
+
if (localStorage.getItem(segmentKey) !== DEFINED) return false;
|
|
46
37
|
localStorage.removeItem(segmentKey);
|
|
47
38
|
return true;
|
|
48
39
|
} catch (e) {
|
|
@@ -55,31 +46,22 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
|
55
46
|
return localStorage.getItem(this.keys.buildSegmentNameKey(name)) === DEFINED;
|
|
56
47
|
}
|
|
57
48
|
|
|
58
|
-
|
|
59
|
-
* Reset (update) the cached list of segments with the given list, removing and adding segments if necessary.
|
|
60
|
-
*
|
|
61
|
-
* @param {string[]} segmentNames list of segment names
|
|
62
|
-
* @returns boolean indicating if the cache was updated (i.e., given list was different from the cached one)
|
|
63
|
-
*/
|
|
64
|
-
resetSegments(names: string[]): boolean {
|
|
65
|
-
let isDiff = false;
|
|
66
|
-
let index;
|
|
67
|
-
|
|
49
|
+
getRegisteredSegments(): string[] {
|
|
68
50
|
// Scan current values from localStorage
|
|
69
|
-
|
|
51
|
+
return Object.keys(localStorage).reduce((accum, key) => {
|
|
70
52
|
let segmentName = this.keys.extractSegmentName(key);
|
|
71
53
|
|
|
72
54
|
if (segmentName) {
|
|
73
55
|
accum.push(segmentName);
|
|
74
56
|
} else {
|
|
75
|
-
// @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block
|
|
57
|
+
// @TODO @BREAKING: This is only to clean up "old" keys. Remove this whole else code block
|
|
76
58
|
segmentName = this.keys.extractOldSegmentKey(key);
|
|
77
59
|
|
|
78
60
|
if (segmentName) { // this was an old segment key, let's clean up.
|
|
79
61
|
const newSegmentKey = this.keys.buildSegmentNameKey(segmentName);
|
|
80
62
|
try {
|
|
81
63
|
// If the new format key is not there, create it.
|
|
82
|
-
if (!localStorage.getItem(newSegmentKey)
|
|
64
|
+
if (!localStorage.getItem(newSegmentKey)) {
|
|
83
65
|
localStorage.setItem(newSegmentKey, DEFINED);
|
|
84
66
|
// we are migrating a segment, let's track it.
|
|
85
67
|
accum.push(segmentName);
|
|
@@ -93,44 +75,32 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
|
93
75
|
|
|
94
76
|
return accum;
|
|
95
77
|
}, [] as string[]);
|
|
78
|
+
}
|
|
96
79
|
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
80
|
+
getKeysCount() {
|
|
81
|
+
return 1;
|
|
82
|
+
}
|
|
100
83
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
84
|
+
setChangeNumber(name?: string, changeNumber?: number) {
|
|
85
|
+
try {
|
|
86
|
+
if (changeNumber) localStorage.setItem(this.keys.buildTillKey(), changeNumber + '');
|
|
87
|
+
else localStorage.removeItem(this.keys.buildTillKey());
|
|
88
|
+
} catch (e) {
|
|
89
|
+
this.log.error(e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
104
92
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
// Slowest path => we need to find at least 1 difference because
|
|
109
|
-
for (index = 0; index < names.length && storedSegmentNames.indexOf(names[index]) !== -1; index++) {
|
|
110
|
-
// TODO: why empty statement?
|
|
111
|
-
}
|
|
93
|
+
getChangeNumber() {
|
|
94
|
+
const n = -1;
|
|
95
|
+
let value: string | number | null = localStorage.getItem(this.keys.buildTillKey());
|
|
112
96
|
|
|
113
|
-
|
|
114
|
-
|
|
97
|
+
if (value !== null) {
|
|
98
|
+
value = parseInt(value, 10);
|
|
115
99
|
|
|
116
|
-
|
|
117
|
-
names.forEach(name => this.addToSegment(name));
|
|
118
|
-
}
|
|
100
|
+
return isNaNNumber(value) ? n : value;
|
|
119
101
|
}
|
|
120
102
|
|
|
121
|
-
return
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
getRegisteredSegments(): string[] {
|
|
125
|
-
return Object.keys(localStorage).reduce<string[]>((accum, key) => {
|
|
126
|
-
const segmentName = this.keys.extractSegmentName(key);
|
|
127
|
-
if (segmentName) accum.push(segmentName);
|
|
128
|
-
return accum;
|
|
129
|
-
}, []);
|
|
130
|
-
}
|
|
131
|
-
|
|
132
|
-
getKeysCount() {
|
|
133
|
-
return 1;
|
|
103
|
+
return n;
|
|
134
104
|
}
|
|
135
105
|
|
|
136
106
|
}
|
|
@@ -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
|
},
|