@splitsoftware/splitio-commons 1.2.1-rc.4 → 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/listeners/browser.js +14 -10
- package/cjs/logger/constants.js +5 -3
- package/cjs/logger/messages/error.js +2 -1
- package/cjs/logger/messages/info.js +1 -0
- package/cjs/sdkClient/client.js +10 -4
- package/cjs/sdkFactory/index.js +5 -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/sync/submitters/eventsSyncTask.js +6 -2
- package/cjs/sync/submitters/impressionsSyncTask.js +6 -2
- 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 +4 -1
- package/esm/listeners/browser.js +14 -10
- package/esm/logger/constants.js +3 -1
- package/esm/logger/messages/error.js +2 -1
- package/esm/logger/messages/info.js +1 -0
- package/esm/sdkClient/client.js +11 -5
- package/esm/sdkFactory/index.js +5 -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/sync/submitters/eventsSyncTask.js +6 -2
- package/esm/sync/submitters/impressionsSyncTask.js +6 -2
- 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 +4 -1
- package/package.json +1 -1
- package/src/listeners/browser.ts +13 -9
- package/src/logger/constants.ts +3 -1
- package/src/logger/messages/error.ts +2 -1
- package/src/logger/messages/info.ts +1 -0
- package/src/sdkClient/client.ts +7 -5
- package/src/sdkFactory/index.ts +5 -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/sync/submitters/eventsSyncTask.ts +6 -2
- package/src/sync/submitters/impressionsSyncTask.ts +6 -2
- package/src/sync/syncManagerOnline.ts +13 -7
- package/src/sync/types.ts +4 -1
- package/src/types.ts +6 -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 +5 -1
- package/src/utils/settingsValidation/types.ts +2 -0
- package/types/logger/constants.d.ts +3 -1
- 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/sync/types.d.ts +3 -0
- package/types/types.d.ts +6 -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/types.d.ts +2 -0
- package/types/utils/settingsValidation/userConsent.d.ts +5 -0
package/cjs/listeners/browser.js
CHANGED
|
@@ -6,6 +6,7 @@ var impressionCountsSyncTask_1 = require("../sync/submitters/impressionCountsSyn
|
|
|
6
6
|
var constants_1 = require("../utils/constants");
|
|
7
7
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
8
8
|
var constants_2 = require("../logger/constants");
|
|
9
|
+
var consent_1 = require("../utils/consent");
|
|
9
10
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
10
11
|
var UNLOAD_DOM_EVENT = 'unload';
|
|
11
12
|
var EVENT_NAME = 'for unload page event.';
|
|
@@ -51,15 +52,18 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
51
52
|
BrowserSignalListener.prototype.flushData = function () {
|
|
52
53
|
if (!this.syncManager)
|
|
53
54
|
return; // In consumer mode there is not sync manager and data to flush
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
this._flushData(eventsUrl + '/
|
|
55
|
+
// Flush data if there is user consent
|
|
56
|
+
if ((0, consent_1.isConsentGranted)(this.settings)) {
|
|
57
|
+
var eventsUrl = this.settings.urls.events;
|
|
58
|
+
var extraMetadata = {
|
|
59
|
+
// sim stands for Sync/Split Impressions Mode
|
|
60
|
+
sim: this.settings.sync.impressionsMode === constants_1.OPTIMIZED ? constants_1.OPTIMIZED : constants_1.DEBUG
|
|
61
|
+
};
|
|
62
|
+
this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
|
|
63
|
+
this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
|
|
64
|
+
if (this.storage.impressionCounts)
|
|
65
|
+
this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, impressionCountsSyncTask_1.fromImpressionCountsCollector);
|
|
66
|
+
}
|
|
63
67
|
// Close streaming connection
|
|
64
68
|
if (this.syncManager.pushManager)
|
|
65
69
|
this.syncManager.pushManager.stop();
|
|
@@ -69,7 +73,7 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
69
73
|
if (!cache.isEmpty()) {
|
|
70
74
|
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.state()) : cache.state();
|
|
71
75
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
72
|
-
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible
|
|
76
|
+
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
|
|
73
77
|
}
|
|
74
78
|
cache.clear();
|
|
75
79
|
}
|
package/cjs/logger/constants.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.SYNC_SPLITS_FETCH_RETRY = exports.POLLING_STOP = exports.POLLING_START = exports.POLLING_SMART_PAUSING = exports.NEW_FACTORY = exports.NEW_SHARED_CLIENT = exports.IMPRESSION_QUEUEING = exports.IMPRESSION = exports.CLIENT_READY = exports.CLIENT_READY_FROM_CACHE = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_SPLITS_SEGMENTS = exports.SYNC_SPLITS_REMOVED = exports.SYNC_SPLITS_NEW = exports.SYNC_SPLITS_FETCH = exports.SYNC_OFFLINE_DATA = exports.RETRIEVE_MANAGER = exports.RETRIEVE_CLIENT_EXISTING = exports.RETRIEVE_CLIENT_DEFAULT = exports.CLEANUP_DEREGISTERING = exports.CLEANUP_REGISTERING = exports.ENGINE_SANITIZE = exports.ENGINE_VALUE = exports.ENGINE_MATCHER_WHITELIST = exports.ENGINE_MATCHER_STARTS_WITH = exports.ENGINE_MATCHER_STRING_INVALID = exports.ENGINE_MATCHER_STRING = exports.ENGINE_MATCHER_SEGMENT = exports.ENGINE_MATCHER_PART_OF = exports.ENGINE_MATCHER_LESS = exports.ENGINE_MATCHER_GREATER = exports.ENGINE_MATCHER_ENDS_WITH = exports.ENGINE_MATCHER_EQUAL_TO_SET = exports.ENGINE_MATCHER_EQUAL = exports.ENGINE_MATCHER_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_MATCHER_CONTAINS_STRING = exports.ENGINE_MATCHER_CONTAINS_ANY = exports.ENGINE_MATCHER_CONTAINS_ALL = exports.ENGINE_MATCHER_BOOLEAN = exports.ENGINE_MATCHER_BETWEEN = exports.ENGINE_MATCHER_ALL = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
|
|
4
|
-
exports.
|
|
5
|
-
exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.
|
|
4
|
+
exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = exports.ERROR_EVENT_TYPE_FORMAT = exports.ERROR_EVENTS_TRACKER = exports.ERROR_IMPRESSIONS_LISTENER = exports.ERROR_IMPRESSIONS_TRACKER = exports.ERROR_STREAMING_AUTH = exports.ERROR_STREAMING_SSE = exports.ERROR_SYNC_OFFLINE_LOADING = exports.ERROR_CLIENT_CANNOT_GET_READY = exports.ERROR_CLIENT_LISTENER = exports.ERROR_LOGLEVEL_INVALID = exports.ERROR_ENGINE_COMBINER_IFELSEIF = exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = exports.WARN_API_KEY = exports.WARN_SPLITS_FILTER_EMPTY = exports.WARN_SPLITS_FILTER_INVALID = exports.WARN_SPLITS_FILTER_IGNORED = exports.WARN_INTEGRATION_INVALID = exports.WARN_NOT_EXISTENT_TT = exports.WARN_LOWERCASE_TRAFFIC_TYPE = exports.WARN_NOT_EXISTENT_SPLIT = exports.WARN_TRIMMING = exports.WARN_CONVERTING = exports.WARN_TRIMMING_PROPERTIES = exports.WARN_SETTING_NULL = exports.SUBMITTERS_PUSH_RETRY = exports.SUBMITTERS_PUSH_FAILS = exports.STREAMING_FALLBACK = exports.STREAMING_PARSING_MESSAGE_FAILS = exports.STREAMING_PARSING_ERROR_FAILS = exports.SYNC_SPLITS_FETCH_FAILS = exports.SYNC_MYSEGMENTS_FETCH_RETRY = exports.CLIENT_NOT_READY = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = void 0;
|
|
5
|
+
exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_EVENTS_TRACKER = exports.LOG_PREFIX_IMPRESSIONS_TRACKER = exports.LOG_PREFIX_SYNC_SUBMITTERS = exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC = exports.LOG_PREFIX_ENGINE_VALUE = exports.LOG_PREFIX_ENGINE_MATCHER = exports.LOG_PREFIX_ENGINE_COMBINER = exports.LOG_PREFIX_ENGINE = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_LOCALHOST_MODULE_REQUIRED = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* Message codes used to trim string log messages from commons and client-side API modules,
|
|
8
8
|
* in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
|
|
@@ -72,6 +72,7 @@ exports.SYNC_CONTINUE_POLLING = 118;
|
|
|
72
72
|
exports.SYNC_STOP_POLLING = 119;
|
|
73
73
|
exports.EVENTS_TRACKER_SUCCESS = 120;
|
|
74
74
|
exports.IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
75
|
+
exports.USER_CONSENT_UPDATED = 122;
|
|
75
76
|
exports.ENGINE_VALUE_INVALID = 200;
|
|
76
77
|
exports.ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
77
78
|
exports.CLIENT_NO_LISTENER = 202;
|
|
@@ -117,10 +118,11 @@ exports.ERROR_INVALID_KEY_OBJECT = 317;
|
|
|
117
118
|
exports.ERROR_INVALID = 318;
|
|
118
119
|
exports.ERROR_EMPTY = 319;
|
|
119
120
|
exports.ERROR_EMPTY_ARRAY = 320;
|
|
120
|
-
exports.
|
|
121
|
+
exports.ERROR_INVALID_CONFIG_PARAM = 321;
|
|
121
122
|
exports.ERROR_HTTP = 322;
|
|
122
123
|
exports.ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
123
124
|
exports.ERROR_STORAGE_INVALID = 324;
|
|
125
|
+
exports.ERROR_NOT_BOOLEAN = 325;
|
|
124
126
|
// Log prefixes (a.k.a. tags or categories)
|
|
125
127
|
exports.LOG_PREFIX_SETTINGS = 'settings';
|
|
126
128
|
exports.LOG_PREFIX_INSTANTIATION = 'Factory instantiation';
|
|
@@ -31,8 +31,9 @@ exports.codesError = [
|
|
|
31
31
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
32
32
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
33
33
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
34
|
+
[c.ERROR_NOT_BOOLEAN, '%s: you must provide a boolean param.'],
|
|
34
35
|
// initialization / settings validation
|
|
35
|
-
[c.
|
|
36
|
+
[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".'],
|
|
36
37
|
[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.'],
|
|
37
38
|
[c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': The provided storage is invalid.%s Fallbacking into default MEMORY storage'],
|
|
38
39
|
];
|
|
@@ -16,6 +16,7 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
16
16
|
[c.NEW_FACTORY, ' New Split SDK instance created.'],
|
|
17
17
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
18
18
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
19
|
+
[c.USER_CONSENT_UPDATED, 'User consent changed from %s to %s.'],
|
|
19
20
|
// synchronizer
|
|
20
21
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
21
22
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -14,13 +14,15 @@ var constants_2 = require("../logger/constants");
|
|
|
14
14
|
*/
|
|
15
15
|
// @TODO missing time tracking to collect telemetry
|
|
16
16
|
function clientFactory(params) {
|
|
17
|
-
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage,
|
|
17
|
+
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker;
|
|
18
|
+
var log = settings.log, mode = settings.mode;
|
|
18
19
|
function getTreatment(key, splitName, attributes, withConfig) {
|
|
19
20
|
if (withConfig === void 0) { withConfig = false; }
|
|
20
21
|
var wrapUp = function (evaluationResult) {
|
|
21
22
|
var queue = [];
|
|
22
23
|
var treatment = processEvaluation(evaluationResult, splitName, key, attributes, withConfig, "getTreatment" + (withConfig ? 'withConfig' : ''), queue);
|
|
23
|
-
|
|
24
|
+
if (settings.userConsent !== constants_1.CONSENT_DECLINED)
|
|
25
|
+
impressionsTracker.track(queue, attributes);
|
|
24
26
|
return treatment;
|
|
25
27
|
};
|
|
26
28
|
var evaluation = (0, evaluator_1.evaluateFeature)(log, key, splitName, attributes, storage);
|
|
@@ -37,7 +39,8 @@ function clientFactory(params) {
|
|
|
37
39
|
Object.keys(evaluationResults).forEach(function (splitName) {
|
|
38
40
|
treatments[splitName] = processEvaluation(evaluationResults[splitName], splitName, key, attributes, withConfig, "getTreatments" + (withConfig ? 'withConfig' : ''), queue);
|
|
39
41
|
});
|
|
40
|
-
|
|
42
|
+
if (settings.userConsent !== constants_1.CONSENT_DECLINED)
|
|
43
|
+
impressionsTracker.track(queue, attributes);
|
|
41
44
|
return treatments;
|
|
42
45
|
};
|
|
43
46
|
var evaluations = (0, evaluator_1.evaluateFeatures)(log, key, splitNames, attributes, storage);
|
|
@@ -91,7 +94,10 @@ function clientFactory(params) {
|
|
|
91
94
|
};
|
|
92
95
|
// 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.
|
|
93
96
|
(0, trafficTypeExistance_1.validateTrafficTypeExistance)(log, readinessManager, storage.splits, mode, trafficTypeName, 'track');
|
|
94
|
-
|
|
97
|
+
if (settings.userConsent !== constants_1.CONSENT_DECLINED)
|
|
98
|
+
return eventTracker.track(eventData, size);
|
|
99
|
+
else
|
|
100
|
+
return false;
|
|
95
101
|
}
|
|
96
102
|
return {
|
|
97
103
|
getTreatment: getTreatment,
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -11,11 +11,12 @@ var sdkLogger_1 = require("../logger/sdkLogger");
|
|
|
11
11
|
var constants_1 = require("../logger/constants");
|
|
12
12
|
var metadataBuilder_1 = require("../storages/metadataBuilder");
|
|
13
13
|
var constants_2 = require("../readiness/constants");
|
|
14
|
+
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
14
15
|
/**
|
|
15
16
|
* Modular SDK factory
|
|
16
17
|
*/
|
|
17
18
|
function sdkFactory(params) {
|
|
18
|
-
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, impressionListener = params.impressionListener, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory;
|
|
19
|
+
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory, extraProps = params.extraProps, syncManagerFactory = params.syncManagerFactory, SignalListener = params.SignalListener, impressionsObserverFactory = params.impressionsObserverFactory, impressionListener = params.impressionListener, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory;
|
|
19
20
|
var log = settings.log;
|
|
20
21
|
// @TODO handle non-recoverable errors: not start sync, mark the SDK as destroyed, etc.
|
|
21
22
|
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
@@ -68,11 +69,11 @@ function sdkFactory(params) {
|
|
|
68
69
|
syncManager && syncManager.start();
|
|
69
70
|
signalListener && signalListener.start();
|
|
70
71
|
log.info(constants_1.NEW_FACTORY);
|
|
71
|
-
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
return (0, objectAssign_1.objectAssign)({
|
|
72
74
|
// Split evaluation and event tracking engine
|
|
73
75
|
client: clientMethod,
|
|
74
76
|
// Manager API to explore available information
|
|
75
|
-
// @ts-ignore
|
|
76
77
|
manager: function () {
|
|
77
78
|
log.debug(constants_1.RETRIEVE_MANAGER);
|
|
78
79
|
return managerInstance;
|
|
@@ -80,6 +81,6 @@ function sdkFactory(params) {
|
|
|
80
81
|
// Logger wrapper API
|
|
81
82
|
Logger: (0, sdkLogger_1.createLoggerAPI)(settings.log),
|
|
82
83
|
settings: settings,
|
|
83
|
-
};
|
|
84
|
+
}, extraProps && extraProps(settings, syncManager));
|
|
84
85
|
}
|
|
85
86
|
exports.sdkFactory = sdkFactory;
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.userConsentProps = void 0;
|
|
4
|
+
var constants_1 = require("../logger/constants");
|
|
5
|
+
var constants_2 = require("../utils/constants");
|
|
6
|
+
// Extend client-side factory instances with user consent getter/setter
|
|
7
|
+
function userConsentProps(settings, syncManager) {
|
|
8
|
+
var log = settings.log;
|
|
9
|
+
return {
|
|
10
|
+
setUserConsent: function (consent) {
|
|
11
|
+
var _a, _b;
|
|
12
|
+
// validate input param
|
|
13
|
+
if (typeof consent !== 'boolean') {
|
|
14
|
+
log.error(constants_1.ERROR_NOT_BOOLEAN, ['setUserConsent']);
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
var newConsentStatus = consent ? constants_2.CONSENT_GRANTED : constants_2.CONSENT_DECLINED;
|
|
18
|
+
if (settings.userConsent !== newConsentStatus) {
|
|
19
|
+
// resume/pause submitters
|
|
20
|
+
if (consent)
|
|
21
|
+
(_a = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _a === void 0 ? void 0 : _a.start();
|
|
22
|
+
else
|
|
23
|
+
(_b = syncManager === null || syncManager === void 0 ? void 0 : syncManager.submitter) === null || _b === void 0 ? void 0 : _b.stop();
|
|
24
|
+
log.info(constants_1.USER_CONSENT_UPDATED, [settings.userConsent, newConsentStatus]); // @ts-ignore, modify readonly prop
|
|
25
|
+
settings.userConsent = newConsentStatus;
|
|
26
|
+
}
|
|
27
|
+
return true;
|
|
28
|
+
},
|
|
29
|
+
getUserConsent: function () {
|
|
30
|
+
return settings.userConsent;
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
exports.userConsentProps = userConsentProps;
|
|
@@ -16,9 +16,19 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
16
16
|
* @override
|
|
17
17
|
*/
|
|
18
18
|
KeyBuilderCS.prototype.buildSegmentNameKey = function (segmentName) {
|
|
19
|
-
return this.
|
|
19
|
+
return this.prefix + "." + this.matchingKey + ".segment." + segmentName;
|
|
20
20
|
};
|
|
21
21
|
KeyBuilderCS.prototype.extractSegmentName = function (builtSegmentKeyName) {
|
|
22
|
+
var prefix = this.prefix + "." + this.matchingKey + ".segment.";
|
|
23
|
+
if ((0, lang_1.startsWith)(builtSegmentKeyName, prefix))
|
|
24
|
+
return builtSegmentKeyName.substr(prefix.length);
|
|
25
|
+
};
|
|
26
|
+
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
27
|
+
KeyBuilderCS.prototype.buildOldSegmentNameKey = function (segmentName) {
|
|
28
|
+
return this.matchingKey + "." + this.prefix + ".segment." + segmentName;
|
|
29
|
+
};
|
|
30
|
+
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
31
|
+
KeyBuilderCS.prototype.extractOldSegmentKey = function (builtSegmentKeyName) {
|
|
22
32
|
var prefix = this.matchingKey + "." + this.prefix + ".segment.";
|
|
23
33
|
if ((0, lang_1.startsWith)(builtSegmentKeyName, prefix))
|
|
24
34
|
return builtSegmentKeyName.substr(prefix.length);
|
|
@@ -60,9 +60,29 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
|
|
|
60
60
|
var index;
|
|
61
61
|
// Scan current values from localStorage
|
|
62
62
|
var storedSegmentNames = Object.keys(localStorage).reduce(function (accum, key) {
|
|
63
|
-
var
|
|
64
|
-
if (
|
|
65
|
-
accum.push(
|
|
63
|
+
var segmentName = _this.keys.extractSegmentName(key);
|
|
64
|
+
if (segmentName) {
|
|
65
|
+
accum.push(segmentName);
|
|
66
|
+
}
|
|
67
|
+
else {
|
|
68
|
+
// @BREAKING: This is only to clean up "old" keys. Remove this whole else code block.
|
|
69
|
+
segmentName = _this.keys.extractOldSegmentKey(key);
|
|
70
|
+
if (segmentName) { // this was an old segment key, let's clean up.
|
|
71
|
+
var newSegmentKey = _this.keys.buildSegmentNameKey(segmentName);
|
|
72
|
+
try {
|
|
73
|
+
// If the new format key is not there, create it.
|
|
74
|
+
if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) {
|
|
75
|
+
localStorage.setItem(newSegmentKey, constants_1.DEFINED);
|
|
76
|
+
// we are migrating a segment, let's track it.
|
|
77
|
+
accum.push(segmentName);
|
|
78
|
+
}
|
|
79
|
+
localStorage.removeItem(key); // we migrated the current key, let's delete it.
|
|
80
|
+
}
|
|
81
|
+
catch (e) {
|
|
82
|
+
_this.log.error(e);
|
|
83
|
+
}
|
|
84
|
+
}
|
|
85
|
+
}
|
|
66
86
|
return accum;
|
|
67
87
|
}, []);
|
|
68
88
|
// Extreme fast => everything is empty
|
|
@@ -25,8 +25,12 @@ function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate,
|
|
|
25
25
|
}
|
|
26
26
|
// register events submitter to be executed when events cache is full
|
|
27
27
|
eventsCache.setOnFullQueueCb(function () {
|
|
28
|
-
|
|
29
|
-
|
|
28
|
+
if (syncTask.isRunning()) {
|
|
29
|
+
log.info(constants_1.SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
30
|
+
syncTask.execute();
|
|
31
|
+
}
|
|
32
|
+
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
33
|
+
// Data will be sent when submitter is resumed.
|
|
30
34
|
});
|
|
31
35
|
return syncTask;
|
|
32
36
|
}
|
|
@@ -41,8 +41,12 @@ function impressionsSyncTaskFactory(log, postTestImpressionsBulk, impressionsCac
|
|
|
41
41
|
var syncTask = (0, submitterSyncTask_1.submitterSyncTaskFactory)(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, DATA_NAME, latencyTracker, fromImpressionsCollector.bind(undefined, sendLabels), 1);
|
|
42
42
|
// register impressions submitter to be executed when impressions cache is full
|
|
43
43
|
impressionsCache.setOnFullQueueCb(function () {
|
|
44
|
-
|
|
45
|
-
|
|
44
|
+
if (syncTask.isRunning()) {
|
|
45
|
+
log.info(constants_1.SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
46
|
+
syncTask.execute();
|
|
47
|
+
}
|
|
48
|
+
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
49
|
+
// Data will be sent when submitter is resumed.
|
|
46
50
|
});
|
|
47
51
|
return syncTask;
|
|
48
52
|
}
|
|
@@ -4,6 +4,7 @@ exports.syncManagerOnlineFactory = void 0;
|
|
|
4
4
|
var submitterManager_1 = require("./submitters/submitterManager");
|
|
5
5
|
var constants_1 = require("./streaming/constants");
|
|
6
6
|
var constants_2 = require("../logger/constants");
|
|
7
|
+
var consent_1 = require("../utils/consent");
|
|
7
8
|
/**
|
|
8
9
|
* Online SyncManager factory.
|
|
9
10
|
* Can be used for server-side API, and client-side API with or without multiple clients.
|
|
@@ -17,7 +18,7 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
|
|
|
17
18
|
* SyncManager factory for modular SDK
|
|
18
19
|
*/
|
|
19
20
|
return function (params) {
|
|
20
|
-
var _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled;
|
|
21
|
+
var settings = params.settings, _a = params.settings, log = _a.log, streamingEnabled = _a.streamingEnabled;
|
|
21
22
|
/** Polling Manager */
|
|
22
23
|
var pollingManager = pollingManagerFactory && pollingManagerFactory(params);
|
|
23
24
|
/** Push Manager */
|
|
@@ -52,11 +53,16 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
|
|
|
52
53
|
var running = false; // flag that indicates whether the syncManager has been started (true) or stopped (false)
|
|
53
54
|
var startFirstTime = true; // flag to distinguish calling the `start` method for the first time, to support pausing and resuming the synchronization
|
|
54
55
|
return {
|
|
56
|
+
// Exposed for fine-grained control of synchronization.
|
|
57
|
+
// E.g.: user consent, app state changes (Page hide, Foreground/Background, Online/Offline).
|
|
58
|
+
pollingManager: pollingManager,
|
|
55
59
|
pushManager: pushManager,
|
|
60
|
+
submitter: submitter,
|
|
56
61
|
/**
|
|
57
62
|
* Method used to start the syncManager for the first time, or resume it after being stopped.
|
|
58
63
|
*/
|
|
59
64
|
start: function () {
|
|
65
|
+
running = true;
|
|
60
66
|
// start syncing splits and segments
|
|
61
67
|
if (pollingManager) {
|
|
62
68
|
if (pushManager) {
|
|
@@ -72,29 +78,27 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
|
|
|
72
78
|
}
|
|
73
79
|
}
|
|
74
80
|
// start periodic data recording (events, impressions, telemetry).
|
|
75
|
-
if (
|
|
81
|
+
if ((0, consent_1.isConsentGranted)(settings))
|
|
76
82
|
submitter.start();
|
|
77
|
-
running = true;
|
|
78
83
|
},
|
|
79
84
|
/**
|
|
80
85
|
* Method used to stop/pause the syncManager.
|
|
81
86
|
*/
|
|
82
87
|
stop: function () {
|
|
88
|
+
running = false;
|
|
83
89
|
// stop syncing
|
|
84
90
|
if (pushManager)
|
|
85
91
|
pushManager.stop();
|
|
86
92
|
if (pollingManager && pollingManager.isRunning())
|
|
87
93
|
pollingManager.stop();
|
|
88
94
|
// stop periodic data recording (events, impressions, telemetry).
|
|
89
|
-
|
|
90
|
-
submitter.stop();
|
|
91
|
-
running = false;
|
|
95
|
+
submitter.stop();
|
|
92
96
|
},
|
|
93
97
|
isRunning: function () {
|
|
94
98
|
return running;
|
|
95
99
|
},
|
|
96
100
|
flush: function () {
|
|
97
|
-
if (
|
|
101
|
+
if ((0, consent_1.isConsentGranted)(settings))
|
|
98
102
|
return submitter.execute();
|
|
99
103
|
else
|
|
100
104
|
return Promise.resolve();
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.isConsentGranted = void 0;
|
|
4
|
+
var constants_1 = require("./constants");
|
|
5
|
+
function isConsentGranted(settings) {
|
|
6
|
+
var userConsent = settings.userConsent;
|
|
7
|
+
// undefined userConsent is handled as granted (default)
|
|
8
|
+
return !userConsent || userConsent === constants_1.CONSENT_GRANTED;
|
|
9
|
+
}
|
|
10
|
+
exports.isConsentGranted = isConsentGranted;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.STORAGE_PLUGGABLE = exports.STORAGE_REDIS = exports.STORAGE_LOCALSTORAGE = exports.STORAGE_MEMORY = exports.CONSUMER_PARTIAL_MODE = exports.CONSUMER_MODE = exports.PRODUCER_MODE = exports.STANDALONE_MODE = exports.LOCALHOST_MODE = exports.OPTIMIZED = exports.DEBUG = exports.SPLIT_EVENT = exports.SPLIT_IMPRESSION = exports.NA = exports.UNKNOWN = exports.CONTROL_WITH_CONFIG = exports.CONTROL = void 0;
|
|
3
|
+
exports.CONSENT_UNKNOWN = exports.CONSENT_DECLINED = exports.CONSENT_GRANTED = exports.STORAGE_PLUGGABLE = exports.STORAGE_REDIS = exports.STORAGE_LOCALSTORAGE = exports.STORAGE_MEMORY = exports.CONSUMER_PARTIAL_MODE = exports.CONSUMER_MODE = exports.PRODUCER_MODE = exports.STANDALONE_MODE = exports.LOCALHOST_MODE = exports.OPTIMIZED = exports.DEBUG = exports.SPLIT_EVENT = exports.SPLIT_IMPRESSION = exports.NA = exports.UNKNOWN = exports.CONTROL_WITH_CONFIG = exports.CONTROL = void 0;
|
|
4
4
|
// Special treatments
|
|
5
5
|
exports.CONTROL = 'control';
|
|
6
6
|
exports.CONTROL_WITH_CONFIG = {
|
|
@@ -27,3 +27,7 @@ exports.STORAGE_MEMORY = 'MEMORY';
|
|
|
27
27
|
exports.STORAGE_LOCALSTORAGE = 'LOCALSTORAGE';
|
|
28
28
|
exports.STORAGE_REDIS = 'REDIS';
|
|
29
29
|
exports.STORAGE_PLUGGABLE = 'PLUGGABLE';
|
|
30
|
+
// User consent
|
|
31
|
+
exports.CONSENT_GRANTED = 'GRANTED'; // The user has granted consent for tracking events and impressions
|
|
32
|
+
exports.CONSENT_DECLINED = 'DECLINED'; // The user has declined consent for tracking events and impressions
|
|
33
|
+
exports.CONSENT_UNKNOWN = 'UNKNOWN'; // The user has neither granted nor declined consent for tracking events and impressions
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.validateConsent = void 0;
|
|
4
|
+
var constants_1 = require("../../logger/constants");
|
|
5
|
+
var constants_2 = require("../constants");
|
|
6
|
+
var userConsentValues = [constants_2.CONSENT_DECLINED, constants_2.CONSENT_GRANTED, constants_2.CONSENT_UNKNOWN];
|
|
7
|
+
function validateConsent(_a) {
|
|
8
|
+
var userConsent = _a.userConsent, log = _a.log;
|
|
9
|
+
if (typeof userConsent === 'string')
|
|
10
|
+
userConsent = userConsent.toUpperCase();
|
|
11
|
+
if (userConsentValues.indexOf(userConsent) > -1)
|
|
12
|
+
return userConsent;
|
|
13
|
+
log.error(constants_1.ERROR_INVALID_CONFIG_PARAM, ['userConsent', userConsentValues, constants_2.CONSENT_GRANTED]);
|
|
14
|
+
return constants_2.CONSENT_GRANTED;
|
|
15
|
+
}
|
|
16
|
+
exports.validateConsent = validateConsent;
|
|
@@ -4,11 +4,11 @@ exports.validImpressionsMode = void 0;
|
|
|
4
4
|
var constants_1 = require("../../logger/constants");
|
|
5
5
|
var constants_2 = require("../constants");
|
|
6
6
|
function validImpressionsMode(log, impressionsMode) {
|
|
7
|
-
impressionsMode
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
impressionsMode
|
|
11
|
-
|
|
12
|
-
return
|
|
7
|
+
if (typeof impressionsMode === 'string')
|
|
8
|
+
impressionsMode = impressionsMode.toUpperCase();
|
|
9
|
+
if ([constants_2.DEBUG, constants_2.OPTIMIZED].indexOf(impressionsMode) > -1)
|
|
10
|
+
return impressionsMode;
|
|
11
|
+
log.error(constants_1.ERROR_INVALID_CONFIG_PARAM, ['impressionsMode', [constants_2.DEBUG, constants_2.OPTIMIZED], constants_2.OPTIMIZED]);
|
|
12
|
+
return constants_2.OPTIMIZED;
|
|
13
13
|
}
|
|
14
14
|
exports.validImpressionsMode = validImpressionsMode;
|
|
@@ -83,7 +83,7 @@ function fromSecondsToMillis(n) {
|
|
|
83
83
|
* @param validationParams defaults and fields validators used to validate and creates a settings object from a given config
|
|
84
84
|
*/
|
|
85
85
|
function settingsValidation(config, validationParams) {
|
|
86
|
-
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost;
|
|
86
|
+
var defaults = validationParams.defaults, runtime = validationParams.runtime, storage = validationParams.storage, integrations = validationParams.integrations, logger = validationParams.logger, localhost = validationParams.localhost, consent = validationParams.consent;
|
|
87
87
|
// creates a settings object merging base, defaults and config objects.
|
|
88
88
|
var withDefaults = (0, lang_1.merge)({}, base, defaults, config);
|
|
89
89
|
// ensure a valid logger.
|
|
@@ -136,6 +136,9 @@ function settingsValidation(config, validationParams) {
|
|
|
136
136
|
withDefaults.sync.__splitFiltersValidation = splitFiltersValidation;
|
|
137
137
|
// ensure a valid impressionsMode
|
|
138
138
|
withDefaults.sync.impressionsMode = (0, impressionsMode_1.validImpressionsMode)(log, withDefaults.sync.impressionsMode);
|
|
139
|
+
// ensure a valid user consent value
|
|
140
|
+
// @ts-ignore, modify readonly prop
|
|
141
|
+
withDefaults.userConsent = consent(withDefaults);
|
|
139
142
|
return withDefaults;
|
|
140
143
|
}
|
|
141
144
|
exports.settingsValidation = settingsValidation;
|
package/esm/listeners/browser.js
CHANGED
|
@@ -3,6 +3,7 @@ import { fromImpressionCountsCollector } from '../sync/submitters/impressionCoun
|
|
|
3
3
|
import { OPTIMIZED, DEBUG } from '../utils/constants';
|
|
4
4
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
5
5
|
import { CLEANUP_REGISTERING, CLEANUP_DEREGISTERING } from '../logger/constants';
|
|
6
|
+
import { isConsentGranted } from '../utils/consent';
|
|
6
7
|
// 'unload' event is used instead of 'beforeunload', since 'unload' is not a cancelable event, so no other listeners can stop the event from occurring.
|
|
7
8
|
var UNLOAD_DOM_EVENT = 'unload';
|
|
8
9
|
var EVENT_NAME = 'for unload page event.';
|
|
@@ -48,15 +49,18 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
48
49
|
BrowserSignalListener.prototype.flushData = function () {
|
|
49
50
|
if (!this.syncManager)
|
|
50
51
|
return; // In consumer mode there is not sync manager and data to flush
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
this._flushData(eventsUrl + '/
|
|
52
|
+
// Flush data if there is user consent
|
|
53
|
+
if (isConsentGranted(this.settings)) {
|
|
54
|
+
var eventsUrl = this.settings.urls.events;
|
|
55
|
+
var extraMetadata = {
|
|
56
|
+
// sim stands for Sync/Split Impressions Mode
|
|
57
|
+
sim: this.settings.sync.impressionsMode === OPTIMIZED ? OPTIMIZED : DEBUG
|
|
58
|
+
};
|
|
59
|
+
this._flushData(eventsUrl + '/testImpressions/beacon', this.storage.impressions, this.serviceApi.postTestImpressionsBulk, this.fromImpressionsCollector, extraMetadata);
|
|
60
|
+
this._flushData(eventsUrl + '/events/beacon', this.storage.events, this.serviceApi.postEventsBulk);
|
|
61
|
+
if (this.storage.impressionCounts)
|
|
62
|
+
this._flushData(eventsUrl + '/testImpressions/count/beacon', this.storage.impressionCounts, this.serviceApi.postTestImpressionsCount, fromImpressionCountsCollector);
|
|
63
|
+
}
|
|
60
64
|
// Close streaming connection
|
|
61
65
|
if (this.syncManager.pushManager)
|
|
62
66
|
this.syncManager.pushManager.stop();
|
|
@@ -66,7 +70,7 @@ var BrowserSignalListener = /** @class */ (function () {
|
|
|
66
70
|
if (!cache.isEmpty()) {
|
|
67
71
|
var dataPayload = fromCacheToPayload ? fromCacheToPayload(cache.state()) : cache.state();
|
|
68
72
|
if (!this._sendBeacon(url, dataPayload, extraMetadata)) {
|
|
69
|
-
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible
|
|
73
|
+
postService(JSON.stringify(dataPayload)).catch(function () { }); // no-op just to catch a possible exception
|
|
70
74
|
}
|
|
71
75
|
cache.clear();
|
|
72
76
|
}
|
package/esm/logger/constants.js
CHANGED
|
@@ -67,6 +67,7 @@ export var SYNC_CONTINUE_POLLING = 118;
|
|
|
67
67
|
export var SYNC_STOP_POLLING = 119;
|
|
68
68
|
export var EVENTS_TRACKER_SUCCESS = 120;
|
|
69
69
|
export var IMPRESSIONS_TRACKER_SUCCESS = 121;
|
|
70
|
+
export var USER_CONSENT_UPDATED = 122;
|
|
70
71
|
export var ENGINE_VALUE_INVALID = 200;
|
|
71
72
|
export var ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
72
73
|
export var CLIENT_NO_LISTENER = 202;
|
|
@@ -112,10 +113,11 @@ export var ERROR_INVALID_KEY_OBJECT = 317;
|
|
|
112
113
|
export var ERROR_INVALID = 318;
|
|
113
114
|
export var ERROR_EMPTY = 319;
|
|
114
115
|
export var ERROR_EMPTY_ARRAY = 320;
|
|
115
|
-
export var
|
|
116
|
+
export var ERROR_INVALID_CONFIG_PARAM = 321;
|
|
116
117
|
export var ERROR_HTTP = 322;
|
|
117
118
|
export var ERROR_LOCALHOST_MODULE_REQUIRED = 323;
|
|
118
119
|
export var ERROR_STORAGE_INVALID = 324;
|
|
120
|
+
export var ERROR_NOT_BOOLEAN = 325;
|
|
119
121
|
// Log prefixes (a.k.a. tags or categories)
|
|
120
122
|
export var LOG_PREFIX_SETTINGS = 'settings';
|
|
121
123
|
export var LOG_PREFIX_INSTANTIATION = 'Factory instantiation';
|
|
@@ -27,8 +27,9 @@ export var codesError = [
|
|
|
27
27
|
[c.ERROR_INVALID, '%s: you passed an invalid %s. It must be a non-empty string.'],
|
|
28
28
|
[c.ERROR_EMPTY, '%s: you passed an empty %s. It must be a non-empty string.'],
|
|
29
29
|
[c.ERROR_EMPTY_ARRAY, '%s: %s must be a non-empty array.'],
|
|
30
|
+
[c.ERROR_NOT_BOOLEAN, '%s: you must provide a boolean param.'],
|
|
30
31
|
// initialization / settings validation
|
|
31
|
-
[c.
|
|
32
|
+
[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".'],
|
|
32
33
|
[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.'],
|
|
33
34
|
[c.ERROR_STORAGE_INVALID, c.LOG_PREFIX_SETTINGS + ': The provided storage is invalid.%s Fallbacking into default MEMORY storage'],
|
|
34
35
|
];
|
|
@@ -12,6 +12,7 @@ export var codesInfo = codesWarn.concat([
|
|
|
12
12
|
[c.NEW_FACTORY, ' New Split SDK instance created.'],
|
|
13
13
|
[c.EVENTS_TRACKER_SUCCESS, c.LOG_PREFIX_EVENTS_TRACKER + 'Successfully queued %s'],
|
|
14
14
|
[c.IMPRESSIONS_TRACKER_SUCCESS, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Successfully stored %s impression(s).'],
|
|
15
|
+
[c.USER_CONSENT_UPDATED, 'User consent changed from %s to %s.'],
|
|
15
16
|
// synchronizer
|
|
16
17
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
17
18
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
package/esm/sdkClient/client.js
CHANGED
|
@@ -4,20 +4,22 @@ 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 { IMPRESSION, IMPRESSION_QUEUEING } from '../logger/constants';
|
|
9
9
|
/**
|
|
10
10
|
* Creator of base client with getTreatments and track methods.
|
|
11
11
|
*/
|
|
12
12
|
// @TODO missing time tracking to collect telemetry
|
|
13
13
|
export function clientFactory(params) {
|
|
14
|
-
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage,
|
|
14
|
+
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker;
|
|
15
|
+
var log = settings.log, mode = settings.mode;
|
|
15
16
|
function getTreatment(key, splitName, attributes, withConfig) {
|
|
16
17
|
if (withConfig === void 0) { withConfig = false; }
|
|
17
18
|
var wrapUp = function (evaluationResult) {
|
|
18
19
|
var queue = [];
|
|
19
20
|
var treatment = processEvaluation(evaluationResult, splitName, key, attributes, withConfig, "getTreatment" + (withConfig ? 'withConfig' : ''), queue);
|
|
20
|
-
|
|
21
|
+
if (settings.userConsent !== CONSENT_DECLINED)
|
|
22
|
+
impressionsTracker.track(queue, attributes);
|
|
21
23
|
return treatment;
|
|
22
24
|
};
|
|
23
25
|
var evaluation = evaluateFeature(log, key, splitName, attributes, storage);
|
|
@@ -34,7 +36,8 @@ export function clientFactory(params) {
|
|
|
34
36
|
Object.keys(evaluationResults).forEach(function (splitName) {
|
|
35
37
|
treatments[splitName] = processEvaluation(evaluationResults[splitName], splitName, key, attributes, withConfig, "getTreatments" + (withConfig ? 'withConfig' : ''), queue);
|
|
36
38
|
});
|
|
37
|
-
|
|
39
|
+
if (settings.userConsent !== CONSENT_DECLINED)
|
|
40
|
+
impressionsTracker.track(queue, attributes);
|
|
38
41
|
return treatments;
|
|
39
42
|
};
|
|
40
43
|
var evaluations = evaluateFeatures(log, key, splitNames, attributes, storage);
|
|
@@ -88,7 +91,10 @@ export function clientFactory(params) {
|
|
|
88
91
|
};
|
|
89
92
|
// 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.
|
|
90
93
|
validateTrafficTypeExistance(log, readinessManager, storage.splits, mode, trafficTypeName, 'track');
|
|
91
|
-
|
|
94
|
+
if (settings.userConsent !== CONSENT_DECLINED)
|
|
95
|
+
return eventTracker.track(eventData, size);
|
|
96
|
+
else
|
|
97
|
+
return false;
|
|
92
98
|
}
|
|
93
99
|
return {
|
|
94
100
|
getTreatment: getTreatment,
|