@splitsoftware/splitio-commons 1.2.1-rc.2 → 1.2.1-rc.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +4 -2
- package/cjs/integrations/ga/SplitToGoogleAnalytics.js +4 -2
- package/cjs/listeners/browser.js +14 -10
- package/cjs/logger/constants.js +6 -4
- package/cjs/logger/messages/error.js +3 -2
- package/cjs/logger/messages/info.js +3 -2
- package/cjs/sdkClient/client.js +10 -4
- package/cjs/sdkFactory/index.js +6 -4
- package/cjs/sdkFactory/userConsentProps.js +34 -0
- package/cjs/storages/KeyBuilderCS.js +11 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +23 -3
- package/cjs/storages/inLocalStorage/index.js +1 -1
- package/cjs/storages/inMemory/ImpressionsCacheInMemory.js +15 -1
- package/cjs/storages/inMemory/InMemoryStorage.js +1 -1
- package/cjs/storages/inMemory/InMemoryStorageCS.js +1 -1
- package/cjs/storages/pluggable/index.js +2 -2
- package/cjs/sync/streaming/pushManager.js +9 -2
- package/cjs/sync/submitters/eventsSyncTask.js +9 -4
- package/cjs/sync/submitters/impressionsSyncTask.js +13 -1
- package/cjs/sync/syncManagerOnline.js +11 -7
- package/cjs/utils/consent.js +10 -0
- package/cjs/utils/constants/index.js +5 -1
- package/cjs/utils/settingsValidation/consent.js +16 -0
- package/cjs/utils/settingsValidation/impressionsMode.js +6 -6
- package/cjs/utils/settingsValidation/index.js +6 -1
- package/cjs/utils/settingsValidation/{runtime/browser.js → runtime.js} +1 -0
- package/esm/integrations/ga/GoogleAnalyticsToSplit.js +4 -2
- package/esm/integrations/ga/SplitToGoogleAnalytics.js +4 -2
- package/esm/listeners/browser.js +14 -10
- package/esm/logger/constants.js +4 -2
- package/esm/logger/messages/error.js +3 -2
- package/esm/logger/messages/info.js +3 -2
- package/esm/sdkClient/client.js +11 -5
- package/esm/sdkFactory/index.js +6 -4
- package/esm/sdkFactory/userConsentProps.js +30 -0
- package/esm/storages/KeyBuilderCS.js +11 -1
- package/esm/storages/inLocalStorage/MySegmentsCacheInLocal.js +23 -3
- package/esm/storages/inLocalStorage/index.js +1 -1
- package/esm/storages/inMemory/ImpressionsCacheInMemory.js +15 -1
- package/esm/storages/inMemory/InMemoryStorage.js +1 -1
- package/esm/storages/inMemory/InMemoryStorageCS.js +1 -1
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/sync/streaming/pushManager.js +9 -2
- package/esm/sync/submitters/eventsSyncTask.js +10 -5
- package/esm/sync/submitters/impressionsSyncTask.js +13 -1
- package/esm/sync/syncManagerOnline.js +11 -7
- package/esm/utils/consent.js +6 -0
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/settingsValidation/consent.js +12 -0
- package/esm/utils/settingsValidation/impressionsMode.js +7 -7
- package/esm/utils/settingsValidation/index.js +6 -1
- package/esm/utils/settingsValidation/{runtime/browser.js → runtime.js} +1 -0
- package/package.json +1 -2
- package/src/integrations/ga/GoogleAnalyticsToSplit.ts +7 -4
- package/src/integrations/ga/SplitToGoogleAnalytics.ts +7 -4
- package/src/integrations/types.ts +5 -0
- package/src/listeners/browser.ts +13 -9
- package/src/logger/constants.ts +4 -2
- package/src/logger/messages/error.ts +3 -2
- package/src/logger/messages/info.ts +3 -2
- package/src/logger/types.ts +4 -4
- package/src/sdkClient/client.ts +7 -5
- package/src/sdkFactory/index.ts +6 -4
- package/src/sdkFactory/types.ts +2 -0
- package/src/sdkFactory/userConsentProps.ts +37 -0
- package/src/storages/KeyBuilderCS.ts +13 -1
- package/src/storages/inLocalStorage/MySegmentsCacheInLocal.ts +23 -3
- package/src/storages/inLocalStorage/index.ts +1 -1
- package/src/storages/inMemory/ImpressionsCacheInMemory.ts +22 -1
- package/src/storages/inMemory/InMemoryStorage.ts +1 -1
- package/src/storages/inMemory/InMemoryStorageCS.ts +1 -1
- package/src/storages/pluggable/index.ts +2 -2
- package/src/storages/types.ts +6 -2
- package/src/sync/streaming/pushManager.ts +11 -2
- package/src/sync/submitters/eventsSyncTask.ts +11 -5
- package/src/sync/submitters/impressionsSyncTask.ts +16 -1
- package/src/sync/syncManagerOnline.ts +13 -7
- package/src/sync/types.ts +4 -1
- package/src/types.ts +21 -0
- package/src/utils/consent.ts +8 -0
- package/src/utils/constants/index.ts +5 -0
- package/src/utils/settingsValidation/consent.ts +14 -0
- package/src/utils/settingsValidation/impressionsMode.ts +7 -8
- package/src/utils/settingsValidation/index.ts +7 -1
- package/src/utils/settingsValidation/runtime.ts +9 -0
- package/src/utils/settingsValidation/types.ts +2 -0
- package/types/integrations/ga/GoogleAnalyticsToSplit.d.ts +2 -2
- package/types/integrations/ga/SplitToGoogleAnalytics.d.ts +2 -3
- package/types/integrations/types.d.ts +4 -0
- package/types/logger/constants.d.ts +4 -2
- package/types/logger/types.d.ts +4 -4
- package/types/sdkFactory/types.d.ts +1 -0
- package/types/sdkFactory/userConsentProps.d.ts +6 -0
- package/types/storages/KeyBuilderCS.d.ts +2 -0
- package/types/storages/inMemory/ImpressionsCacheInMemory.d.ts +9 -0
- package/types/storages/types.d.ts +3 -1
- package/types/sync/types.d.ts +3 -0
- package/types/types.d.ts +21 -0
- package/types/utils/consent.d.ts +2 -0
- package/types/utils/constants/index.d.ts +3 -0
- package/types/utils/settingsValidation/consent.d.ts +5 -0
- package/types/utils/settingsValidation/impressionsMode.d.ts +1 -1
- package/types/utils/settingsValidation/runtime/browser.d.ts +2 -4
- package/types/utils/settingsValidation/runtime/node.d.ts +1 -4
- package/types/utils/settingsValidation/runtime.d.ts +2 -0
- package/types/utils/settingsValidation/types.d.ts +2 -0
- package/types/utils/settingsValidation/userConsent.d.ts +5 -0
- package/cjs/utils/settingsValidation/runtime/node.js +0 -22
- package/esm/utils/settingsValidation/runtime/node.js +0 -17
- package/src/utils/settingsValidation/runtime/browser.ts +0 -6
- package/src/utils/settingsValidation/runtime/node.ts +0 -22
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { submitterManagerFactory } from './submitters/submitterManager';
|
|
2
2
|
import { PUSH_SUBSYSTEM_UP, PUSH_SUBSYSTEM_DOWN } from './streaming/constants';
|
|
3
3
|
import { SYNC_START_POLLING, SYNC_CONTINUE_POLLING, SYNC_STOP_POLLING } from '../logger/constants';
|
|
4
|
+
import { isConsentGranted } from '../utils/consent';
|
|
4
5
|
/**
|
|
5
6
|
* Online SyncManager factory.
|
|
6
7
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -14,7 +15,7 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
14
15
|
* SyncManager factory for modular SDK
|
|
15
16
|
*/
|
|
16
17
|
return function (params) {
|
|
17
|
-
var _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled;
|
|
18
|
+
var settings = params.settings, _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled;
|
|
18
19
|
/** Polling Manager */
|
|
19
20
|
var pollingManager = pollingManagerFactory && pollingManagerFactory(params);
|
|
20
21
|
/** Push Manager */
|
|
@@ -49,11 +50,16 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
49
50
|
var running = false; // flag that indicates whether the syncManager has been started (true) or stopped (false)
|
|
50
51
|
var startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
|
|
51
52
|
return {
|
|
53
|
+
// Exposed for fine-grained control of synchronization.
|
|
54
|
+
// E.g.: user consent, app state changes (Page hide, Foreground/Background, Online/Offline).
|
|
55
|
+
pollingManager: pollingManager,
|
|
52
56
|
pushManager: pushManager,
|
|
57
|
+
submitter: submitter,
|
|
53
58
|
/**
|
|
54
59
|
* Method used to start the syncManager for the first time, or resume it after being stopped.
|
|
55
60
|
*/
|
|
56
61
|
start: function () {
|
|
62
|
+
running = true;
|
|
57
63
|
// start syncing splits and segments
|
|
58
64
|
if (pollingManager) {
|
|
59
65
|
if (pushManager) {
|
|
@@ -69,29 +75,27 @@ export function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFacto
|
|
|
69
75
|
}
|
|
70
76
|
}
|
|
71
77
|
// start periodic data recording (events, impressions, telemetry).
|
|
72
|
-
if (
|
|
78
|
+
if (isConsentGranted(settings))
|
|
73
79
|
submitter.start();
|
|
74
|
-
running = true;
|
|
75
80
|
},
|
|
76
81
|
/**
|
|
77
82
|
* Method used to stop/pause the syncManager.
|
|
78
83
|
*/
|
|
79
84
|
stop: function () {
|
|
85
|
+
running = false;
|
|
80
86
|
// stop syncing
|
|
81
87
|
if (pushManager)
|
|
82
88
|
pushManager.stop();
|
|
83
89
|
if (pollingManager && pollingManager.isRunning())
|
|
84
90
|
pollingManager.stop();
|
|
85
91
|
// stop periodic data recording (events, impressions, telemetry).
|
|
86
|
-
|
|
87
|
-
submitter.stop();
|
|
88
|
-
running = false;
|
|
92
|
+
submitter.stop();
|
|
89
93
|
},
|
|
90
94
|
isRunning: function () {
|
|
91
95
|
return running;
|
|
92
96
|
},
|
|
93
97
|
flush: function () {
|
|
94
|
-
if (
|
|
98
|
+
if (isConsentGranted(settings))
|
|
95
99
|
return submitter.execute();
|
|
96
100
|
else
|
|
97
101
|
return Promise.resolve();
|
|
@@ -24,3 +24,7 @@ export var STORAGE_MEMORY = 'MEMORY';
|
|
|
24
24
|
export var STORAGE_LOCALSTORAGE = 'LOCALSTORAGE';
|
|
25
25
|
export var STORAGE_REDIS = 'REDIS';
|
|
26
26
|
export var STORAGE_PLUGGABLE = 'PLUGGABLE';
|
|
27
|
+
// User consent
|
|
28
|
+
export var CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
|
|
29
|
+
export var CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
|
|
30
|
+
export var CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
|
+
import { CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN } from '../constants';
|
|
3
|
+
var userConsentValues = [CONSENT_DECLINED, CONSENT_GRANTED, CONSENT_UNKNOWN];
|
|
4
|
+
export function validateConsent(_a) {
|
|
5
|
+
var userConsent = _a.userConsent, log = _a.log;
|
|
6
|
+
if (typeof userConsent === 'string')
|
|
7
|
+
userConsent = userConsent.toUpperCase();
|
|
8
|
+
if (userConsentValues.indexOf(userConsent) > -1)
|
|
9
|
+
return userConsent;
|
|
10
|
+
log.error(ERROR_INVALID_CONFIG_PARAM, ['userConsent', userConsentValues, CONSENT_GRANTED]);
|
|
11
|
+
return CONSENT_GRANTED;
|
|
12
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { ERROR_INVALID_CONFIG_PARAM } from '../../logger/constants';
|
|
2
2
|
import { DEBUG, OPTIMIZED } from '../constants';
|
|
3
3
|
export function validImpressionsMode(log, impressionsMode) {
|
|
4
|
-
impressionsMode
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
impressionsMode
|
|
8
|
-
|
|
9
|
-
return
|
|
4
|
+
if (typeof impressionsMode === 'string')
|
|
5
|
+
impressionsMode = impressionsMode.toUpperCase();
|
|
6
|
+
if ([DEBUG, OPTIMIZED].indexOf(impressionsMode) > -1)
|
|
7
|
+
return impressionsMode;
|
|
8
|
+
log.error(ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [DEBUG, OPTIMIZED], OPTIMIZED]);
|
|
9
|
+
return OPTIMIZED;
|
|
10
10
|
}
|
|
@@ -33,6 +33,8 @@ var base = {
|
|
|
33
33
|
eventsPushRate: 60,
|
|
34
34
|
// how many events will be queued before flushing
|
|
35
35
|
eventsQueueSize: 500,
|
|
36
|
+
// how many impressions will be queued before flushing
|
|
37
|
+
impressionsQueueSize: 30000,
|
|
36
38
|
// backoff base seconds to wait before re attempting to connect to push notifications
|
|
37
39
|
pushRetryBackoffBase: 1,
|
|
38
40
|
},
|
|
@@ -78,7 +80,7 @@ function fromSecondsToMillis(n) {
|
|
|
78
80
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
79
81
|
*/
|
|
80
82
|
export function settingsValidation(config, validationParams) {
|
|
81
|
-
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost;
|
|
83
|
+
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
82
84
|
// creates a settings object merging base, defaults and config objects.
|
|
83
85
|
var withDefaults = merge({}, base, defaults, config);
|
|
84
86
|
// ensure a valid logger.
|
|
@@ -131,5 +133,8 @@ export function settingsValidation(config, validationParams) {
|
|
|
131
133
|
withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
|
|
132
134
|
// ensure a valid impressionsMode
|
|
133
135
|
withDefaults.sync.impressionsMode = validImpressionsMode(log, withDefaults.sync.impressionsMode);
|
|
136
|
+
// ensure a valid user consent value
|
|
137
|
+
// @ts-ignore, modify readonly prop
|
|
138
|
+
withDefaults.userConsent = consent(withDefaults);
|
|
134
139
|
return withDefaults;
|
|
135
140
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@splitsoftware/splitio-commons",
|
|
3
|
-
"version": "1.2.1-rc.
|
|
3
|
+
"version": "1.2.1-rc.5",
|
|
4
4
|
"description": "Split Javascript SDK common components",
|
|
5
5
|
"main": "cjs/index.js",
|
|
6
6
|
"module": "esm/index.js",
|
|
@@ -49,7 +49,6 @@
|
|
|
49
49
|
"devDependencies": {
|
|
50
50
|
"@types/google.analytics": "0.0.40",
|
|
51
51
|
"@types/ioredis": "^4.28.0",
|
|
52
|
-
"@types/ip": "^1.1.0",
|
|
53
52
|
"@types/jest": "^27.0.0",
|
|
54
53
|
"@types/lodash": "^4.14.162",
|
|
55
54
|
"@typescript-eslint/eslint-plugin": "^4.2.0",
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { IIntegrationFactoryParams } from '../types';
|
|
1
|
+
import { IIntegrationFactoryParams, IntegrationFactory } from '../types';
|
|
2
2
|
import { GaToSplit } from './GaToSplit';
|
|
3
3
|
import { GoogleAnalyticsToSplitOptions } from './types';
|
|
4
4
|
|
|
5
|
-
export function GoogleAnalyticsToSplit(options: GoogleAnalyticsToSplitOptions) {
|
|
5
|
+
export function GoogleAnalyticsToSplit(options: GoogleAnalyticsToSplitOptions): IntegrationFactory {
|
|
6
6
|
|
|
7
7
|
// GaToSplit integration factory
|
|
8
|
-
|
|
8
|
+
function GoogleAnalyticsToSplitFactory(params: IIntegrationFactoryParams) {
|
|
9
9
|
return GaToSplit(options, params);
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
GoogleAnalyticsToSplitFactory.type = 'GOOGLE_ANALYTICS_TO_SPLIT';
|
|
13
|
+
return GoogleAnalyticsToSplitFactory;
|
|
11
14
|
}
|
|
@@ -1,11 +1,14 @@
|
|
|
1
|
-
import { IIntegrationFactoryParams } from '../types';
|
|
1
|
+
import { IIntegrationFactoryParams, IntegrationFactory } from '../types';
|
|
2
2
|
import { SplitToGa } from './SplitToGa';
|
|
3
3
|
import { SplitToGoogleAnalyticsOptions } from './types';
|
|
4
4
|
|
|
5
|
-
export function SplitToGoogleAnalytics(options: SplitToGoogleAnalyticsOptions = {}) {
|
|
5
|
+
export function SplitToGoogleAnalytics(options: SplitToGoogleAnalyticsOptions = {}): IntegrationFactory {
|
|
6
6
|
|
|
7
7
|
// SplitToGa integration factory
|
|
8
|
-
|
|
8
|
+
function SplitToGoogleAnalyticsFactory(params: IIntegrationFactoryParams) {
|
|
9
9
|
return new SplitToGa(params.settings.log, options);
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
SplitToGoogleAnalyticsFactory.type = 'SPLIT_TO_GOOGLE_ANALYTICS';
|
|
13
|
+
return SplitToGoogleAnalyticsFactory;
|
|
11
14
|
}
|
package/src/listeners/browser.ts
CHANGED
|
@@ -11,6 +11,7 @@ import { OPTIMIZED, DEBUG } from '../utils/constants';
|
|
|
11
11
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
12
12
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
13
13
|
import { ISyncManager } from '../sync/types';
|
|
14
|
+
import { isConsentGranted } from '../utils/consent';
|
|
14
15
|
|
|
15
16
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
16
17
|
const UNLOAD_DOM_EVENT = 'unload';
|
|
@@ -65,15 +66,18 @@ export class BrowserSignalListener implements ISignalListener {
|
|
|
65
66
|
flushData() {
|
|
66
67
|
if (!this.syncManager) return; // In consumer mode there is not sync manager and data to flush
|
|
67
68
|
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
69
|
+
// Flush data if there is user consent
|
|
70
|
+
if (isConsentGranted(this.settings)) {
|
|
71
|
+
const eventsUrl = this.settings.urls.events;
|
|
72
|
+
const extraMetadata = {
|
|
73
|
+
// sim stands for Sync/Split Impressions Mode
|
|
74
|
+
sim: this.settings.sync.impressionsMode === OPTIMIZED ? OPTIMIZED : DEBUG
|
|
75
|
+
};
|
|
73
76
|
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
+
this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
|
|
78
|
+
this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
|
|
79
|
+
if (this.storage.impressionCounts) this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
|
|
80
|
+
}
|
|
77
81
|
|
|
78
82
|
// Close streaming connection
|
|
79
83
|
if (this.syncManager.pushManager) this.syncManager.pushManager.stop();
|
|
@@ -84,7 +88,7 @@ export class BrowserSignalListener implements ISignalListener {
|
|
|
84
88
|
if (!cache.isEmpty()) {
|
|
85
89
|
const dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.state()) : cache.state();
|
|
86
90
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
87
|
-
postService(JSON.stringify(dataPayload)).catch(() => { }); // no-op just to catch a possible
|
|
91
|
+
postService(JSON.stringify(dataPayload)).catch(() => { }); // no-op just to catch a possible exception
|
|
88
92
|
}
|
|
89
93
|
cache.clear();
|
|
90
94
|
}
|
package/src/logger/constants.ts
CHANGED
|
@@ -61,13 +61,14 @@ export const STREAMING_RECONNECT = 111;
|
|
|
61
61
|
export const STREAMING_CONNECTING = 112;
|
|
62
62
|
export const STREAMING_DISABLED = 113;
|
|
63
63
|
export const STREAMING_DISCONNECTING = 114;
|
|
64
|
-
export const
|
|
64
|
+
export const SUBMITTERS_PUSH_FULL_QUEUE = 115;
|
|
65
65
|
export const SUBMITTERS_PUSH = 116;
|
|
66
66
|
export const SYNC_START_POLLING = 117;
|
|
67
67
|
export const SYNC_CONTINUE_POLLING = 118;
|
|
68
68
|
export const SYNC_STOP_POLLING = 119;
|
|
69
69
|
export const EVENTS_TRACKER_SUCCESS = 120;
|
|
70
70
|
export const IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
71
|
+
export const USER_CONSENT_UPDATED = 122;
|
|
71
72
|
|
|
72
73
|
export const ENGINE_VALUE_INVALID = 200;
|
|
73
74
|
export const ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
@@ -115,10 +116,11 @@ export const ERROR_INVALID_KEY_OBJECT = 317;
|
|
|
115
116
|
export const ERROR_INVALID = 318;
|
|
116
117
|
export const ERROR_EMPTY = 319;
|
|
117
118
|
export const ERROR_EMPTY_ARRAY = 320;
|
|
118
|
-
export const
|
|
119
|
+
export const ERROR_INVALID_CONFIG_PARAM = 321;
|
|
119
120
|
export const ERROR_HTTP = 322;
|
|
120
121
|
export const ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
121
122
|
export const ERROR_STORAGE_INVALID = 324;
|
|
123
|
+
export const ERROR_NOT_BOOLEAN = 325;
|
|
122
124
|
|
|
123
125
|
// Log prefixes (a.k.a. tags or categories)
|
|
124
126
|
export const LOG_PREFIX_SETTINGS = 'settings';
|
|
@@ -13,7 +13,7 @@ export const codesError: [number, string][] = [
|
|
|
13
13
|
[c.ERROR_SYNC_OFFLINE_LOADING, c.LOG_PREFIX_SYNC_OFFLINE + 'There was an issue loading the mock Splits data, no changes will be applied to the current cache. %s'],
|
|
14
14
|
[c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to connect or error on streaming connection, with error message: %s'],
|
|
15
15
|
[c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error: %s.'],
|
|
16
|
-
[c.ERROR_HTTP, '
|
|
16
|
+
[c.ERROR_HTTP, 'Response status is not OK. Status: %s. URL: %s. Message: %s'],
|
|
17
17
|
// client status
|
|
18
18
|
[c.ERROR_CLIENT_LISTENER, 'A listener was added for %s on the SDK, which has already fired and won\'t be emitted again. The callback won\'t be executed.'],
|
|
19
19
|
[c.ERROR_CLIENT_DESTROYED, '%s: Client has already been destroyed - no calls possible.'],
|
|
@@ -28,8 +28,9 @@ export const codesError: [number, string][] = [
|
|
|
28
28
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
29
29
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
30
30
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
31
|
+
[c.ERROR_NOT_BOOLEAN, '%s: you must provide a boolean param.'],
|
|
31
32
|
// initialization / settings validation
|
|
32
|
-
[c.
|
|
33
|
+
[c.ERROR_INVALID_CONFIG_PARAM, c.LOG_PREFIX_SETTINGS + ': you passed an invalid "%s" config param. It should be one of the following values: %s. Defaulting to "%s".'],
|
|
33
34
|
[c.ERROR_LOCALHOST_MODULE_REQUIRED, c.LOG_PREFIX_SETTINGS + ': an invalid value was received for "sync.localhostMode" config. A valid entity should be provided for localhost mode.'],
|
|
34
35
|
[c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS+': The provided storage is invalid.%s Fallbacking into default MEMORY storage'],
|
|
35
36
|
];
|
|
@@ -14,13 +14,14 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
14
14
|
[c.NEW_FACTORY, ' New Split SDK instance created.'],
|
|
15
15
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
16
16
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
17
|
+
[c.USER_CONSENT_UPDATED, 'User consent changed from %s to %s.'],
|
|
17
18
|
|
|
18
19
|
// synchronizer
|
|
19
20
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
20
21
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
21
22
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
22
23
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
|
|
23
|
-
[c.
|
|
24
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
|
|
24
25
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
|
|
25
26
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
26
27
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -29,5 +30,5 @@ export const codesInfo: [number, string][] = codesWarn.concat([
|
|
|
29
30
|
[c.STREAMING_DISCONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Disconnecting streaming.'],
|
|
30
31
|
[c.SYNC_START_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming not available. Starting polling.'],
|
|
31
32
|
[c.SYNC_CONTINUE_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming couldn\'t connect. Continue polling.'],
|
|
32
|
-
[c.SYNC_STOP_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming
|
|
33
|
+
[c.SYNC_STOP_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming connected. Syncing and stopping polling.'],
|
|
33
34
|
]);
|
package/src/logger/types.ts
CHANGED
|
@@ -9,15 +9,15 @@ export interface ILoggerOptions {
|
|
|
9
9
|
export interface ILogger {
|
|
10
10
|
setLogLevel(logLevel: LogLevel): void
|
|
11
11
|
|
|
12
|
-
debug(msg:
|
|
12
|
+
debug(msg: any): void
|
|
13
13
|
debug(msg: string | number, args?: any[]): void
|
|
14
14
|
|
|
15
|
-
info(msg:
|
|
15
|
+
info(msg: any): void
|
|
16
16
|
info(msg: string | number, args?: any[]): void
|
|
17
17
|
|
|
18
|
-
warn(msg:
|
|
18
|
+
warn(msg: any): void
|
|
19
19
|
warn(msg: string | number, args?: any[]): void
|
|
20
20
|
|
|
21
|
-
error(msg:
|
|
21
|
+
error(msg: any): void
|
|
22
22
|
error(msg: string | number, args?: any[]): void
|
|
23
23
|
}
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -4,7 +4,7 @@ import { getMatching, getBucketing } from '../utils/key';
|
|
|
4
4
|
import { validateSplitExistance } from '../utils/inputValidation/splitExistance';
|
|
5
5
|
import { validateTrafficTypeExistance } from '../utils/inputValidation/trafficTypeExistance';
|
|
6
6
|
import { SDK_NOT_READY } from '../utils/labels';
|
|
7
|
-
import { CONTROL } from '../utils/constants';
|
|
7
|
+
import { CONSENT_DECLINED, CONTROL } from '../utils/constants';
|
|
8
8
|
import { IClientFactoryParams } from './types';
|
|
9
9
|
import { IEvaluationResult } from '../evaluator/types';
|
|
10
10
|
import { SplitIO, ImpressionDTO } from '../types';
|
|
@@ -16,13 +16,14 @@ import { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
|
16
16
|
*/
|
|
17
17
|
// @TODO missing time tracking to collect telemetry
|
|
18
18
|
export function clientFactory(params: IClientFactoryParams): SplitIO.IClient | SplitIO.IAsyncClient {
|
|
19
|
-
const { sdkReadinessManager: { readinessManager }, storage, settings
|
|
19
|
+
const { sdkReadinessManager: { readinessManager }, storage, settings, impressionsTracker, eventTracker } = params;
|
|
20
|
+
const { log, mode } = settings;
|
|
20
21
|
|
|
21
22
|
function getTreatment(key: SplitIO.SplitKey, splitName: string, attributes: SplitIO.Attributes | undefined, withConfig = false) {
|
|
22
23
|
const wrapUp = (evaluationResult: IEvaluationResult) => {
|
|
23
24
|
const queue: ImpressionDTO[] = [];
|
|
24
25
|
const treatment = processEvaluation(evaluationResult, splitName, key, attributes, withConfig, `getTreatment${withConfig ? 'withConfig' : ''}`, queue);
|
|
25
|
-
impressionsTracker.track(queue, attributes);
|
|
26
|
+
if (settings.userConsent !== CONSENT_DECLINED) impressionsTracker.track(queue, attributes);
|
|
26
27
|
return treatment;
|
|
27
28
|
};
|
|
28
29
|
|
|
@@ -42,7 +43,7 @@ export function clientFactory(params: IClientFactoryParams): SplitIO.IClient | S
|
|
|
42
43
|
Object.keys(evaluationResults).forEach(splitName => {
|
|
43
44
|
treatments[splitName] = processEvaluation(evaluationResults[splitName], splitName, key, attributes, withConfig, `getTreatments${withConfig ? 'withConfig' : ''}`, queue);
|
|
44
45
|
});
|
|
45
|
-
impressionsTracker.track(queue, attributes);
|
|
46
|
+
if (settings.userConsent !== CONSENT_DECLINED) impressionsTracker.track(queue, attributes);
|
|
46
47
|
return treatments;
|
|
47
48
|
};
|
|
48
49
|
|
|
@@ -115,7 +116,8 @@ export function clientFactory(params: IClientFactoryParams): SplitIO.IClient | S
|
|
|
115
116
|
// This may be async but we only warn, we don't actually care if it is valid or not in terms of queueing the event.
|
|
116
117
|
validateTrafficTypeExistance(log, readinessManager, storage.splits, mode, trafficTypeName, 'track');
|
|
117
118
|
|
|
118
|
-
return eventTracker.track(eventData, size);
|
|
119
|
+
if (settings.userConsent !== CONSENT_DECLINED) return eventTracker.track(eventData, size);
|
|
120
|
+
else return false;
|
|
119
121
|
}
|
|
120
122
|
|
|
121
123
|
return {
|
package/src/sdkFactory/index.ts
CHANGED
|
@@ -12,13 +12,14 @@ import { createLoggerAPI } from '../logger/sdkLogger';
|
|
|
12
12
|
import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
|
|
13
13
|
import { metadataBuilder } from '../storages/metadataBuilder';
|
|
14
14
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
15
|
+
import { objectAssign } from '../utils/lang/objectAssign';
|
|
15
16
|
|
|
16
17
|
/**
|
|
17
18
|
* Modular SDK factory
|
|
18
19
|
*/
|
|
19
20
|
export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.ISDK | SplitIO.IAsyncSDK {
|
|
20
21
|
|
|
21
|
-
const { settings, platform, storageFactory, splitApiFactory,
|
|
22
|
+
const { settings, platform, storageFactory, splitApiFactory, extraProps,
|
|
22
23
|
syncManagerFactory, SignalListener, impressionsObserverFactory, impressionListener,
|
|
23
24
|
integrationsManagerFactory, sdkManagerFactory, sdkClientMethodFactory } = params;
|
|
24
25
|
const log = settings.log;
|
|
@@ -33,6 +34,7 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
33
34
|
|
|
34
35
|
// @TODO consider passing the settings object, so that each storage access only what it needs
|
|
35
36
|
const storageFactoryParams: IStorageFactoryParams = {
|
|
37
|
+
impressionsQueueSize: settings.scheduler.impressionsQueueSize,
|
|
36
38
|
eventsQueueSize: settings.scheduler.eventsQueueSize,
|
|
37
39
|
optimize: shouldBeOptimized(settings),
|
|
38
40
|
|
|
@@ -87,12 +89,12 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
87
89
|
|
|
88
90
|
log.info(NEW_FACTORY);
|
|
89
91
|
|
|
90
|
-
|
|
92
|
+
// @ts-ignore
|
|
93
|
+
return objectAssign({
|
|
91
94
|
// Split evaluation and event tracking engine
|
|
92
95
|
client: clientMethod,
|
|
93
96
|
|
|
94
97
|
// Manager API to explore available information
|
|
95
|
-
// @ts-ignore
|
|
96
98
|
manager() {
|
|
97
99
|
log.debug(RETRIEVE_MANAGER);
|
|
98
100
|
return managerInstance;
|
|
@@ -102,5 +104,5 @@ export function sdkFactory(params: ISdkFactoryParams): SplitIO.ICsSDK | SplitIO.
|
|
|
102
104
|
Logger: createLoggerAPI(settings.log),
|
|
103
105
|
|
|
104
106
|
settings,
|
|
105
|
-
};
|
|
107
|
+
}, extraProps && extraProps(settings, syncManager));
|
|
106
108
|
}
|
package/src/sdkFactory/types.ts
CHANGED
|
@@ -70,4 +70,6 @@ export interface ISdkFactoryParams {
|
|
|
70
70
|
// Impression observer factory. If provided, will be used for impressions dedupe
|
|
71
71
|
impressionsObserverFactory?: () => IImpressionObserver
|
|
72
72
|
|
|
73
|
+
// Optional function to assign additional properties to the factory instance
|
|
74
|
+
extraProps?: (settings: ISettings, syncManager?: ISyncManager) => object
|
|
73
75
|
}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { ERROR_NOT_BOOLEAN, USER_CONSENT_UPDATED } from '../logger/constants';
|
|
2
|
+
import { ISyncManager } from '../sync/types';
|
|
3
|
+
import { ISettings } from '../types';
|
|
4
|
+
import { CONSENT_GRANTED, CONSENT_DECLINED } from '../utils/constants';
|
|
5
|
+
|
|
6
|
+
// Extend client-side factory instances with user consent getter/setter
|
|
7
|
+
export function userConsentProps(settings: ISettings, syncManager?: ISyncManager) {
|
|
8
|
+
|
|
9
|
+
const log = settings.log;
|
|
10
|
+
|
|
11
|
+
return {
|
|
12
|
+
setUserConsent(consent: unknown) {
|
|
13
|
+
// validate input param
|
|
14
|
+
if (typeof consent !== 'boolean') {
|
|
15
|
+
log.error(ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
16
|
+
return false;
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const newConsentStatus = consent ? CONSENT_GRANTED : CONSENT_DECLINED;
|
|
20
|
+
|
|
21
|
+
if (settings.userConsent !== newConsentStatus) {
|
|
22
|
+
// resume/pause submitters
|
|
23
|
+
if (consent) syncManager?.submitter?.start();
|
|
24
|
+
else syncManager?.submitter?.stop();
|
|
25
|
+
|
|
26
|
+
log.info(USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
27
|
+
settings.userConsent = newConsentStatus;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
return true;
|
|
31
|
+
},
|
|
32
|
+
|
|
33
|
+
getUserConsent() {
|
|
34
|
+
return settings.userConsent;
|
|
35
|
+
}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
@@ -16,10 +16,22 @@ export class KeyBuilderCS extends KeyBuilder {
|
|
|
16
16
|
* @override
|
|
17
17
|
*/
|
|
18
18
|
buildSegmentNameKey(segmentName: string) {
|
|
19
|
-
return `${this.
|
|
19
|
+
return `${this.prefix}.${this.matchingKey}.segment.${segmentName}`;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
22
|
extractSegmentName(builtSegmentKeyName: string) {
|
|
23
|
+
const prefix = `${this.prefix}.${this.matchingKey}.segment.`;
|
|
24
|
+
|
|
25
|
+
if (startsWith(builtSegmentKeyName, prefix))
|
|
26
|
+
return builtSegmentKeyName.substr(prefix.length);
|
|
27
|
+
}
|
|
28
|
+
|
|
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
|
+
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
34
|
+
extractOldSegmentKey(builtSegmentKeyName: string) {
|
|
23
35
|
const prefix = `${this.matchingKey}.${this.prefix}.segment.`;
|
|
24
36
|
|
|
25
37
|
if (startsWith(builtSegmentKeyName, prefix))
|
|
@@ -67,9 +67,29 @@ export class MySegmentsCacheInLocal extends AbstractSegmentsCacheSync {
|
|
|
67
67
|
|
|
68
68
|
// Scan current values from localStorage
|
|
69
69
|
const storedSegmentNames = Object.keys(localStorage).reduce((accum, key) => {
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
if (
|
|
70
|
+
let segmentName = this.keys.extractSegmentName(key);
|
|
71
|
+
|
|
72
|
+
if (segmentName) {
|
|
73
|
+
accum.push(segmentName);
|
|
74
|
+
} else {
|
|
75
|
+
// @BREAKING: This is only to clean up "old" keys. Remove this whole else code block.
|
|
76
|
+
segmentName = this.keys.extractOldSegmentKey(key);
|
|
77
|
+
|
|
78
|
+
if (segmentName) { // this was an old segment key, let's clean up.
|
|
79
|
+
const newSegmentKey = this.keys.buildSegmentNameKey(segmentName);
|
|
80
|
+
try {
|
|
81
|
+
// If the new format key is not there, create it.
|
|
82
|
+
if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) {
|
|
83
|
+
localStorage.setItem(newSegmentKey, DEFINED);
|
|
84
|
+
// we are migrating a segment, let's track it.
|
|
85
|
+
accum.push(segmentName);
|
|
86
|
+
}
|
|
87
|
+
localStorage.removeItem(key); // we migrated the current key, let's delete it.
|
|
88
|
+
} catch (e) {
|
|
89
|
+
this.log.error(e);
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
}
|
|
73
93
|
|
|
74
94
|
return accum;
|
|
75
95
|
}, [] as string[]);
|
|
@@ -40,7 +40,7 @@ export function InLocalStorage(options: InLocalStorageOptions = {}): IStorageSyn
|
|
|
40
40
|
return {
|
|
41
41
|
splits: new SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
|
|
42
42
|
segments: new MySegmentsCacheInLocal(log, keys),
|
|
43
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
43
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
44
44
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
45
45
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
46
46
|
|
|
@@ -3,13 +3,34 @@ import { ImpressionDTO } from '../../types';
|
|
|
3
3
|
|
|
4
4
|
export class ImpressionsCacheInMemory implements IImpressionsCacheSync {
|
|
5
5
|
|
|
6
|
-
private
|
|
6
|
+
private onFullQueue?: () => void;
|
|
7
|
+
private readonly maxQueue: number;
|
|
8
|
+
private queue: ImpressionDTO[];
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
*
|
|
12
|
+
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
13
|
+
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
14
|
+
*/
|
|
15
|
+
constructor(impressionsQueueSize: number = 0) {
|
|
16
|
+
this.maxQueue = impressionsQueueSize;
|
|
17
|
+
this.queue = [];
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
setOnFullQueueCb(cb: () => void) {
|
|
21
|
+
this.onFullQueue = cb;
|
|
22
|
+
}
|
|
7
23
|
|
|
8
24
|
/**
|
|
9
25
|
* Store impressions in sequential order
|
|
10
26
|
*/
|
|
11
27
|
track(data: ImpressionDTO[]) {
|
|
12
28
|
this.queue.push(...data);
|
|
29
|
+
|
|
30
|
+
// Check if the cache queue is full and we need to flush it.
|
|
31
|
+
if (this.maxQueue > 0 && this.queue.length >= this.maxQueue && this.onFullQueue) {
|
|
32
|
+
this.onFullQueue();
|
|
33
|
+
}
|
|
13
34
|
}
|
|
14
35
|
|
|
15
36
|
/**
|
|
@@ -16,7 +16,7 @@ export function InMemoryStorageFactory(params: IStorageFactoryParams): IStorageS
|
|
|
16
16
|
return {
|
|
17
17
|
splits: new SplitsCacheInMemory(),
|
|
18
18
|
segments: new SegmentsCacheInMemory(),
|
|
19
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
19
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
20
20
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
21
21
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
22
22
|
|
|
@@ -16,7 +16,7 @@ export function InMemoryStorageCSFactory(params: IStorageFactoryParams): IStorag
|
|
|
16
16
|
return {
|
|
17
17
|
splits: new SplitsCacheInMemory(),
|
|
18
18
|
segments: new MySegmentsCacheInMemory(),
|
|
19
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
19
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
20
20
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
21
21
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
22
22
|
|
|
@@ -63,7 +63,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
|
|
|
63
63
|
|
|
64
64
|
const prefix = validatePrefix(options.prefix);
|
|
65
65
|
|
|
66
|
-
function PluggableStorageFactory({ log, metadata, onReadyCb, mode, eventsQueueSize, optimize }: IStorageFactoryParams): IStorageAsync {
|
|
66
|
+
function PluggableStorageFactory({ log, metadata, onReadyCb, mode, eventsQueueSize, impressionsQueueSize, optimize }: IStorageFactoryParams): IStorageAsync {
|
|
67
67
|
const keys = new KeyBuilderSS(prefix, metadata);
|
|
68
68
|
const wrapper = wrapperAdapter(log, options.wrapper);
|
|
69
69
|
const isPartialConsumer = mode === CONSUMER_PARTIAL_MODE;
|
|
@@ -74,7 +74,7 @@ export function PluggableStorage(options: PluggableStorageOptions): IStorageAsyn
|
|
|
74
74
|
return {
|
|
75
75
|
splits: new SplitsCachePluggable(log, keys, wrapper),
|
|
76
76
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
77
|
-
impressions: isPartialConsumer ? new ImpressionsCacheInMemory() : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
77
|
+
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
78
78
|
impressionCounts: optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
79
79
|
events: isPartialConsumer ? promisifyEventsTrack(new EventsCacheInMemory(eventsQueueSize)) : new EventsCachePluggable(log, keys.buildEventsKey(), wrapper, metadata),
|
|
80
80
|
// @TODO add telemetry cache when required
|