@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
|
@@ -4,8 +4,10 @@ exports.GoogleAnalyticsToSplit = void 0;
|
|
|
4
4
|
var GaToSplit_1 = require("./GaToSplit");
|
|
5
5
|
function GoogleAnalyticsToSplit(options) {
|
|
6
6
|
// GaToSplit integration factory
|
|
7
|
-
|
|
7
|
+
function GoogleAnalyticsToSplitFactory(params) {
|
|
8
8
|
return (0, GaToSplit_1.GaToSplit)(options, params);
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
|
+
GoogleAnalyticsToSplitFactory.type = 'GOOGLE_ANALYTICS_TO_SPLIT';
|
|
11
|
+
return GoogleAnalyticsToSplitFactory;
|
|
10
12
|
}
|
|
11
13
|
exports.GoogleAnalyticsToSplit = GoogleAnalyticsToSplit;
|
|
@@ -5,8 +5,10 @@ var SplitToGa_1 = require("./SplitToGa");
|
|
|
5
5
|
function SplitToGoogleAnalytics(options) {
|
|
6
6
|
if (options === void 0) { options = {}; }
|
|
7
7
|
// SplitToGa integration factory
|
|
8
|
-
|
|
8
|
+
function SplitToGoogleAnalyticsFactory(params) {
|
|
9
9
|
return new SplitToGa_1.SplitToGa(params.settings.log, options);
|
|
10
|
-
}
|
|
10
|
+
}
|
|
11
|
+
SplitToGoogleAnalyticsFactory.type = 'SPLIT_TO_GOOGLE_ANALYTICS';
|
|
12
|
+
return SplitToGoogleAnalyticsFactory;
|
|
11
13
|
}
|
|
12
14
|
exports.SplitToGoogleAnalytics = SplitToGoogleAnalytics;
|
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.
|
|
@@ -65,13 +65,14 @@ exports.STREAMING_RECONNECT = 111;
|
|
|
65
65
|
exports.STREAMING_CONNECTING = 112;
|
|
66
66
|
exports.STREAMING_DISABLED = 113;
|
|
67
67
|
exports.STREAMING_DISCONNECTING = 114;
|
|
68
|
-
exports.
|
|
68
|
+
exports.SUBMITTERS_PUSH_FULL_QUEUE = 115;
|
|
69
69
|
exports.SUBMITTERS_PUSH = 116;
|
|
70
70
|
exports.SYNC_START_POLLING = 117;
|
|
71
71
|
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';
|
|
@@ -16,7 +16,7 @@ exports.codesError = [
|
|
|
16
16
|
[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'],
|
|
17
17
|
[c.ERROR_STREAMING_SSE, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to connect or error on streaming connection, with error message: %s'],
|
|
18
18
|
[c.ERROR_STREAMING_AUTH, c.LOG_PREFIX_SYNC_STREAMING + 'Failed to authenticate for streaming. Error: %s.'],
|
|
19
|
-
[c.ERROR_HTTP, '
|
|
19
|
+
[c.ERROR_HTTP, 'Response status is not OK. Status: %s. URL: %s. Message: %s'],
|
|
20
20
|
// client status
|
|
21
21
|
[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.'],
|
|
22
22
|
[c.ERROR_CLIENT_DESTROYED, '%s: Client has already been destroyed - no calls possible.'],
|
|
@@ -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,12 +16,13 @@ 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'],
|
|
22
23
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
23
24
|
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of splits #%s. Reason: %s'],
|
|
24
|
-
[c.
|
|
25
|
+
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
|
|
25
26
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s %s.'],
|
|
26
27
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
27
28
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
@@ -30,5 +31,5 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
30
31
|
[c.STREAMING_DISCONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Disconnecting streaming.'],
|
|
31
32
|
[c.SYNC_START_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming not available. Starting polling.'],
|
|
32
33
|
[c.SYNC_CONTINUE_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming couldn\'t connect. Continue polling.'],
|
|
33
|
-
[c.SYNC_STOP_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming
|
|
34
|
+
[c.SYNC_STOP_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming connected. Syncing and stopping polling.'],
|
|
34
35
|
]);
|
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.
|
|
@@ -25,6 +26,7 @@ function sdkFactory(params) {
|
|
|
25
26
|
var readinessManager = sdkReadinessManager.readinessManager;
|
|
26
27
|
// @TODO consider passing the settings object, so that each storage access only what it needs
|
|
27
28
|
var storageFactoryParams = {
|
|
29
|
+
impressionsQueueSize: settings.scheduler.impressionsQueueSize,
|
|
28
30
|
eventsQueueSize: settings.scheduler.eventsQueueSize,
|
|
29
31
|
optimize: (0, utils_1.shouldBeOptimized)(settings),
|
|
30
32
|
// ATM, only used by InLocalStorage
|
|
@@ -67,11 +69,11 @@ function sdkFactory(params) {
|
|
|
67
69
|
syncManager && syncManager.start();
|
|
68
70
|
signalListener && signalListener.start();
|
|
69
71
|
log.info(constants_1.NEW_FACTORY);
|
|
70
|
-
|
|
72
|
+
// @ts-ignore
|
|
73
|
+
return (0, objectAssign_1.objectAssign)({
|
|
71
74
|
// Split evaluation and event tracking engine
|
|
72
75
|
client: clientMethod,
|
|
73
76
|
// Manager API to explore available information
|
|
74
|
-
// @ts-ignore
|
|
75
77
|
manager: function () {
|
|
76
78
|
log.debug(constants_1.RETRIEVE_MANAGER);
|
|
77
79
|
return managerInstance;
|
|
@@ -79,6 +81,6 @@ function sdkFactory(params) {
|
|
|
79
81
|
// Logger wrapper API
|
|
80
82
|
Logger: (0, sdkLogger_1.createLoggerAPI)(settings.log),
|
|
81
83
|
settings: settings,
|
|
82
|
-
};
|
|
84
|
+
}, extraProps && extraProps(settings, syncManager));
|
|
83
85
|
}
|
|
84
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
|
|
@@ -33,7 +33,7 @@ function InLocalStorage(options) {
|
|
|
33
33
|
return {
|
|
34
34
|
splits: new SplitsCacheInLocal_1.SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
|
|
35
35
|
segments: new MySegmentsCacheInLocal_1.MySegmentsCacheInLocal(log, keys),
|
|
36
|
-
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(),
|
|
36
|
+
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
37
37
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
|
|
38
38
|
events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
|
|
39
39
|
destroy: function () {
|
|
@@ -2,15 +2,29 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.ImpressionsCacheInMemory = void 0;
|
|
4
4
|
var ImpressionsCacheInMemory = /** @class */ (function () {
|
|
5
|
-
|
|
5
|
+
/**
|
|
6
|
+
*
|
|
7
|
+
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
8
|
+
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
9
|
+
*/
|
|
10
|
+
function ImpressionsCacheInMemory(impressionsQueueSize) {
|
|
11
|
+
if (impressionsQueueSize === void 0) { impressionsQueueSize = 0; }
|
|
12
|
+
this.maxQueue = impressionsQueueSize;
|
|
6
13
|
this.queue = [];
|
|
7
14
|
}
|
|
15
|
+
ImpressionsCacheInMemory.prototype.setOnFullQueueCb = function (cb) {
|
|
16
|
+
this.onFullQueue = cb;
|
|
17
|
+
};
|
|
8
18
|
/**
|
|
9
19
|
* Store impressions in sequential order
|
|
10
20
|
*/
|
|
11
21
|
ImpressionsCacheInMemory.prototype.track = function (data) {
|
|
12
22
|
var _a;
|
|
13
23
|
(_a = this.queue).push.apply(_a, data);
|
|
24
|
+
// Check if the cache queue is full and we need to flush it.
|
|
25
|
+
if (this.maxQueue > 0 && this.queue.length >= this.maxQueue && this.onFullQueue) {
|
|
26
|
+
this.onFullQueue();
|
|
27
|
+
}
|
|
14
28
|
};
|
|
15
29
|
/**
|
|
16
30
|
* Clear the data stored on the cache.
|
|
@@ -16,7 +16,7 @@ function InMemoryStorageFactory(params) {
|
|
|
16
16
|
return {
|
|
17
17
|
splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
|
|
18
18
|
segments: new SegmentsCacheInMemory_1.SegmentsCacheInMemory(),
|
|
19
|
-
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(),
|
|
19
|
+
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
20
20
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
|
|
21
21
|
events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
|
|
22
22
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
@@ -16,7 +16,7 @@ function InMemoryStorageCSFactory(params) {
|
|
|
16
16
|
return {
|
|
17
17
|
splits: new SplitsCacheInMemory_1.SplitsCacheInMemory(),
|
|
18
18
|
segments: new MySegmentsCacheInMemory_1.MySegmentsCacheInMemory(),
|
|
19
|
-
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(),
|
|
19
|
+
impressions: new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
20
20
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
|
|
21
21
|
events: new EventsCacheInMemory_1.EventsCacheInMemory(params.eventsQueueSize),
|
|
22
22
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
@@ -54,7 +54,7 @@ function PluggableStorage(options) {
|
|
|
54
54
|
validatePluggableStorageOptions(options);
|
|
55
55
|
var prefix = (0, KeyBuilder_1.validatePrefix)(options.prefix);
|
|
56
56
|
function PluggableStorageFactory(_a) {
|
|
57
|
-
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb, mode = _a.mode, eventsQueueSize = _a.eventsQueueSize, optimize = _a.optimize;
|
|
57
|
+
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb, mode = _a.mode, eventsQueueSize = _a.eventsQueueSize, impressionsQueueSize = _a.impressionsQueueSize, optimize = _a.optimize;
|
|
58
58
|
var keys = new KeyBuilderSS_1.KeyBuilderSS(prefix, metadata);
|
|
59
59
|
var wrapper = (0, wrapperAdapter_1.wrapperAdapter)(log, options.wrapper);
|
|
60
60
|
var isPartialConsumer = mode === constants_1.CONSUMER_PARTIAL_MODE;
|
|
@@ -63,7 +63,7 @@ function PluggableStorage(options) {
|
|
|
63
63
|
return {
|
|
64
64
|
splits: new SplitsCachePluggable_1.SplitsCachePluggable(log, keys, wrapper),
|
|
65
65
|
segments: new SegmentsCachePluggable_1.SegmentsCachePluggable(log, keys, wrapper),
|
|
66
|
-
impressions: isPartialConsumer ? new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory() : new ImpressionsCachePluggable_1.ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
66
|
+
impressions: isPartialConsumer ? new ImpressionsCacheInMemory_1.ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable_1.ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
67
67
|
impressionCounts: optimize ? new ImpressionCountsCacheInMemory_1.ImpressionCountsCacheInMemory() : undefined,
|
|
68
68
|
events: isPartialConsumer ? promisifyEventsTrack(new EventsCacheInMemory_1.EventsCacheInMemory(eventsQueueSize)) : new EventsCachePluggable_1.EventsCachePluggable(log, keys.buildEventsKey(), wrapper, metadata),
|
|
69
69
|
// @TODO add telemetry cache when required
|
|
@@ -58,6 +58,7 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
58
58
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
59
59
|
var disconnected;
|
|
60
60
|
// flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
61
|
+
// true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
|
|
61
62
|
var disabled; // `disabled` implies `disconnected === true`
|
|
62
63
|
/** PushManager functions related to initialization */
|
|
63
64
|
var connectPushRetryBackoff = new Backoff_1.Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
|
|
@@ -258,13 +259,15 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
258
259
|
return (0, objectAssign_1.objectAssign)(
|
|
259
260
|
// Expose Event Emitter functionality and Event constants
|
|
260
261
|
Object.create(pushEmitter), {
|
|
261
|
-
// Stop/pause push mode
|
|
262
|
+
// Stop/pause push mode.
|
|
263
|
+
// It doesn't emit events. Neither PUSH_SUBSYSTEM_DOWN to start polling.
|
|
262
264
|
stop: function () {
|
|
263
265
|
disconnectPush(); // `handleNonRetryableError` cannot be used as `stop`, because it emits PUSH_SUBSYSTEM_DOWN event, which starts polling.
|
|
264
266
|
if (userKey)
|
|
265
267
|
this.remove(userKey); // Necessary to properly resume streaming in client-side (e.g., RN SDK transition to foreground).
|
|
266
268
|
},
|
|
267
|
-
// Start/resume push mode
|
|
269
|
+
// Start/resume push mode.
|
|
270
|
+
// It eventually emits PUSH_SUBSYSTEM_DOWN, that starts polling, or PUSH_SUBSYSTEM_UP, that executes a syncAll
|
|
268
271
|
start: function () {
|
|
269
272
|
// Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
|
|
270
273
|
if (disabled || disconnected === false)
|
|
@@ -275,6 +278,10 @@ function pushManagerFactory(params, pollingManager) {
|
|
|
275
278
|
else
|
|
276
279
|
setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
277
280
|
},
|
|
281
|
+
// true/false if start or stop was called last respectively
|
|
282
|
+
isRunning: function () {
|
|
283
|
+
return disconnected === false;
|
|
284
|
+
},
|
|
278
285
|
// [Only for client-side]
|
|
279
286
|
add: function (userKey, mySegmentsSyncTask) {
|
|
280
287
|
var hash = (0, AuthClient_1.hashUserKey)(userKey);
|
|
@@ -3,12 +3,13 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.eventsSyncTaskFactory = void 0;
|
|
4
4
|
var submitterSyncTask_1 = require("./submitterSyncTask");
|
|
5
5
|
var constants_1 = require("../../logger/constants");
|
|
6
|
+
var DATA_NAME = 'events';
|
|
6
7
|
/**
|
|
7
8
|
* Sync task that periodically posts tracked events
|
|
8
9
|
*/
|
|
9
10
|
function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, eventsFirstPushWindow, latencyTracker) {
|
|
10
11
|
// don't retry events.
|
|
11
|
-
var syncTask = (0, submitterSyncTask_1.submitterSyncTaskFactory)(log, postEventsBulk, eventsCache, eventsPushRate,
|
|
12
|
+
var syncTask = (0, submitterSyncTask_1.submitterSyncTaskFactory)(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
|
|
12
13
|
// Set a timer for the first push of events,
|
|
13
14
|
if (eventsFirstPushWindow > 0) {
|
|
14
15
|
var stopEventPublisherTimeout_1;
|
|
@@ -22,10 +23,14 @@ function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate,
|
|
|
22
23
|
originalStop_1();
|
|
23
24
|
};
|
|
24
25
|
}
|
|
25
|
-
// register
|
|
26
|
+
// register events submitter to be executed when events cache is full
|
|
26
27
|
eventsCache.setOnFullQueueCb(function () {
|
|
27
|
-
|
|
28
|
-
|
|
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.
|
|
29
34
|
});
|
|
30
35
|
return syncTask;
|
|
31
36
|
}
|
|
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.impressionsSyncTaskFactory = exports.fromImpressionsCollector = void 0;
|
|
4
4
|
var lang_1 = require("../../utils/lang");
|
|
5
5
|
var submitterSyncTask_1 = require("./submitterSyncTask");
|
|
6
|
+
var constants_1 = require("../../logger/constants");
|
|
7
|
+
var DATA_NAME = 'impressions';
|
|
6
8
|
/**
|
|
7
9
|
* Converts `impressions` data from cache into request payload.
|
|
8
10
|
*/
|
|
@@ -36,6 +38,16 @@ exports.fromImpressionsCollector = fromImpressionsCollector;
|
|
|
36
38
|
function impressionsSyncTaskFactory(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, sendLabels, latencyTracker) {
|
|
37
39
|
if (sendLabels === void 0) { sendLabels = false; }
|
|
38
40
|
// retry impressions only once.
|
|
39
|
-
|
|
41
|
+
var syncTask = (0, submitterSyncTask_1.submitterSyncTaskFactory)(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, DATA_NAME, latencyTracker, fromImpressionsCollector.bind(undefined, sendLabels), 1);
|
|
42
|
+
// register impressions submitter to be executed when impressions cache is full
|
|
43
|
+
impressionsCache.setOnFullQueueCb(function () {
|
|
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.
|
|
50
|
+
});
|
|
51
|
+
return syncTask;
|
|
40
52
|
}
|
|
41
53
|
exports.impressionsSyncTaskFactory = impressionsSyncTaskFactory;
|
|
@@ -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
|