@splitsoftware/splitio-commons 1.2.1-rc.1 → 1.2.1-rc.12
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/consent/index.js +10 -0
- package/cjs/consent/sdkUserConsent.js +58 -0
- package/cjs/evaluator/Engine.js +6 -6
- package/cjs/evaluator/combiners/and.js +1 -1
- package/cjs/evaluator/combiners/ifelseif.js +2 -2
- package/cjs/evaluator/condition/engineUtils.js +2 -2
- package/cjs/evaluator/condition/index.js +4 -4
- package/cjs/evaluator/index.js +5 -5
- package/cjs/evaluator/matchers/cont_all.js +1 -1
- package/cjs/evaluator/matchers/cont_any.js +1 -1
- package/cjs/evaluator/matchers/cont_str.js +1 -1
- package/cjs/evaluator/matchers/dependency.js +1 -1
- package/cjs/evaluator/matchers/eq_set.js +1 -1
- package/cjs/evaluator/matchers/ew.js +1 -1
- package/cjs/evaluator/matchers/part_of.js +1 -1
- package/cjs/evaluator/matchers/segment.js +1 -1
- package/cjs/evaluator/matchers/sw.js +1 -1
- package/cjs/evaluator/matchers/whitelist.js +1 -1
- package/cjs/evaluator/matchersTransform/index.js +12 -12
- package/cjs/evaluator/parser/index.js +6 -6
- package/cjs/evaluator/treatments/index.js +1 -1
- package/cjs/evaluator/value/index.js +1 -1
- package/cjs/evaluator/value/sanitize.js +4 -4
- package/cjs/integrations/browser.js +3 -3
- package/cjs/integrations/ga/GaToSplit.js +14 -14
- package/cjs/integrations/ga/GoogleAnalyticsToSplit.js +5 -3
- package/cjs/integrations/ga/SplitToGa.js +1 -1
- package/cjs/integrations/ga/SplitToGoogleAnalytics.js +4 -2
- package/cjs/listeners/browser.js +15 -11
- package/cjs/listeners/node.js +1 -1
- package/cjs/logger/constants.js +9 -3
- package/cjs/logger/index.js +2 -2
- package/cjs/logger/messages/debug.js +4 -4
- package/cjs/logger/messages/error.js +5 -4
- package/cjs/logger/messages/info.js +8 -5
- package/cjs/logger/messages/warn.js +1 -1
- package/cjs/logger/sdkLogger.js +1 -1
- package/cjs/readiness/readinessManager.js +2 -2
- package/cjs/readiness/sdkReadinessManager.js +4 -4
- package/cjs/sdkClient/client.js +12 -11
- package/cjs/sdkClient/clientAttributesDecoration.js +4 -4
- package/cjs/sdkClient/clientCS.js +3 -3
- package/cjs/sdkClient/clientInputValidation.js +20 -22
- package/cjs/sdkClient/sdkClient.js +6 -9
- package/cjs/sdkClient/sdkClientMethod.js +1 -1
- package/cjs/sdkClient/sdkClientMethodCS.js +7 -13
- package/cjs/sdkClient/sdkClientMethodCSWithTT.js +8 -18
- package/cjs/sdkFactory/index.js +16 -13
- package/cjs/sdkManager/index.js +11 -11
- package/cjs/services/splitApi.js +3 -2
- package/cjs/services/splitHttpClient.js +2 -2
- package/cjs/storages/KeyBuilder.js +2 -6
- package/cjs/storages/KeyBuilderCS.js +13 -3
- package/cjs/storages/KeyBuilderSS.js +1 -1
- package/cjs/storages/findLatencyIndex.js +1 -1
- package/cjs/storages/inLocalStorage/MySegmentsCacheInLocal.js +24 -4
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +12 -12
- package/cjs/storages/inLocalStorage/index.js +4 -4
- package/cjs/storages/inMemory/AttributesCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/ImpressionCountsCacheInMemory.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/inMemory/LatenciesCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/MySegmentsCacheInMemory.js +1 -1
- package/cjs/storages/inMemory/SegmentsCacheInMemory.js +2 -2
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +5 -5
- package/cjs/storages/inRedis/LatenciesCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/RedisAdapter.js +24 -11
- package/cjs/storages/inRedis/SegmentsCacheInRedis.js +1 -1
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +3 -3
- package/cjs/storages/inRedis/index.js +1 -1
- package/cjs/storages/pluggable/SegmentsCachePluggable.js +1 -1
- package/cjs/storages/pluggable/SplitsCachePluggable.js +3 -3
- package/cjs/storages/pluggable/inMemoryWrapper.js +4 -4
- package/cjs/storages/pluggable/index.js +6 -6
- package/cjs/sync/offline/LocalhostFromFile.js +1 -1
- package/cjs/sync/offline/LocalhostFromObject.js +1 -1
- package/cjs/sync/offline/splitsParser/parseCondition.js +1 -1
- package/cjs/sync/offline/splitsParser/splitsParserFromFile.js +13 -13
- package/cjs/sync/offline/splitsParser/splitsParserFromSettings.js +3 -3
- package/cjs/sync/offline/syncManagerOffline.js +1 -1
- package/cjs/sync/offline/syncTasks/fromObjectSyncTask.js +2 -2
- package/cjs/sync/polling/fetchers/segmentChangesFetcher.js +1 -1
- package/cjs/sync/polling/pollingManagerCS.js +6 -6
- package/cjs/sync/polling/pollingManagerSS.js +3 -3
- package/cjs/sync/polling/syncTasks/mySegmentsSyncTask.js +1 -1
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
- package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/mySegmentsUpdater.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +2 -2
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -2
- package/cjs/sync/streaming/AuthClient/index.js +3 -3
- package/cjs/sync/streaming/SSEClient/index.js +2 -1
- package/cjs/sync/streaming/SSEHandler/NotificationParser.js +1 -1
- package/cjs/sync/streaming/SSEHandler/index.js +3 -3
- package/cjs/sync/streaming/mySegmentsV2utils.js +1 -1
- package/cjs/sync/streaming/pushManager.js +24 -17
- package/cjs/sync/submitters/eventsSyncTask.js +17 -5
- package/cjs/sync/submitters/impressionCountsSyncTask.js +1 -1
- package/cjs/sync/submitters/impressionsSyncTask.js +15 -3
- package/cjs/sync/submitters/metricsSyncTask.js +3 -3
- package/cjs/sync/submitters/submitterManager.js +4 -4
- package/cjs/sync/submitters/submitterSyncTask.js +1 -1
- package/cjs/sync/syncManagerOnline.js +12 -8
- package/cjs/trackers/eventTracker.js +11 -4
- package/cjs/trackers/impressionObserver/impressionObserverCS.js +1 -1
- package/cjs/trackers/impressionObserver/impressionObserverSS.js +1 -1
- package/cjs/trackers/impressionObserver/utils.js +8 -1
- package/cjs/trackers/impressionsTracker.js +9 -8
- package/cjs/utils/MinEvents.js +2 -1
- package/cjs/utils/constants/index.js +5 -1
- package/cjs/utils/inputValidation/apiKey.js +1 -1
- package/cjs/utils/inputValidation/attribute.js +4 -4
- package/cjs/utils/inputValidation/attributes.js +2 -2
- package/cjs/utils/inputValidation/event.js +1 -1
- package/cjs/utils/inputValidation/eventProperties.js +5 -5
- package/cjs/utils/inputValidation/eventValue.js +1 -1
- package/cjs/utils/inputValidation/key.js +6 -5
- package/cjs/utils/inputValidation/preloadedData.js +8 -8
- package/cjs/utils/inputValidation/split.js +1 -1
- package/cjs/utils/inputValidation/splits.js +2 -2
- package/cjs/utils/inputValidation/trafficType.js +1 -1
- package/cjs/utils/inputValidation/trafficTypeExistance.js +1 -1
- package/cjs/utils/jwt/index.js +1 -1
- package/cjs/utils/key/index.js +3 -3
- package/cjs/utils/lang/index.js +13 -4
- package/cjs/utils/lang/maps.js +16 -2
- package/cjs/utils/murmur3/common.js +1 -1
- package/cjs/utils/murmur3/murmur3.js +10 -10
- package/cjs/utils/murmur3/murmur3_128.js +1 -1
- package/cjs/utils/murmur3/murmur3_128_x86.js +37 -37
- package/cjs/utils/murmur3/murmur3_64.js +1 -1
- package/cjs/utils/settingsValidation/consent.js +16 -0
- package/cjs/utils/settingsValidation/impressionsMode.js +6 -6
- package/cjs/utils/settingsValidation/index.js +32 -14
- package/cjs/utils/settingsValidation/integrations/configurable.js +1 -1
- package/cjs/utils/settingsValidation/integrations/pluggable.js +1 -1
- package/cjs/utils/settingsValidation/localhost/builtin.js +2 -2
- package/cjs/utils/settingsValidation/logger/builtinLogger.js +3 -3
- package/cjs/utils/settingsValidation/logger/commons.js +1 -1
- package/cjs/utils/settingsValidation/logger/pluggableLogger.js +1 -1
- package/cjs/utils/settingsValidation/runtime.js +11 -0
- package/cjs/utils/settingsValidation/splitFilters.js +1 -1
- package/cjs/utils/settingsValidation/storage/storageCS.js +1 -1
- package/cjs/utils/timeTracker/index.js +3 -3
- package/esm/consent/index.js +6 -0
- package/esm/consent/sdkUserConsent.js +54 -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 +6 -2
- package/esm/logger/messages/debug.js +3 -3
- package/esm/logger/messages/error.js +4 -3
- package/esm/logger/messages/info.js +7 -4
- package/esm/sdkClient/client.js +3 -2
- package/esm/sdkClient/clientCS.js +1 -1
- package/esm/sdkClient/clientInputValidation.js +6 -8
- package/esm/sdkClient/sdkClient.js +4 -7
- package/esm/sdkClient/sdkClientMethodCS.js +3 -9
- package/esm/sdkClient/sdkClientMethodCSWithTT.js +3 -13
- package/esm/sdkFactory/index.js +10 -7
- package/esm/services/splitApi.js +2 -1
- package/esm/storages/KeyBuilder.js +2 -6
- 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/inRedis/RedisAdapter.js +15 -2
- package/esm/storages/pluggable/index.js +2 -2
- package/esm/sync/offline/splitsParser/splitsParserFromFile.js +1 -1
- package/esm/sync/polling/fetchers/segmentChangesFetcher.js +2 -2
- package/esm/sync/streaming/SSEClient/index.js +2 -1
- package/esm/sync/streaming/pushManager.js +9 -2
- package/esm/sync/submitters/eventsSyncTask.js +18 -6
- package/esm/sync/submitters/impressionsSyncTask.js +13 -1
- package/esm/sync/syncManagerOnline.js +11 -7
- package/esm/trackers/eventTracker.js +8 -1
- package/esm/trackers/impressionObserver/utils.js +7 -1
- package/esm/trackers/impressionsTracker.js +6 -5
- package/esm/utils/constants/index.js +4 -0
- package/esm/utils/inputValidation/attributes.js +1 -1
- package/esm/utils/inputValidation/key.js +2 -1
- package/esm/utils/lang/index.js +12 -4
- package/esm/utils/lang/maps.js +14 -1
- package/esm/utils/settingsValidation/consent.js +12 -0
- package/esm/utils/settingsValidation/impressionsMode.js +7 -7
- package/esm/utils/settingsValidation/index.js +28 -10
- package/esm/utils/settingsValidation/runtime.js +7 -0
- package/package.json +8 -8
- package/src/consent/index.ts +8 -0
- package/src/consent/sdkUserConsent.ts +58 -0
- package/src/evaluator/parser/index.ts +1 -1
- package/src/evaluator/types.ts +2 -2
- package/src/evaluator/value/index.ts +2 -2
- package/src/evaluator/value/sanitize.ts +2 -2
- package/src/integrations/ga/GoogleAnalyticsToSplit.ts +7 -4
- package/src/integrations/ga/SplitToGoogleAnalytics.ts +7 -4
- package/src/integrations/pluggable.ts +2 -2
- package/src/integrations/types.ts +5 -0
- package/src/listeners/browser.ts +13 -9
- package/src/logger/constants.ts +6 -2
- package/src/logger/messages/debug.ts +3 -3
- package/src/logger/messages/error.ts +4 -3
- package/src/logger/messages/info.ts +7 -4
- package/src/logger/types.ts +4 -0
- package/src/sdkClient/client.ts +5 -5
- package/src/sdkClient/clientCS.ts +1 -1
- package/src/sdkClient/clientInputValidation.ts +8 -7
- package/src/sdkClient/sdkClient.ts +6 -9
- package/src/sdkClient/sdkClientMethod.ts +2 -2
- package/src/sdkClient/sdkClientMethodCS.ts +5 -11
- package/src/sdkClient/sdkClientMethodCSWithTT.ts +6 -16
- package/src/sdkFactory/index.ts +11 -8
- package/src/sdkFactory/types.ts +14 -3
- package/src/storages/KeyBuilder.ts +2 -6
- 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/inRedis/RedisAdapter.ts +8 -2
- package/src/storages/pluggable/index.ts +2 -2
- package/src/storages/types.ts +6 -2
- package/src/sync/offline/splitsParser/splitsParserFromFile.ts +1 -1
- package/src/sync/streaming/SSEClient/index.ts +2 -1
- package/src/sync/streaming/pushManager.ts +11 -2
- package/src/sync/submitters/eventsSyncTask.ts +19 -6
- package/src/sync/submitters/impressionsSyncTask.ts +16 -1
- package/src/sync/syncManagerOnline.ts +13 -7
- package/src/sync/types.ts +4 -1
- package/src/trackers/eventTracker.ts +11 -3
- package/src/trackers/impressionObserver/utils.ts +8 -1
- package/src/trackers/impressionsTracker.ts +7 -8
- package/src/types.ts +22 -1
- package/src/utils/constants/index.ts +5 -0
- package/src/utils/inputValidation/attributes.ts +1 -2
- package/src/utils/lang/index.ts +15 -4
- package/src/utils/lang/maps.ts +15 -1
- package/src/utils/settingsValidation/consent.ts +16 -0
- package/src/utils/settingsValidation/impressionsMode.ts +8 -8
- package/src/utils/settingsValidation/index.ts +29 -10
- package/src/utils/settingsValidation/runtime.ts +9 -0
- package/src/utils/settingsValidation/types.ts +12 -6
- package/types/consent/index.d.ts +2 -0
- package/types/consent/sdkUserConsent.d.ts +13 -0
- package/types/evaluator/types.d.ts +2 -2
- package/types/evaluator/value/index.d.ts +1 -1
- package/types/evaluator/value/sanitize.d.ts +1 -1
- 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 +6 -2
- package/types/logger/types.d.ts +4 -0
- package/types/sdkClient/client.d.ts +2 -2
- package/types/sdkClient/clientAttributesDecoration.d.ts +1 -1
- package/types/sdkClient/clientInputValidation.d.ts +2 -3
- package/types/sdkClient/sdkClient.d.ts +2 -2
- package/types/sdkClient/sdkClientMethod.d.ts +2 -2
- package/types/sdkClient/sdkClientMethodCS.d.ts +2 -2
- package/types/sdkClient/sdkClientMethodCSWithTT.d.ts +2 -2
- package/types/sdkFactory/types.d.ts +12 -3
- 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/inRedis/RedisAdapter.d.ts +1 -1
- package/types/storages/types.d.ts +3 -1
- package/types/sync/types.d.ts +3 -0
- package/types/trackers/eventTracker.d.ts +2 -2
- package/types/trackers/impressionObserver/utils.d.ts +4 -0
- package/types/trackers/impressionsTracker.d.ts +2 -3
- package/types/types.d.ts +22 -1
- package/types/utils/consent.d.ts +2 -0
- package/types/utils/constants/index.d.ts +3 -0
- package/types/utils/lang/index.d.ts +6 -1
- package/types/utils/lang/maps.d.ts +7 -0
- package/types/utils/settingsValidation/consent.d.ts +6 -0
- package/types/utils/settingsValidation/impressionsMode.d.ts +1 -1
- package/types/utils/settingsValidation/runtime/browser.d.ts +2 -0
- package/types/utils/settingsValidation/runtime/node.d.ts +2 -0
- package/types/utils/settingsValidation/runtime.d.ts +2 -0
- package/types/utils/settingsValidation/types.d.ts +12 -6
- package/types/utils/settingsValidation/userConsent.d.ts +5 -0
- package/cjs/sdkClient/types.js +0 -2
- package/esm/sdkClient/types.js +0 -1
- package/src/sdkClient/types.ts +0 -21
|
@@ -18,16 +18,7 @@ var method = 'Client instantiation';
|
|
|
18
18
|
*/
|
|
19
19
|
export function sdkClientMethodCSFactory(params) {
|
|
20
20
|
var storage = params.storage, syncManager = params.syncManager, sdkReadinessManager = params.sdkReadinessManager, _a = params.settings, _b = _a.core, key = _b.key, trafficType = _b.trafficType, readyTimeout = _a.startup.readyTimeout, log = _a.log;
|
|
21
|
-
|
|
22
|
-
// `false` value is used as binded key/TT of the default client, which leads to several issues.
|
|
23
|
-
// @TODO update when supporting non-recoverable errors
|
|
24
|
-
var validKey = validateKey(log, key, method);
|
|
25
|
-
var validTrafficType;
|
|
26
|
-
if (trafficType !== undefined) {
|
|
27
|
-
validTrafficType = validateTrafficType(log, trafficType, method);
|
|
28
|
-
}
|
|
29
|
-
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), // @ts-ignore
|
|
30
|
-
validKey, validTrafficType);
|
|
21
|
+
var mainClientInstance = clientCSDecorator(log, sdkClientFactory(params), key, trafficType);
|
|
31
22
|
var parsedDefaultKey = keyParser(key);
|
|
32
23
|
var defaultInstanceId = buildInstanceId(parsedDefaultKey, trafficType);
|
|
33
24
|
// Cache instances created per factory.
|
|
@@ -72,9 +63,8 @@ export function sdkClientMethodCSFactory(params) {
|
|
|
72
63
|
sdkReadinessManager: sharedSdkReadiness_1,
|
|
73
64
|
storage: sharedStorage || storage,
|
|
74
65
|
syncManager: sharedSyncManager,
|
|
75
|
-
signalListener: undefined,
|
|
76
|
-
|
|
77
|
-
})), validKey, validTrafficType);
|
|
66
|
+
signalListener: undefined, // only the main client "destroy" method stops the signal listener
|
|
67
|
+
}), true), validKey, validTrafficType);
|
|
78
68
|
sharedSyncManager && sharedSyncManager.start();
|
|
79
69
|
log.info(NEW_SHARED_CLIENT);
|
|
80
70
|
}
|
package/esm/sdkFactory/index.js
CHANGED
|
@@ -8,11 +8,12 @@ import { createLoggerAPI } from '../logger/sdkLogger';
|
|
|
8
8
|
import { NEW_FACTORY, RETRIEVE_MANAGER } from '../logger/constants';
|
|
9
9
|
import { metadataBuilder } from '../storages/metadataBuilder';
|
|
10
10
|
import { SDK_SPLITS_ARRIVED, SDK_SEGMENTS_ARRIVED } from '../readiness/constants';
|
|
11
|
+
import { objectAssign } from '../utils/lang/objectAssign';
|
|
11
12
|
/**
|
|
12
13
|
* Modular SDK factory
|
|
13
14
|
*/
|
|
14
15
|
export function sdkFactory(params) {
|
|
15
|
-
var settings = params.settings, platform = params.platform, storageFactory = params.storageFactory, splitApiFactory = params.splitApiFactory,
|
|
16
|
+
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, integrationsManagerFactory = params.integrationsManagerFactory, sdkManagerFactory = params.sdkManagerFactory, sdkClientMethodFactory = params.sdkClientMethodFactory;
|
|
16
17
|
var log = settings.log;
|
|
17
18
|
// @TODO handle non-recoverable errors: not start sync, mark the SDK as destroyed, etc.
|
|
18
19
|
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
@@ -22,6 +23,7 @@ export function sdkFactory(params) {
|
|
|
22
23
|
var readinessManager = sdkReadinessManager.readinessManager;
|
|
23
24
|
// @TODO consider passing the settings object, so that each storage access only what it needs
|
|
24
25
|
var storageFactoryParams = {
|
|
26
|
+
impressionsQueueSize: settings.scheduler.impressionsQueueSize,
|
|
25
27
|
eventsQueueSize: settings.scheduler.eventsQueueSize,
|
|
26
28
|
optimize: shouldBeOptimized(settings),
|
|
27
29
|
// ATM, only used by InLocalStorage
|
|
@@ -54,21 +56,22 @@ export function sdkFactory(params) {
|
|
|
54
56
|
var integrationsManager = integrationsManagerFactory && integrationsManagerFactory({ settings: settings, storage: storage });
|
|
55
57
|
// trackers
|
|
56
58
|
var observer = impressionsObserverFactory && impressionsObserverFactory();
|
|
57
|
-
var impressionsTracker = impressionsTrackerFactory(
|
|
58
|
-
var eventTracker = eventTrackerFactory(
|
|
59
|
+
var impressionsTracker = impressionsTrackerFactory(settings, storage.impressions, integrationsManager, observer, storage.impressionCounts);
|
|
60
|
+
var eventTracker = eventTrackerFactory(settings, storage.events, integrationsManager);
|
|
59
61
|
// signal listener
|
|
60
62
|
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
|
61
63
|
// Sdk client and manager
|
|
62
|
-
var
|
|
64
|
+
var ctx = { eventTracker: eventTracker, impressionsTracker: impressionsTracker, sdkReadinessManager: sdkReadinessManager, settings: settings, storage: storage, syncManager: syncManager, signalListener: signalListener };
|
|
65
|
+
var clientMethod = sdkClientMethodFactory(ctx);
|
|
63
66
|
var managerInstance = sdkManagerFactory(log, storage.splits, sdkReadinessManager);
|
|
64
67
|
syncManager && syncManager.start();
|
|
65
68
|
signalListener && signalListener.start();
|
|
66
69
|
log.info(NEW_FACTORY);
|
|
67
|
-
|
|
70
|
+
// @ts-ignore
|
|
71
|
+
return objectAssign({
|
|
68
72
|
// Split evaluation and event tracking engine
|
|
69
73
|
client: clientMethod,
|
|
70
74
|
// Manager API to explore available information
|
|
71
|
-
// @ts-ignore
|
|
72
75
|
manager: function () {
|
|
73
76
|
log.debug(RETRIEVE_MANAGER);
|
|
74
77
|
return managerInstance;
|
|
@@ -76,5 +79,5 @@ export function sdkFactory(params) {
|
|
|
76
79
|
// Logger wrapper API
|
|
77
80
|
Logger: createLoggerAPI(settings.log),
|
|
78
81
|
settings: settings,
|
|
79
|
-
};
|
|
82
|
+
}, extraProps && extraProps(ctx));
|
|
80
83
|
}
|
package/esm/services/splitApi.js
CHANGED
|
@@ -72,7 +72,8 @@ export function splitApiFactory(settings, platform) {
|
|
|
72
72
|
return splitHttpClient(url, {
|
|
73
73
|
// Adding extra headers to send impressions in OPTIMIZED or DEBUG modes.
|
|
74
74
|
method: 'POST',
|
|
75
|
-
body: body,
|
|
75
|
+
body: body,
|
|
76
|
+
headers: objectAssign({ SplitSDKImpressionsMode: SplitSDKImpressionsMode }, headers)
|
|
76
77
|
});
|
|
77
78
|
},
|
|
78
79
|
/**
|
|
@@ -1,12 +1,8 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { startsWith } from '../utils/lang';
|
|
2
2
|
var everythingAtTheEnd = /[^.]+$/;
|
|
3
3
|
var DEFAULT_PREFIX = 'SPLITIO';
|
|
4
4
|
export function validatePrefix(prefix) {
|
|
5
|
-
return prefix
|
|
6
|
-
endsWith(prefix, '.' + DEFAULT_PREFIX) ?
|
|
7
|
-
prefix : // suffix already appended
|
|
8
|
-
prefix + '.' + DEFAULT_PREFIX : // append suffix
|
|
9
|
-
DEFAULT_PREFIX; // use default prefix if none is provided
|
|
5
|
+
return prefix ? prefix + '.SPLITIO' : 'SPLITIO';
|
|
10
6
|
}
|
|
11
7
|
var KeyBuilder = /** @class */ (function () {
|
|
12
8
|
function KeyBuilder(prefix) {
|
|
@@ -13,9 +13,19 @@ var KeyBuilderCS = /** @class */ (function (_super) {
|
|
|
13
13
|
* @override
|
|
14
14
|
*/
|
|
15
15
|
KeyBuilderCS.prototype.buildSegmentNameKey = function (segmentName) {
|
|
16
|
-
return this.
|
|
16
|
+
return this.prefix + "." + this.matchingKey + ".segment." + segmentName;
|
|
17
17
|
};
|
|
18
18
|
KeyBuilderCS.prototype.extractSegmentName = function (builtSegmentKeyName) {
|
|
19
|
+
var prefix = this.prefix + "." + this.matchingKey + ".segment.";
|
|
20
|
+
if (startsWith(builtSegmentKeyName, prefix))
|
|
21
|
+
return builtSegmentKeyName.substr(prefix.length);
|
|
22
|
+
};
|
|
23
|
+
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
24
|
+
KeyBuilderCS.prototype.buildOldSegmentNameKey = function (segmentName) {
|
|
25
|
+
return this.matchingKey + "." + this.prefix + ".segment." + segmentName;
|
|
26
|
+
};
|
|
27
|
+
// @BREAKING: The key used to start with the matching key instead of the prefix, this was changed on version 10.17.3
|
|
28
|
+
KeyBuilderCS.prototype.extractOldSegmentKey = function (builtSegmentKeyName) {
|
|
19
29
|
var prefix = this.matchingKey + "." + this.prefix + ".segment.";
|
|
20
30
|
if (startsWith(builtSegmentKeyName, prefix))
|
|
21
31
|
return builtSegmentKeyName.substr(prefix.length);
|
|
@@ -57,9 +57,29 @@ var MySegmentsCacheInLocal = /** @class */ (function (_super) {
|
|
|
57
57
|
var index;
|
|
58
58
|
// Scan current values from localStorage
|
|
59
59
|
var storedSegmentNames = Object.keys(localStorage).reduce(function (accum, key) {
|
|
60
|
-
var
|
|
61
|
-
if (
|
|
62
|
-
accum.push(
|
|
60
|
+
var segmentName = _this.keys.extractSegmentName(key);
|
|
61
|
+
if (segmentName) {
|
|
62
|
+
accum.push(segmentName);
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
// @BREAKING: This is only to clean up "old" keys. Remove this whole else code block.
|
|
66
|
+
segmentName = _this.keys.extractOldSegmentKey(key);
|
|
67
|
+
if (segmentName) { // this was an old segment key, let's clean up.
|
|
68
|
+
var newSegmentKey = _this.keys.buildSegmentNameKey(segmentName);
|
|
69
|
+
try {
|
|
70
|
+
// If the new format key is not there, create it.
|
|
71
|
+
if (!localStorage.getItem(newSegmentKey) && names.indexOf(segmentName) > -1) {
|
|
72
|
+
localStorage.setItem(newSegmentKey, DEFINED);
|
|
73
|
+
// we are migrating a segment, let's track it.
|
|
74
|
+
accum.push(segmentName);
|
|
75
|
+
}
|
|
76
|
+
localStorage.removeItem(key); // we migrated the current key, let's delete it.
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
_this.log.error(e);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
}
|
|
63
83
|
return accum;
|
|
64
84
|
}, []);
|
|
65
85
|
// Extreme fast => everything is empty
|
|
@@ -30,7 +30,7 @@ export function InLocalStorage(options) {
|
|
|
30
30
|
return {
|
|
31
31
|
splits: new SplitsCacheInLocal(log, keys, expirationTimestamp, params.splitFiltersValidation),
|
|
32
32
|
segments: new MySegmentsCacheInLocal(log, keys),
|
|
33
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
33
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
34
34
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
35
35
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
36
36
|
destroy: function () {
|
|
@@ -1,13 +1,27 @@
|
|
|
1
1
|
var ImpressionsCacheInMemory = /** @class */ (function () {
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
*
|
|
4
|
+
* @param impressionsQueueSize number of queued impressions to call onFullQueueCb.
|
|
5
|
+
* Default value is 0, that means no maximum value, in case we want to avoid this being triggered.
|
|
6
|
+
*/
|
|
7
|
+
function ImpressionsCacheInMemory(impressionsQueueSize) {
|
|
8
|
+
if (impressionsQueueSize === void 0) { impressionsQueueSize = 0; }
|
|
9
|
+
this.maxQueue = impressionsQueueSize;
|
|
3
10
|
this.queue = [];
|
|
4
11
|
}
|
|
12
|
+
ImpressionsCacheInMemory.prototype.setOnFullQueueCb = function (cb) {
|
|
13
|
+
this.onFullQueue = cb;
|
|
14
|
+
};
|
|
5
15
|
/**
|
|
6
16
|
* Store impressions in sequential order
|
|
7
17
|
*/
|
|
8
18
|
ImpressionsCacheInMemory.prototype.track = function (data) {
|
|
9
19
|
var _a;
|
|
10
20
|
(_a = this.queue).push.apply(_a, data);
|
|
21
|
+
// Check if the cache queue is full and we need to flush it.
|
|
22
|
+
if (this.maxQueue > 0 && this.queue.length >= this.maxQueue && this.onFullQueue) {
|
|
23
|
+
this.onFullQueue();
|
|
24
|
+
}
|
|
11
25
|
};
|
|
12
26
|
/**
|
|
13
27
|
* Clear the data stored on the cache.
|
|
@@ -13,7 +13,7 @@ export function InMemoryStorageFactory(params) {
|
|
|
13
13
|
return {
|
|
14
14
|
splits: new SplitsCacheInMemory(),
|
|
15
15
|
segments: new SegmentsCacheInMemory(),
|
|
16
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
16
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
17
17
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
18
18
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
19
19
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
@@ -13,7 +13,7 @@ export function InMemoryStorageCSFactory(params) {
|
|
|
13
13
|
return {
|
|
14
14
|
splits: new SplitsCacheInMemory(),
|
|
15
15
|
segments: new MySegmentsCacheInMemory(),
|
|
16
|
-
impressions: new ImpressionsCacheInMemory(),
|
|
16
|
+
impressions: new ImpressionsCacheInMemory(params.impressionsQueueSize),
|
|
17
17
|
impressionCounts: params.optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
18
18
|
events: new EventsCacheInMemory(params.eventsQueueSize),
|
|
19
19
|
// When using MEMORY we should clean all the caches to leave them empty
|
|
@@ -143,15 +143,28 @@ var RedisAdapter = /** @class */ (function (_super) {
|
|
|
143
143
|
else { // If it IS the string URL, that'll be the first param for ioredis.
|
|
144
144
|
result.unshift(options.url);
|
|
145
145
|
}
|
|
146
|
+
if (options.connectionTimeout) {
|
|
147
|
+
merge(opts, { connectTimeout: options.connectionTimeout });
|
|
148
|
+
}
|
|
149
|
+
if (options.tls) {
|
|
150
|
+
merge(opts, { tls: options.tls });
|
|
151
|
+
}
|
|
146
152
|
return result;
|
|
147
153
|
};
|
|
148
154
|
/**
|
|
149
155
|
* Parses the options into what we care about.
|
|
150
156
|
*/
|
|
151
157
|
RedisAdapter._defineOptions = function (_a) {
|
|
152
|
-
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass;
|
|
158
|
+
var connectionTimeout = _a.connectionTimeout, operationTimeout = _a.operationTimeout, url = _a.url, host = _a.host, port = _a.port, db = _a.db, pass = _a.pass, tls = _a.tls;
|
|
153
159
|
var parsedOptions = {
|
|
154
|
-
connectionTimeout: connectionTimeout,
|
|
160
|
+
connectionTimeout: connectionTimeout,
|
|
161
|
+
operationTimeout: operationTimeout,
|
|
162
|
+
url: url,
|
|
163
|
+
host: host,
|
|
164
|
+
port: port,
|
|
165
|
+
db: db,
|
|
166
|
+
pass: pass,
|
|
167
|
+
tls: tls
|
|
155
168
|
};
|
|
156
169
|
return merge({}, DEFAULT_OPTIONS, parsedOptions);
|
|
157
170
|
};
|
|
@@ -51,7 +51,7 @@ export function PluggableStorage(options) {
|
|
|
51
51
|
validatePluggableStorageOptions(options);
|
|
52
52
|
var prefix = validatePrefix(options.prefix);
|
|
53
53
|
function PluggableStorageFactory(_a) {
|
|
54
|
-
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb, mode = _a.mode, eventsQueueSize = _a.eventsQueueSize, optimize = _a.optimize;
|
|
54
|
+
var log = _a.log, metadata = _a.metadata, onReadyCb = _a.onReadyCb, mode = _a.mode, eventsQueueSize = _a.eventsQueueSize, impressionsQueueSize = _a.impressionsQueueSize, optimize = _a.optimize;
|
|
55
55
|
var keys = new KeyBuilderSS(prefix, metadata);
|
|
56
56
|
var wrapper = wrapperAdapter(log, options.wrapper);
|
|
57
57
|
var isPartialConsumer = mode === CONSUMER_PARTIAL_MODE;
|
|
@@ -60,7 +60,7 @@ export function PluggableStorage(options) {
|
|
|
60
60
|
return {
|
|
61
61
|
splits: new SplitsCachePluggable(log, keys, wrapper),
|
|
62
62
|
segments: new SegmentsCachePluggable(log, keys, wrapper),
|
|
63
|
-
impressions: isPartialConsumer ? new ImpressionsCacheInMemory() : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
63
|
+
impressions: isPartialConsumer ? new ImpressionsCacheInMemory(impressionsQueueSize) : new ImpressionsCachePluggable(log, keys.buildImpressionsKey(), wrapper, metadata),
|
|
64
64
|
impressionCounts: optimize ? new ImpressionCountsCacheInMemory() : undefined,
|
|
65
65
|
events: isPartialConsumer ? promisifyEventsTrack(new EventsCacheInMemory(eventsQueueSize)) : new EventsCachePluggable(log, keys.buildEventsKey(), wrapper, metadata),
|
|
66
66
|
// @TODO add telemetry cache when required
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { __spreadArray } from "tslib";
|
|
2
2
|
function greedyFetch(fetchSegmentChanges, since, segmentName, noCache) {
|
|
3
3
|
return fetchSegmentChanges(since, segmentName, noCache)
|
|
4
4
|
.then(function (resp) { return resp.json(); })
|
|
@@ -9,7 +9,7 @@ function greedyFetch(fetchSegmentChanges, since, segmentName, noCache) {
|
|
|
9
9
|
}
|
|
10
10
|
else {
|
|
11
11
|
return Promise.all([json, greedyFetch(fetchSegmentChanges, till, segmentName, noCache)]).then(function (flatMe) {
|
|
12
|
-
return
|
|
12
|
+
return __spreadArray([flatMe[0]], flatMe[1], true);
|
|
13
13
|
});
|
|
14
14
|
}
|
|
15
15
|
});
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isString } from '../../../utils/lang';
|
|
1
2
|
var VERSION = '1.1';
|
|
2
3
|
var CONTROL_CHANNEL_REGEX = /^control_/;
|
|
3
4
|
/**
|
|
@@ -8,7 +9,7 @@ var CONTROL_CHANNEL_REGEX = /^control_/;
|
|
|
8
9
|
*/
|
|
9
10
|
function buildSSEHeaders(settings) {
|
|
10
11
|
var headers = {
|
|
11
|
-
SplitSDKClientKey: settings.core.authorizationKey.slice(-4),
|
|
12
|
+
SplitSDKClientKey: isString(settings.core.authorizationKey) ? settings.core.authorizationKey.slice(-4) : '',
|
|
12
13
|
SplitSDKVersion: settings.version,
|
|
13
14
|
};
|
|
14
15
|
// ip and hostname are false if IPAddressesEnabled is false
|
|
@@ -55,6 +55,7 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
55
55
|
// It is used to halt the `connectPush` process if it was in progress.
|
|
56
56
|
var disconnected;
|
|
57
57
|
// flag that indicates a PUSH_NONRETRYABLE_ERROR, condition with which starting pushManager again is ignored.
|
|
58
|
+
// true if STREAMING_DISABLED control event, or 'pushEnabled: false', or non-recoverable SSE or Auth errors.
|
|
58
59
|
var disabled; // `disabled` implies `disconnected === true`
|
|
59
60
|
/** PushManager functions related to initialization */
|
|
60
61
|
var connectPushRetryBackoff = new Backoff(connectPush, settings.scheduler.pushRetryBackoffBase);
|
|
@@ -255,13 +256,15 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
255
256
|
return objectAssign(
|
|
256
257
|
// Expose Event Emitter functionality and Event constants
|
|
257
258
|
Object.create(pushEmitter), {
|
|
258
|
-
// Stop/pause push mode
|
|
259
|
+
// Stop/pause push mode.
|
|
260
|
+
// It doesn't emit events. Neither PUSH_SUBSYSTEM_DOWN to start polling.
|
|
259
261
|
stop: function () {
|
|
260
262
|
disconnectPush(); // `handleNonRetryableError` cannot be used as `stop`, because it emits PUSH_SUBSYSTEM_DOWN event, which starts polling.
|
|
261
263
|
if (userKey)
|
|
262
264
|
this.remove(userKey); // Necessary to properly resume streaming in client-side (e.g., RN SDK transition to foreground).
|
|
263
265
|
},
|
|
264
|
-
// Start/resume push mode
|
|
266
|
+
// Start/resume push mode.
|
|
267
|
+
// It eventually emits PUSH_SUBSYSTEM_DOWN, that starts polling, or PUSH_SUBSYSTEM_UP, that executes a syncAll
|
|
265
268
|
start: function () {
|
|
266
269
|
// Guard condition to avoid calling `connectPush` again if the `start` method is called multiple times or if push has been disabled.
|
|
267
270
|
if (disabled || disconnected === false)
|
|
@@ -272,6 +275,10 @@ export function pushManagerFactory(params, pollingManager) {
|
|
|
272
275
|
else
|
|
273
276
|
setTimeout(connectPush); // server-side runs in next cycle as in client-side, for consistency with client-side
|
|
274
277
|
},
|
|
278
|
+
// true/false if start or stop was called last respectively
|
|
279
|
+
isRunning: function () {
|
|
280
|
+
return disconnected === false;
|
|
281
|
+
},
|
|
275
282
|
// [Only for client-side]
|
|
276
283
|
add: function (userKey, mySegmentsSyncTask) {
|
|
277
284
|
var hash = hashUserKey(userKey);
|
|
@@ -1,28 +1,40 @@
|
|
|
1
1
|
import { submitterSyncTaskFactory } from './submitterSyncTask';
|
|
2
|
-
import {
|
|
2
|
+
import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
3
|
+
var DATA_NAME = 'events';
|
|
3
4
|
/**
|
|
4
5
|
* Sync task that periodically posts tracked events
|
|
5
6
|
*/
|
|
6
7
|
export function eventsSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, eventsFirstPushWindow, latencyTracker) {
|
|
7
8
|
// don't retry events.
|
|
8
|
-
var syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate,
|
|
9
|
-
// Set a timer for the first push of events
|
|
9
|
+
var syncTask = submitterSyncTaskFactory(log, postEventsBulk, eventsCache, eventsPushRate, DATA_NAME, latencyTracker);
|
|
10
|
+
// Set a timer for the first push window of events.
|
|
11
|
+
// Not implemented in the base submitter or sync task, since this feature is only used by the events submitter.
|
|
10
12
|
if (eventsFirstPushWindow > 0) {
|
|
13
|
+
var running_1 = false;
|
|
11
14
|
var stopEventPublisherTimeout_1;
|
|
12
15
|
var originalStart_1 = syncTask.start;
|
|
13
16
|
syncTask.start = function () {
|
|
17
|
+
running_1 = true;
|
|
14
18
|
stopEventPublisherTimeout_1 = setTimeout(originalStart_1, eventsFirstPushWindow);
|
|
15
19
|
};
|
|
16
20
|
var originalStop_1 = syncTask.stop;
|
|
17
21
|
syncTask.stop = function () {
|
|
22
|
+
running_1 = false;
|
|
18
23
|
clearTimeout(stopEventPublisherTimeout_1);
|
|
19
24
|
originalStop_1();
|
|
20
25
|
};
|
|
26
|
+
syncTask.isRunning = function () {
|
|
27
|
+
return running_1;
|
|
28
|
+
};
|
|
21
29
|
}
|
|
22
|
-
// register
|
|
30
|
+
// register events submitter to be executed when events cache is full
|
|
23
31
|
eventsCache.setOnFullQueueCb(function () {
|
|
24
|
-
|
|
25
|
-
|
|
32
|
+
if (syncTask.isRunning()) {
|
|
33
|
+
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
34
|
+
syncTask.execute();
|
|
35
|
+
}
|
|
36
|
+
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
37
|
+
// Data will be sent when submitter is resumed.
|
|
26
38
|
});
|
|
27
39
|
return syncTask;
|
|
28
40
|
}
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { groupBy, forOwn } from '../../utils/lang';
|
|
2
2
|
import { submitterSyncTaskFactory } from './submitterSyncTask';
|
|
3
|
+
import { SUBMITTERS_PUSH_FULL_QUEUE } from '../../logger/constants';
|
|
4
|
+
var DATA_NAME = 'impressions';
|
|
3
5
|
/**
|
|
4
6
|
* Converts `impressions` data from cache into request payload.
|
|
5
7
|
*/
|
|
@@ -32,5 +34,15 @@ export function fromImpressionsCollector(sendLabels, data) {
|
|
|
32
34
|
export function impressionsSyncTaskFactory(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, sendLabels, latencyTracker) {
|
|
33
35
|
if (sendLabels === void 0) { sendLabels = false; }
|
|
34
36
|
// retry impressions only once.
|
|
35
|
-
|
|
37
|
+
var syncTask = submitterSyncTaskFactory(log, postTestImpressionsBulk, impressionsCache, impressionsRefreshRate, DATA_NAME, latencyTracker, fromImpressionsCollector.bind(undefined, sendLabels), 1);
|
|
38
|
+
// register impressions submitter to be executed when impressions cache is full
|
|
39
|
+
impressionsCache.setOnFullQueueCb(function () {
|
|
40
|
+
if (syncTask.isRunning()) {
|
|
41
|
+
log.info(SUBMITTERS_PUSH_FULL_QUEUE, [DATA_NAME]);
|
|
42
|
+
syncTask.execute();
|
|
43
|
+
}
|
|
44
|
+
// If submitter is stopped (e.g., user consent declined or unknown, or app state offline), we don't send the data.
|
|
45
|
+
// Data will be sent when submitter is resumed.
|
|
46
|
+
});
|
|
47
|
+
return syncTask;
|
|
36
48
|
}
|
|
@@ -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 '../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();
|
|
@@ -1,13 +1,17 @@
|
|
|
1
1
|
import { objectAssign } from '../utils/lang/objectAssign';
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import { EVENTS_TRACKER_SUCCESS, ERROR_EVENTS_TRACKER } from '../logger/constants';
|
|
4
|
+
import { CONSENT_DECLINED } from '../utils/constants';
|
|
5
|
+
import { isStorageSync } from './impressionObserver/utils';
|
|
4
6
|
/**
|
|
5
7
|
* Event tracker stores events in cache and pass them to the integrations manager if provided.
|
|
6
8
|
*
|
|
7
9
|
* @param eventsCache cache to save events
|
|
8
10
|
* @param integrationsManager optional event handler used for integrations
|
|
9
11
|
*/
|
|
10
|
-
export function eventTrackerFactory(
|
|
12
|
+
export function eventTrackerFactory(settings, eventsCache, integrationsManager) {
|
|
13
|
+
var log = settings.log;
|
|
14
|
+
var isSync = isStorageSync(settings);
|
|
11
15
|
function queueEventsCallback(eventData, tracked) {
|
|
12
16
|
var eventTypeId = eventData.eventTypeId, trafficTypeName = eventData.trafficTypeName, key = eventData.key, value = eventData.value, timestamp = eventData.timestamp, properties = eventData.properties;
|
|
13
17
|
// Logging every prop would be too much.
|
|
@@ -33,6 +37,9 @@ export function eventTrackerFactory(log, eventsCache, integrationsManager) {
|
|
|
33
37
|
}
|
|
34
38
|
return {
|
|
35
39
|
track: function (eventData, size) {
|
|
40
|
+
if (settings.userConsent === CONSENT_DECLINED) {
|
|
41
|
+
return isSync ? false : Promise.resolve(false);
|
|
42
|
+
}
|
|
36
43
|
var tracked = eventsCache.track(eventData, size);
|
|
37
44
|
if (thenable(tracked)) {
|
|
38
45
|
return tracked.then(queueEventsCallback.bind(null, eventData));
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
|
|
1
|
+
import { CONSUMER_MODE, CONSUMER_PARTIAL_MODE, OPTIMIZED, PRODUCER_MODE, STANDALONE_MODE } from '../../utils/constants';
|
|
2
2
|
/**
|
|
3
3
|
* Checks if impressions previous time should be added or not.
|
|
4
4
|
*/
|
|
@@ -13,3 +13,9 @@ export function shouldBeOptimized(settings) {
|
|
|
13
13
|
return false;
|
|
14
14
|
return settings.sync.impressionsMode === OPTIMIZED ? true : false;
|
|
15
15
|
}
|
|
16
|
+
/**
|
|
17
|
+
* Storage is async if mode is consumer or partial consumer
|
|
18
|
+
*/
|
|
19
|
+
export function isStorageSync(settings) {
|
|
20
|
+
return [CONSUMER_MODE, CONSUMER_PARTIAL_MODE].indexOf(settings.mode) === -1 ? true : false;
|
|
21
|
+
}
|
|
@@ -2,6 +2,7 @@ import { objectAssign } from '../utils/lang/objectAssign';
|
|
|
2
2
|
import { thenable } from '../utils/promise/thenable';
|
|
3
3
|
import { truncateTimeFrame } from '../utils/time';
|
|
4
4
|
import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIONS_LISTENER } from '../logger/constants';
|
|
5
|
+
import { CONSENT_DECLINED } from '../utils/constants';
|
|
5
6
|
/**
|
|
6
7
|
* Impressions tracker stores impressions in cache and pass them to the listener and integrations manager if provided.
|
|
7
8
|
*
|
|
@@ -12,16 +13,16 @@ import { IMPRESSIONS_TRACKER_SUCCESS, ERROR_IMPRESSIONS_TRACKER, ERROR_IMPRESSIO
|
|
|
12
13
|
* @param observer optional impression observer. If provided, previous time (pt property) is included in impression instances
|
|
13
14
|
* @param countsCache optional cache to save impressions count. If provided, impressions will be deduped (OPTIMIZED mode)
|
|
14
15
|
*/
|
|
15
|
-
export function impressionsTrackerFactory(
|
|
16
|
-
// @TODO consider passing only an optional integrationsManager to handle impressions
|
|
17
|
-
_a, impressionListener, integrationsManager,
|
|
16
|
+
export function impressionsTrackerFactory(settings, impressionsCache, integrationsManager,
|
|
18
17
|
// if observer is provided, it implies `shouldAddPreviousTime` flag (i.e., if impressions previous time should be added or not)
|
|
19
18
|
observer,
|
|
20
19
|
// if countsCache is provided, it implies `isOptimized` flag (i.e., if impressions should be deduped or not)
|
|
21
20
|
countsCache) {
|
|
22
|
-
var
|
|
21
|
+
var log = settings.log, impressionListener = settings.impressionListener, _a = settings.runtime, ip = _a.ip, hostname = _a.hostname, version = settings.version;
|
|
23
22
|
return {
|
|
24
23
|
track: function (impressions, attributes) {
|
|
24
|
+
if (settings.userConsent === CONSENT_DECLINED)
|
|
25
|
+
return;
|
|
25
26
|
var impressionsCount = impressions.length;
|
|
26
27
|
var impressionsToStore = []; // Track only the impressions that are going to be stored
|
|
27
28
|
// Wraps impressions to store and adds previousTime if it corresponds
|
|
@@ -65,7 +66,7 @@ countsCache) {
|
|
|
65
66
|
// integrationsManager.handleImpression does not throw errors
|
|
66
67
|
if (integrationsManager)
|
|
67
68
|
integrationsManager.handleImpression(impressionData);
|
|
68
|
-
try { // An exception on the listeners should not break the SDK.
|
|
69
|
+
try { // @ts-ignore. An exception on the listeners should not break the SDK.
|
|
69
70
|
if (impressionListener)
|
|
70
71
|
impressionListener.logImpression(impressionData);
|
|
71
72
|
}
|
|
@@ -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
|
|
@@ -3,7 +3,7 @@ import { validateAttribute } from './attribute';
|
|
|
3
3
|
import { ERROR_NOT_PLAIN_OBJECT } from '../../logger/constants';
|
|
4
4
|
export function validateAttributes(log, maybeAttrs, method) {
|
|
5
5
|
// Attributes are optional
|
|
6
|
-
if (
|
|
6
|
+
if (maybeAttrs == undefined || isObject(maybeAttrs)) // eslint-disable-line eqeqeq
|
|
7
7
|
return maybeAttrs;
|
|
8
8
|
log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'attributes']);
|
|
9
9
|
return false;
|
|
@@ -35,7 +35,8 @@ export function validateKey(log, maybeKey, method) {
|
|
|
35
35
|
var bucketingKey = validateKeyValue(log, maybeKey.bucketingKey, method, 'bucketingKey');
|
|
36
36
|
if (matchingKey && bucketingKey)
|
|
37
37
|
return {
|
|
38
|
-
matchingKey: matchingKey,
|
|
38
|
+
matchingKey: matchingKey,
|
|
39
|
+
bucketingKey: bucketingKey
|
|
39
40
|
};
|
|
40
41
|
log.error(ERROR_INVALID_KEY_OBJECT, [method]);
|
|
41
42
|
return false;
|