@splitsoftware/splitio-commons 1.8.2-rc.0 → 1.8.2-rc.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGES.txt +24 -22
- package/README.md +1 -1
- package/cjs/logger/constants.js +3 -3
- package/cjs/logger/messages/debug.js +7 -7
- package/cjs/logger/messages/error.js +2 -2
- package/cjs/logger/messages/info.js +3 -3
- package/cjs/logger/messages/warn.js +7 -7
- package/cjs/sdkClient/client.js +20 -20
- package/cjs/sdkClient/clientAttributesDecoration.js +8 -8
- package/cjs/sdkClient/clientInputValidation.js +10 -10
- package/cjs/sdkClient/sdkClient.js +1 -1
- package/cjs/sdkFactory/index.js +1 -1
- package/cjs/sdkManager/index.js +10 -8
- package/cjs/services/splitApi.js +1 -0
- package/cjs/services/splitHttpClient.js +1 -1
- package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +6 -10
- package/cjs/storages/inMemory/SplitsCacheInMemory.js +8 -16
- package/cjs/storages/inRedis/SplitsCacheInRedis.js +20 -23
- package/cjs/storages/pluggable/SplitsCachePluggable.js +18 -18
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +5 -12
- package/cjs/sync/streaming/pushManager.js +1 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +2 -2
- package/cjs/utils/inputValidation/apiKey.js +26 -25
- package/cjs/utils/inputValidation/preloadedData.js +3 -3
- package/cjs/utils/inputValidation/split.js +1 -1
- package/cjs/utils/inputValidation/splits.js +2 -2
- package/cjs/utils/settingsValidation/index.js +1 -1
- package/esm/logger/constants.js +2 -2
- package/esm/logger/messages/debug.js +7 -7
- package/esm/logger/messages/error.js +2 -2
- package/esm/logger/messages/info.js +3 -3
- package/esm/logger/messages/warn.js +7 -7
- package/esm/sdkClient/client.js +20 -20
- package/esm/sdkClient/clientAttributesDecoration.js +8 -8
- package/esm/sdkClient/clientInputValidation.js +10 -10
- package/esm/sdkClient/sdkClient.js +1 -1
- package/esm/sdkFactory/index.js +1 -1
- package/esm/sdkManager/index.js +10 -8
- package/esm/services/splitApi.js +1 -0
- package/esm/services/splitHttpClient.js +1 -1
- package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +6 -10
- package/esm/storages/inMemory/SplitsCacheInMemory.js +8 -16
- package/esm/storages/inRedis/SplitsCacheInRedis.js +20 -23
- package/esm/storages/pluggable/SplitsCachePluggable.js +18 -18
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
- package/esm/sync/polling/updaters/splitChangesUpdater.js +5 -12
- package/esm/sync/streaming/pushManager.js +1 -1
- package/esm/sync/submitters/telemetrySubmitter.js +2 -2
- package/esm/utils/inputValidation/apiKey.js +27 -26
- package/esm/utils/inputValidation/preloadedData.js +3 -3
- package/esm/utils/inputValidation/split.js +1 -1
- package/esm/utils/inputValidation/splits.js +2 -2
- package/esm/utils/settingsValidation/index.js +1 -1
- package/package.json +1 -1
- package/src/logger/constants.ts +2 -2
- package/src/logger/messages/debug.ts +7 -7
- package/src/logger/messages/error.ts +2 -2
- package/src/logger/messages/info.ts +3 -3
- package/src/logger/messages/warn.ts +7 -7
- package/src/sdkClient/client.ts +20 -20
- package/src/sdkClient/clientAttributesDecoration.ts +10 -10
- package/src/sdkClient/clientInputValidation.ts +10 -10
- package/src/sdkClient/sdkClient.ts +3 -3
- package/src/sdkFactory/index.ts +1 -1
- package/src/sdkManager/index.ts +11 -8
- package/src/services/splitApi.ts +1 -0
- package/src/services/splitHttpClient.ts +1 -1
- package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +6 -10
- package/src/storages/inMemory/AttributesCacheInMemory.ts +7 -6
- package/src/storages/inMemory/SplitsCacheInMemory.ts +6 -14
- package/src/storages/inRedis/SplitsCacheInRedis.ts +19 -20
- package/src/storages/pluggable/SplitsCachePluggable.ts +17 -18
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
- package/src/sync/polling/updaters/splitChangesUpdater.ts +6 -12
- package/src/sync/streaming/pushManager.ts +1 -1
- package/src/sync/submitters/telemetrySubmitter.ts +2 -2
- package/src/types.ts +147 -140
- package/src/utils/inputValidation/apiKey.ts +25 -24
- package/src/utils/inputValidation/preloadedData.ts +3 -3
- package/src/utils/inputValidation/split.ts +1 -1
- package/src/utils/inputValidation/splits.ts +1 -1
- package/src/utils/settingsValidation/index.ts +1 -1
- package/types/logger/constants.d.ts +1 -1
- package/types/sdkClient/clientAttributesDecoration.d.ts +7 -7
- package/types/storages/inMemory/AttributesCacheInMemory.d.ts +4 -3
- package/types/types.d.ts +142 -135
- package/types/utils/inputValidation/apiKey.d.ts +5 -5
- package/types/utils/inputValidation/sdkKey.d.ts +7 -0
- package/types/utils/settingsValidation/index.d.ts +1 -1
- package/types/storages/metadataBuilder.d.ts +0 -3
- /package/types/storages/inMemory/{uniqueKeysCacheInMemory.d.ts → UniqueKeysCacheInMemory.d.ts} +0 -0
- /package/types/storages/inMemory/{uniqueKeysCacheInMemoryCS.d.ts → UniqueKeysCacheInMemoryCS.d.ts} +0 -0
- /package/types/storages/inRedis/{uniqueKeysCacheInRedis.d.ts → UniqueKeysCacheInRedis.d.ts} +0 -0
package/CHANGES.txt
CHANGED
|
@@ -1,42 +1,44 @@
|
|
|
1
|
-
1.8.2 (
|
|
2
|
-
- Updated
|
|
1
|
+
1.8.2 (May 15, 2023)
|
|
2
|
+
- Updated terminology on the SDKs codebase to be more aligned with current standard without causing a breaking change. The core change is the term split for feature flag on things like logs and intensense comments.
|
|
3
|
+
- Updated split storage modules to optimize some operations when using Redis and pluggable storages.
|
|
4
|
+
- Updated some transitive dependencies for vulnerability fixes.
|
|
3
5
|
|
|
4
6
|
1.8.1 (February 7, 2023)
|
|
5
|
-
- Updated a module import to remove a trailing comma that can cause issues with some bundlers.
|
|
7
|
+
- Updated a module import to remove a trailing comma that can cause issues with some bundlers.
|
|
6
8
|
|
|
7
9
|
1.8.0 (February 3, 2023)
|
|
8
|
-
- Added flush data method to client
|
|
10
|
+
- Added flush data method to client.
|
|
9
11
|
|
|
10
12
|
1.7.3 (December 16, 2022)
|
|
11
|
-
- Updated unique keys cache for Redis and Pluggable storages to optimize the usage of the underlying storage.
|
|
12
|
-
- Updated some transitive dependencies for vulnerability fixes.
|
|
13
|
-
- Bugfixing - Updated events and impressions cache in localhost mode in order to avoid memory leaks (Related to issue https://github.com/splitio/javascript-commons/issues/181).
|
|
13
|
+
- Updated unique keys cache for Redis and Pluggable storages to optimize the usage of the underlying storage.
|
|
14
|
+
- Updated some transitive dependencies for vulnerability fixes.
|
|
15
|
+
- Bugfixing - Updated events and impressions cache in localhost mode in order to avoid memory leaks (Related to issue https://github.com/splitio/javascript-commons/issues/181).
|
|
14
16
|
|
|
15
17
|
1.7.2 (October 14, 2022)
|
|
16
|
-
- Bugfixing - Handle `Navigator.sendBeacon` API exceptions in the browser, and fallback to regular Fetch/XHR transport in case of error.
|
|
18
|
+
- Bugfixing - Handle `Navigator.sendBeacon` API exceptions in the browser, and fallback to regular Fetch/XHR transport in case of error.
|
|
17
19
|
|
|
18
20
|
1.7.1 (October 5, 2022)
|
|
19
|
-
- Updated default value of `scheduler.featuresRefreshRate` config parameter to 60 seconds.
|
|
21
|
+
- Updated default value of `scheduler.featuresRefreshRate` config parameter to 60 seconds.
|
|
20
22
|
|
|
21
23
|
1.7.0 (October 4, 2022)
|
|
22
|
-
- Added a new impressions mode for the SDK called NONE, to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
|
|
23
|
-
- Updated SDK telemetry to support pluggable storage, partial consumer mode, and synchronizer.
|
|
24
|
-
- Updated storage implementations to improve the performance of
|
|
25
|
-
- Updated evaluation flow to avoid unnecessarily storage calls when the SDK is not ready.
|
|
24
|
+
- Added a new impressions mode for the SDK called NONE, to be used in factory when there is no desire to capture impressions on an SDK factory to feed Split's analytics engine. Running NONE mode, the SDK will only capture unique keys evaluated for a particular feature flag instead of full blown impressions.
|
|
25
|
+
- Updated SDK telemetry to support pluggable storage, partial consumer mode, and synchronizer.
|
|
26
|
+
- Updated storage implementations to improve the performance of feature flag evaluations (i.e., `getTreatment(s)` method calls) when using the default storage in memory.
|
|
27
|
+
- Updated evaluation flow to avoid unnecessarily storage calls when the SDK is not ready.
|
|
26
28
|
|
|
27
29
|
1.6.1 (July 22, 2022)
|
|
28
|
-
- Updated GoogleAnalyticsToSplit integration to validate `autoRequire` config parameter and avoid some wrong warning logs when mapping GA hit fields to Split event properties.
|
|
30
|
+
- Updated GoogleAnalyticsToSplit integration to validate `autoRequire` config parameter and avoid some wrong warning logs when mapping GA hit fields to Split event properties.
|
|
29
31
|
|
|
30
32
|
1.6.0 (July 21, 2022)
|
|
31
|
-
- Added `autoRequire` configuration option to the Google Analytics to Split integration, which takes care of requiring the splitTracker plugin on trackers dynamically created by Google tag managers (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
|
|
32
|
-
- Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in modern mobile and desktop Web browsers.
|
|
33
|
-
- Updated the synchronization flow to be more reliable in the event of an edge case generating delay in cache purge propagation, keeping the SDK cache properly synced.
|
|
34
|
-
- Bugfixing - Removed js-yaml dependency to avoid resolution to an incompatible version on certain npm versions when installing third-party dependencies that also define js-yaml as transitive dependency (Related to issue https://github.com/splitio/javascript-client/issues/662).
|
|
33
|
+
- Added `autoRequire` configuration option to the Google Analytics to Split integration, which takes care of requiring the splitTracker plugin on trackers dynamically created by Google tag managers (See https://help.split.io/hc/en-us/articles/360040838752#set-up-with-gtm-and-gtag.js).
|
|
34
|
+
- Updated browser listener to push remaining impressions and events on 'visibilitychange' and 'pagehide' DOM events, instead of 'unload', which is not reliable in modern mobile and desktop Web browsers.
|
|
35
|
+
- Updated the synchronization flow to be more reliable in the event of an edge case generating delay in cache purge propagation, keeping the SDK cache properly synced.
|
|
36
|
+
- Bugfixing - Removed js-yaml dependency to avoid resolution to an incompatible version on certain npm versions when installing third-party dependencies that also define js-yaml as transitive dependency (Related to issue https://github.com/splitio/javascript-client/issues/662).
|
|
35
37
|
|
|
36
38
|
1.5.0 (June 29, 2022)
|
|
37
|
-
- Added a new config option to control the tasks that listen or poll for updates on feature flags and segments, via the new config sync.enabled . Running online Split will always pull the most recent updates upon initialization, this only affects updates fetching on a running instance. Useful when a consistent session experience is a must or to save resources when updates are not being used.
|
|
38
|
-
- Updated telemetry logic to track the anonymous config for user consent flag set to declined or unknown.
|
|
39
|
-
- Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while its periodic post of impressions is running.
|
|
39
|
+
- Added a new config option to control the tasks that listen or poll for updates on feature flags and segments, via the new config sync.enabled . Running online, Split SDK will always pull the most recent updates upon initialization, this only affects updates fetching on a running instance. Useful when a consistent session experience is a must or to save resources when updates are not being used.
|
|
40
|
+
- Updated telemetry logic to track the anonymous config for user consent flag set to declined or unknown.
|
|
41
|
+
- Updated submitters logic, to avoid duplicating the post of impressions to Split cloud when the SDK is destroyed while its periodic post of impressions is running.
|
|
40
42
|
|
|
41
43
|
1.4.1 (June 13, 2022)
|
|
42
44
|
- Bugfixing - Updated submitters logic, to avoid dropping impressions and events that are being tracked while POST request is pending.
|
|
@@ -84,7 +86,7 @@
|
|
|
84
86
|
- Updated dependencies for vulnerability fixes.
|
|
85
87
|
|
|
86
88
|
0.1.0 (March 30, 2021)
|
|
87
|
-
- Initial public release. It includes common modules to be consumed by the different Split implementations written in JavaScript. Based on the original JS SDK in the `javascript-client` repository.
|
|
89
|
+
- Initial public release. It includes common modules to be consumed by the different Split SDK implementations written in JavaScript. Based on the original JS SDK in the `javascript-client` repository.
|
|
88
90
|
- It's designed with a modular approach, with the following goals in mind:
|
|
89
91
|
- Dependents should be able to include the modules that are needed for, as an example, a storage.
|
|
90
92
|
- Dependents should be able to use the module that's specific for their runtime environment, allowing for better usage of native APIs as well as to build optimizations targeted by each platform.
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
[](https://badge.fury.io/js/%40splitsoftware%2Fsplitio-commons) [](https://github.com/splitio/javascript-commons/actions/workflows/ci.yml)
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
|
-
This library is designed to work with Split, the platform for controlled rollouts, which serves features to your users via
|
|
6
|
+
This library is designed to work with Split, the platform for controlled rollouts, which serves features to your users via feature flags to manage your complete customer experience.
|
|
7
7
|
|
|
8
8
|
[](https://twitter.com/intent/follow?screen_name=splitsoftware)
|
|
9
9
|
|
package/cjs/logger/constants.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
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.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.
|
|
4
|
+
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_SDK_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_INITIAL = exports.USER_CONSENT_NOT_UPDATED = 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
5
|
exports.LOG_PREFIX_CLEANUP = exports.LOG_PREFIX_UNIQUE_KEYS_TRACKER = 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_MIN_CONFIG_PARAM = 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 = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* Message codes used to trim string log messages from commons and client-side API modules,
|
|
@@ -97,7 +97,7 @@ exports.WARN_INTEGRATION_INVALID = 218;
|
|
|
97
97
|
exports.WARN_SPLITS_FILTER_IGNORED = 219;
|
|
98
98
|
exports.WARN_SPLITS_FILTER_INVALID = 220;
|
|
99
99
|
exports.WARN_SPLITS_FILTER_EMPTY = 221;
|
|
100
|
-
exports.
|
|
100
|
+
exports.WARN_SDK_KEY = 222;
|
|
101
101
|
exports.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2 = 223;
|
|
102
102
|
exports.ERROR_ENGINE_COMBINER_IFELSEIF = 300;
|
|
103
103
|
exports.ERROR_LOGLEVEL_INVALID = 301;
|
|
@@ -137,7 +137,7 @@ exports.LOG_PREFIX_SYNC = 'sync';
|
|
|
137
137
|
exports.LOG_PREFIX_SYNC_MANAGER = exports.LOG_PREFIX_SYNC + ':sync-manager: ';
|
|
138
138
|
exports.LOG_PREFIX_SYNC_OFFLINE = exports.LOG_PREFIX_SYNC + ':offline: ';
|
|
139
139
|
exports.LOG_PREFIX_SYNC_STREAMING = exports.LOG_PREFIX_SYNC + ':streaming: ';
|
|
140
|
-
exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC + ':
|
|
140
|
+
exports.LOG_PREFIX_SYNC_SPLITS = exports.LOG_PREFIX_SYNC + ':featureflag-changes: ';
|
|
141
141
|
exports.LOG_PREFIX_SYNC_SEGMENTS = exports.LOG_PREFIX_SYNC + ':segment-changes: ';
|
|
142
142
|
exports.LOG_PREFIX_SYNC_MYSEGMENTS = exports.LOG_PREFIX_SYNC + ':my-segments: ';
|
|
143
143
|
exports.LOG_PREFIX_SYNC_POLLING = exports.LOG_PREFIX_SYNC + ':polling-manager: ';
|
|
@@ -16,8 +16,8 @@ exports.codesDebug = info_1.codesInfo.concat([
|
|
|
16
16
|
[c.ENGINE_MATCHER_CONTAINS_ALL, c.LOG_PREFIX_ENGINE_MATCHER + '[containsAllMatcher] %s contains all elements of %s? %s'],
|
|
17
17
|
[c.ENGINE_MATCHER_CONTAINS_ANY, c.LOG_PREFIX_ENGINE_MATCHER + '[containsAnyMatcher] %s contains at least an element of %s? %s'],
|
|
18
18
|
[c.ENGINE_MATCHER_CONTAINS_STRING, c.LOG_PREFIX_ENGINE_MATCHER + '[containsStringMatcher] %s contains %s? %s'],
|
|
19
|
-
[c.ENGINE_MATCHER_DEPENDENCY, c.LOG_PREFIX_ENGINE_MATCHER + '[dependencyMatcher] parent
|
|
20
|
-
[c.ENGINE_MATCHER_DEPENDENCY_PRE, c.LOG_PREFIX_ENGINE_MATCHER + '[dependencyMatcher] will evaluate parent
|
|
19
|
+
[c.ENGINE_MATCHER_DEPENDENCY, c.LOG_PREFIX_ENGINE_MATCHER + '[dependencyMatcher] parent feature flag "%s" evaluated to "%s" with label "%s". %s evaluated treatment is part of [%s] ? %s.'],
|
|
20
|
+
[c.ENGINE_MATCHER_DEPENDENCY_PRE, c.LOG_PREFIX_ENGINE_MATCHER + '[dependencyMatcher] will evaluate parent feature flag: "%s" with key: %s %s'],
|
|
21
21
|
[c.ENGINE_MATCHER_EQUAL, c.LOG_PREFIX_ENGINE_MATCHER + '[equalToMatcher] is %s equal to %s? %s'],
|
|
22
22
|
[c.ENGINE_MATCHER_EQUAL_TO_SET, c.LOG_PREFIX_ENGINE_MATCHER + '[equalToSetMatcher] is %s equal to set %s? %s'],
|
|
23
23
|
[c.ENGINE_MATCHER_ENDS_WITH, c.LOG_PREFIX_ENGINE_MATCHER + '[endsWithMatcher] %s ends with %s? %s'],
|
|
@@ -38,15 +38,15 @@ exports.codesDebug = info_1.codesInfo.concat([
|
|
|
38
38
|
[c.RETRIEVE_CLIENT_EXISTING, 'Retrieving existing SDK client.'],
|
|
39
39
|
[c.RETRIEVE_MANAGER, 'Retrieving manager instance.'],
|
|
40
40
|
// synchronizer
|
|
41
|
-
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + '
|
|
42
|
-
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up
|
|
43
|
-
[c.SYNC_SPLITS_NEW, c.LOG_PREFIX_SYNC_SPLITS + 'New
|
|
44
|
-
[c.SYNC_SPLITS_REMOVED, c.LOG_PREFIX_SYNC_SPLITS + 'Removed
|
|
41
|
+
[c.SYNC_OFFLINE_DATA, c.LOG_PREFIX_SYNC_OFFLINE + 'Feature flags data: \n%s'],
|
|
42
|
+
[c.SYNC_SPLITS_FETCH, c.LOG_PREFIX_SYNC_SPLITS + 'Spin up feature flags update using since = %s'],
|
|
43
|
+
[c.SYNC_SPLITS_NEW, c.LOG_PREFIX_SYNC_SPLITS + 'New feature flags %s'],
|
|
44
|
+
[c.SYNC_SPLITS_REMOVED, c.LOG_PREFIX_SYNC_SPLITS + 'Removed feature flags %s'],
|
|
45
45
|
[c.SYNC_SPLITS_SEGMENTS, c.LOG_PREFIX_SYNC_SPLITS + 'Segment names collected %s'],
|
|
46
46
|
[c.STREAMING_NEW_MESSAGE, c.LOG_PREFIX_SYNC_STREAMING + 'New SSE message received, with data: %s.'],
|
|
47
47
|
[c.SYNC_TASK_START, c.LOG_PREFIX_SYNC + ': Starting %s. Running each %s millis'],
|
|
48
48
|
[c.SYNC_TASK_EXECUTE, c.LOG_PREFIX_SYNC + ': Running %s'],
|
|
49
49
|
[c.SYNC_TASK_STOP, c.LOG_PREFIX_SYNC + ': Stopping %s'],
|
|
50
50
|
// initialization / settings validation
|
|
51
|
-
[c.SETTINGS_SPLITS_FILTER, c.LOG_PREFIX_SETTINGS + ':
|
|
51
|
+
[c.SETTINGS_SPLITS_FILTER, c.LOG_PREFIX_SETTINGS + ': feature flags filtering criteria is "%s".']
|
|
52
52
|
]);
|
|
@@ -5,7 +5,7 @@ var tslib_1 = require("tslib");
|
|
|
5
5
|
var c = (0, tslib_1.__importStar)(require("../constants"));
|
|
6
6
|
exports.codesError = [
|
|
7
7
|
// evaluator
|
|
8
|
-
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid
|
|
8
|
+
[c.ERROR_ENGINE_COMBINER_IFELSEIF, c.LOG_PREFIX_ENGINE_COMBINER + 'Invalid feature flag, no valid rules found'],
|
|
9
9
|
// SDK
|
|
10
10
|
[c.ERROR_LOGLEVEL_INVALID, 'logger: Invalid Log Level - No changes to the logs will be applied.'],
|
|
11
11
|
[c.ERROR_CLIENT_CANNOT_GET_READY, 'The SDK will not get ready. Reason: %s'],
|
|
@@ -13,7 +13,7 @@ exports.codesError = [
|
|
|
13
13
|
[c.ERROR_IMPRESSIONS_LISTENER, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Impression listener logImpression method threw: %s.'],
|
|
14
14
|
[c.ERROR_EVENTS_TRACKER, c.LOG_PREFIX_EVENTS_TRACKER + 'Failed to queue %s'],
|
|
15
15
|
// synchronizer
|
|
16
|
-
[c.ERROR_SYNC_OFFLINE_LOADING, c.LOG_PREFIX_SYNC_OFFLINE + 'There was an issue loading the mock
|
|
16
|
+
[c.ERROR_SYNC_OFFLINE_LOADING, c.LOG_PREFIX_SYNC_OFFLINE + 'There was an issue loading the mock feature flags 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
19
|
[c.ERROR_HTTP, 'Response status is not OK. Status: %s. URL: %s. Message: %s'],
|
|
@@ -10,7 +10,7 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
10
10
|
[c.CLIENT_READY_FROM_CACHE, READY_MSG + ' from cache'],
|
|
11
11
|
[c.CLIENT_READY, READY_MSG],
|
|
12
12
|
// SDK
|
|
13
|
-
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER + '
|
|
13
|
+
[c.IMPRESSION, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Feature flag: %s. Key: %s. Evaluation: %s. Label: %s'],
|
|
14
14
|
[c.IMPRESSION_QUEUEING, c.LOG_PREFIX_IMPRESSIONS_TRACKER + 'Queueing corresponding impression.'],
|
|
15
15
|
[c.NEW_SHARED_CLIENT, 'New shared client instance created.'],
|
|
16
16
|
[c.NEW_FACTORY, 'New Split SDK instance created.'],
|
|
@@ -23,13 +23,13 @@ exports.codesInfo = warn_1.codesWarn.concat([
|
|
|
23
23
|
[c.POLLING_SMART_PAUSING, c.LOG_PREFIX_SYNC_POLLING + 'Turning segments data polling %s.'],
|
|
24
24
|
[c.POLLING_START, c.LOG_PREFIX_SYNC_POLLING + 'Starting polling'],
|
|
25
25
|
[c.POLLING_STOP, c.LOG_PREFIX_SYNC_POLLING + 'Stopping polling'],
|
|
26
|
-
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of
|
|
26
|
+
[c.SYNC_SPLITS_FETCH_RETRY, c.LOG_PREFIX_SYNC_SPLITS + 'Retrying download of feature flags #%s. Reason: %s'],
|
|
27
27
|
[c.SUBMITTERS_PUSH_FULL_QUEUE, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing full %s queue and reseting timer.'],
|
|
28
28
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
29
29
|
[c.STREAMING_REFRESH_TOKEN, c.LOG_PREFIX_SYNC_STREAMING + 'Refreshing streaming token in %s seconds, and connecting streaming in %s seconds.'],
|
|
30
30
|
[c.STREAMING_RECONNECT, c.LOG_PREFIX_SYNC_STREAMING + 'Attempting to reconnect streaming in %s seconds.'],
|
|
31
31
|
[c.STREAMING_CONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Connecting streaming.'],
|
|
32
|
-
[c.STREAMING_DISABLED, c.LOG_PREFIX_SYNC_STREAMING + 'Streaming is disabled for given
|
|
32
|
+
[c.STREAMING_DISABLED, c.LOG_PREFIX_SYNC_STREAMING + 'Streaming is disabled for given SDK key. Switching to polling mode.'],
|
|
33
33
|
[c.STREAMING_DISCONNECTING, c.LOG_PREFIX_SYNC_STREAMING + 'Disconnecting streaming.'],
|
|
34
34
|
[c.SYNC_START_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming not available. Starting polling.'],
|
|
35
35
|
[c.SYNC_CONTINUE_POLLING, c.LOG_PREFIX_SYNC_MANAGER + 'Streaming couldn\'t connect. Continue polling.'],
|
|
@@ -10,7 +10,7 @@ exports.codesWarn = error_1.codesError.concat([
|
|
|
10
10
|
[c.ENGINE_VALUE_NO_ATTRIBUTES, c.LOG_PREFIX_ENGINE_VALUE + 'Defined attribute [%s], no attributes received.'],
|
|
11
11
|
// synchronizer
|
|
12
12
|
[c.SYNC_MYSEGMENTS_FETCH_RETRY, c.LOG_PREFIX_SYNC_MYSEGMENTS + 'Retrying download of segments #%s. Reason: %s'],
|
|
13
|
-
[c.SYNC_SPLITS_FETCH_FAILS, c.LOG_PREFIX_SYNC_SPLITS + 'Error while doing fetch of
|
|
13
|
+
[c.SYNC_SPLITS_FETCH_FAILS, c.LOG_PREFIX_SYNC_SPLITS + 'Error while doing fetch of feature flags. %s'],
|
|
14
14
|
[c.STREAMING_PARSING_ERROR_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE error notification: %s'],
|
|
15
15
|
[c.STREAMING_PARSING_MESSAGE_FAILS, c.LOG_PREFIX_SYNC_STREAMING + 'Error parsing SSE message notification: %s'],
|
|
16
16
|
[c.STREAMING_FALLBACK, c.LOG_PREFIX_SYNC_STREAMING + 'Falling back to polling mode. Reason: %s'],
|
|
@@ -24,14 +24,14 @@ exports.codesWarn = error_1.codesError.concat([
|
|
|
24
24
|
[c.WARN_TRIMMING_PROPERTIES, '%s: Event has more than 300 properties. Some of them will be trimmed when processed.'],
|
|
25
25
|
[c.WARN_CONVERTING, '%s: %s "%s" is not of type string, converting.'],
|
|
26
26
|
[c.WARN_TRIMMING, '%s: %s "%s" has extra whitespace, trimming.'],
|
|
27
|
-
[c.WARN_NOT_EXISTENT_SPLIT, '%s:
|
|
27
|
+
[c.WARN_NOT_EXISTENT_SPLIT, '%s: feature flag "%s" does not exist in this environment. Please double check what feature flags exist in the Split user interface.'],
|
|
28
28
|
[c.WARN_LOWERCASE_TRAFFIC_TYPE, '%s: traffic_type_name should be all lowercase - converting string to lowercase.'],
|
|
29
|
-
[c.WARN_NOT_EXISTENT_TT, '%s: traffic type "%s" does not have any corresponding
|
|
29
|
+
[c.WARN_NOT_EXISTENT_TT, '%s: traffic type "%s" does not have any corresponding feature flag in this environment, make sure you\'re tracking your events to a valid traffic type defined in the Split user interface.'],
|
|
30
30
|
// initialization / settings validation
|
|
31
31
|
[c.WARN_INTEGRATION_INVALID, c.LOG_PREFIX_SETTINGS + ': %s integration item(s) at settings is invalid. %s'],
|
|
32
|
-
[c.WARN_SPLITS_FILTER_IGNORED, c.LOG_PREFIX_SETTINGS + ':
|
|
33
|
-
[c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ':
|
|
34
|
-
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ':
|
|
35
|
-
[c.
|
|
32
|
+
[c.WARN_SPLITS_FILTER_IGNORED, c.LOG_PREFIX_SETTINGS + ': feature flag filters have been configured but will have no effect if mode is not "%s", since synchronization is being deferred to an external tool.'],
|
|
33
|
+
[c.WARN_SPLITS_FILTER_INVALID, c.LOG_PREFIX_SETTINGS + ': feature flag filter at position %s is invalid. It must be an object with a valid filter type ("byName" or "byPrefix") and a list of "values".'],
|
|
34
|
+
[c.WARN_SPLITS_FILTER_EMPTY, c.LOG_PREFIX_SETTINGS + ': feature flag filter configuration must be a non-empty array of filter objects.'],
|
|
35
|
+
[c.WARN_SDK_KEY, c.LOG_PREFIX_SETTINGS + ': You already have %s. We recommend keeping only one instance of the factory at all times (Singleton pattern) and reusing it throughout your application'],
|
|
36
36
|
[c.STREAMING_PARSING_MY_SEGMENTS_UPDATE_V2, c.LOG_PREFIX_SYNC_STREAMING + 'Fetching MySegments due to an error processing %s notification: %s'],
|
|
37
37
|
]);
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -11,10 +11,10 @@ var constants_1 = require("../utils/constants");
|
|
|
11
11
|
var constants_2 = require("../logger/constants");
|
|
12
12
|
var utils_1 = require("../trackers/impressionObserver/utils");
|
|
13
13
|
var treatmentNotReady = { treatment: constants_1.CONTROL, label: labels_1.SDK_NOT_READY };
|
|
14
|
-
function treatmentsNotReady(
|
|
14
|
+
function treatmentsNotReady(featureFlagNames) {
|
|
15
15
|
var evaluations = {};
|
|
16
|
-
|
|
17
|
-
evaluations[
|
|
16
|
+
featureFlagNames.forEach(function (featureFlagName) {
|
|
17
|
+
evaluations[featureFlagName] = treatmentNotReady;
|
|
18
18
|
});
|
|
19
19
|
return evaluations;
|
|
20
20
|
}
|
|
@@ -24,59 +24,59 @@ function treatmentsNotReady(splitNames) {
|
|
|
24
24
|
function clientFactory(params) {
|
|
25
25
|
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker, telemetryTracker = params.telemetryTracker;
|
|
26
26
|
var log = settings.log, mode = settings.mode;
|
|
27
|
-
function getTreatment(key,
|
|
27
|
+
function getTreatment(key, featureFlagName, attributes, withConfig) {
|
|
28
28
|
if (withConfig === void 0) { withConfig = false; }
|
|
29
29
|
var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? constants_1.TREATMENT_WITH_CONFIG : constants_1.TREATMENT);
|
|
30
30
|
var wrapUp = function (evaluationResult) {
|
|
31
31
|
var queue = [];
|
|
32
|
-
var treatment = processEvaluation(evaluationResult,
|
|
32
|
+
var treatment = processEvaluation(evaluationResult, featureFlagName, key, attributes, withConfig, "getTreatment" + (withConfig ? 'withConfig' : ''), queue);
|
|
33
33
|
impressionsTracker.track(queue, attributes);
|
|
34
34
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
35
35
|
return treatment;
|
|
36
36
|
};
|
|
37
37
|
var evaluation = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
38
|
-
(0, evaluator_1.evaluateFeature)(log, key,
|
|
38
|
+
(0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage) :
|
|
39
39
|
(0, utils_1.isStorageSync)(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
40
40
|
treatmentNotReady :
|
|
41
41
|
Promise.resolve(treatmentNotReady); // Promisify if async
|
|
42
42
|
return (0, thenable_1.thenable)(evaluation) ? evaluation.then(function (res) { return wrapUp(res); }) : wrapUp(evaluation);
|
|
43
43
|
}
|
|
44
|
-
function getTreatmentWithConfig(key,
|
|
45
|
-
return getTreatment(key,
|
|
44
|
+
function getTreatmentWithConfig(key, featureFlagName, attributes) {
|
|
45
|
+
return getTreatment(key, featureFlagName, attributes, true);
|
|
46
46
|
}
|
|
47
|
-
function getTreatments(key,
|
|
47
|
+
function getTreatments(key, featureFlagNames, attributes, withConfig) {
|
|
48
48
|
if (withConfig === void 0) { withConfig = false; }
|
|
49
49
|
var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? constants_1.TREATMENTS_WITH_CONFIG : constants_1.TREATMENTS);
|
|
50
50
|
var wrapUp = function (evaluationResults) {
|
|
51
51
|
var queue = [];
|
|
52
52
|
var treatments = {};
|
|
53
|
-
Object.keys(evaluationResults).forEach(function (
|
|
54
|
-
treatments[
|
|
53
|
+
Object.keys(evaluationResults).forEach(function (featureFlagName) {
|
|
54
|
+
treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, attributes, withConfig, "getTreatments" + (withConfig ? 'withConfig' : ''), queue);
|
|
55
55
|
});
|
|
56
56
|
impressionsTracker.track(queue, attributes);
|
|
57
57
|
stopTelemetryTracker(queue[0] && queue[0].label);
|
|
58
58
|
return treatments;
|
|
59
59
|
};
|
|
60
60
|
var evaluations = readinessManager.isReady() || readinessManager.isReadyFromCache() ?
|
|
61
|
-
(0, evaluator_1.evaluateFeatures)(log, key,
|
|
61
|
+
(0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage) :
|
|
62
62
|
(0, utils_1.isStorageSync)(settings) ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
63
|
-
treatmentsNotReady(
|
|
64
|
-
Promise.resolve(treatmentsNotReady(
|
|
63
|
+
treatmentsNotReady(featureFlagNames) :
|
|
64
|
+
Promise.resolve(treatmentsNotReady(featureFlagNames)); // Promisify if async
|
|
65
65
|
return (0, thenable_1.thenable)(evaluations) ? evaluations.then(function (res) { return wrapUp(res); }) : wrapUp(evaluations);
|
|
66
66
|
}
|
|
67
|
-
function getTreatmentsWithConfig(key,
|
|
68
|
-
return getTreatments(key,
|
|
67
|
+
function getTreatmentsWithConfig(key, featureFlagNames, attributes) {
|
|
68
|
+
return getTreatments(key, featureFlagNames, attributes, true);
|
|
69
69
|
}
|
|
70
70
|
// Internal function
|
|
71
|
-
function processEvaluation(evaluation,
|
|
71
|
+
function processEvaluation(evaluation, featureFlagName, key, attributes, withConfig, invokingMethodName, queue) {
|
|
72
72
|
var matchingKey = (0, key_1.getMatching)(key);
|
|
73
73
|
var bucketingKey = (0, key_1.getBucketing)(key);
|
|
74
74
|
var treatment = evaluation.treatment, label = evaluation.label, changeNumber = evaluation.changeNumber, _a = evaluation.config, config = _a === void 0 ? null : _a;
|
|
75
|
-
log.info(constants_2.IMPRESSION, [
|
|
76
|
-
if ((0, splitExistance_1.validateSplitExistance)(log, readinessManager,
|
|
75
|
+
log.info(constants_2.IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
|
|
76
|
+
if ((0, splitExistance_1.validateSplitExistance)(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
77
77
|
log.info(constants_2.IMPRESSION_QUEUEING);
|
|
78
78
|
queue.push({
|
|
79
|
-
feature:
|
|
79
|
+
feature: featureFlagName,
|
|
80
80
|
keyName: matchingKey,
|
|
81
81
|
treatment: treatment,
|
|
82
82
|
time: Date.now(),
|
|
@@ -15,17 +15,17 @@ function clientAttributesDecoration(log, client) {
|
|
|
15
15
|
var clientGetTreatments = client.getTreatments;
|
|
16
16
|
var clientGetTreatmentsWithConfig = client.getTreatmentsWithConfig;
|
|
17
17
|
var clientTrack = client.track;
|
|
18
|
-
function getTreatment(maybeKey,
|
|
19
|
-
return clientGetTreatment(maybeKey,
|
|
18
|
+
function getTreatment(maybeKey, maybeFeatureFlagName, maybeAttributes) {
|
|
19
|
+
return clientGetTreatment(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
|
|
20
20
|
}
|
|
21
|
-
function getTreatmentWithConfig(maybeKey,
|
|
22
|
-
return clientGetTreatmentWithConfig(maybeKey,
|
|
21
|
+
function getTreatmentWithConfig(maybeKey, maybeFeatureFlagName, maybeAttributes) {
|
|
22
|
+
return clientGetTreatmentWithConfig(maybeKey, maybeFeatureFlagName, combineAttributes(maybeAttributes));
|
|
23
23
|
}
|
|
24
|
-
function getTreatments(maybeKey,
|
|
25
|
-
return clientGetTreatments(maybeKey,
|
|
24
|
+
function getTreatments(maybeKey, maybeFeatureFlagNames, maybeAttributes) {
|
|
25
|
+
return clientGetTreatments(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
|
|
26
26
|
}
|
|
27
|
-
function getTreatmentsWithConfig(maybeKey,
|
|
28
|
-
return clientGetTreatmentsWithConfig(maybeKey,
|
|
27
|
+
function getTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, maybeAttributes) {
|
|
28
|
+
return clientGetTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, combineAttributes(maybeAttributes));
|
|
29
29
|
}
|
|
30
30
|
function track(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties) {
|
|
31
31
|
return clientTrack(maybeKey, maybeTT, maybeEvent, maybeEventValue, maybeProperties);
|
|
@@ -16,10 +16,10 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
16
16
|
/**
|
|
17
17
|
* Avoid repeating this validations code
|
|
18
18
|
*/
|
|
19
|
-
function validateEvaluationParams(maybeKey,
|
|
19
|
+
function validateEvaluationParams(maybeKey, maybeFeatureFlagNameOrNames, maybeAttributes, methodName) {
|
|
20
20
|
var multi = (0, lang_1.startsWith)(methodName, 'getTreatments');
|
|
21
21
|
var key = (0, inputValidation_1.validateKey)(log, maybeKey, methodName);
|
|
22
|
-
var splitOrSplits = multi ? (0, inputValidation_1.validateSplits)(log,
|
|
22
|
+
var splitOrSplits = multi ? (0, inputValidation_1.validateSplits)(log, maybeFeatureFlagNameOrNames, methodName) : (0, inputValidation_1.validateSplit)(log, maybeFeatureFlagNameOrNames, methodName);
|
|
23
23
|
var attributes = (0, inputValidation_1.validateAttributes)(log, maybeAttributes, methodName);
|
|
24
24
|
var isOperational = (0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, methodName);
|
|
25
25
|
(0, inputValidation_1.validateIfOperational)(log, readinessManager, methodName);
|
|
@@ -34,8 +34,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
34
34
|
function wrapResult(value) {
|
|
35
35
|
return isSync ? value : Promise.resolve(value);
|
|
36
36
|
}
|
|
37
|
-
function getTreatment(maybeKey,
|
|
38
|
-
var params = validateEvaluationParams(maybeKey,
|
|
37
|
+
function getTreatment(maybeKey, maybeFeatureFlagName, maybeAttributes) {
|
|
38
|
+
var params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes, 'getTreatment');
|
|
39
39
|
if (params.valid) {
|
|
40
40
|
return client.getTreatment(params.key, params.splitOrSplits, params.attributes);
|
|
41
41
|
}
|
|
@@ -43,8 +43,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
43
43
|
return wrapResult(constants_1.CONTROL);
|
|
44
44
|
}
|
|
45
45
|
}
|
|
46
|
-
function getTreatmentWithConfig(maybeKey,
|
|
47
|
-
var params = validateEvaluationParams(maybeKey,
|
|
46
|
+
function getTreatmentWithConfig(maybeKey, maybeFeatureFlagName, maybeAttributes) {
|
|
47
|
+
var params = validateEvaluationParams(maybeKey, maybeFeatureFlagName, maybeAttributes, 'getTreatmentWithConfig');
|
|
48
48
|
if (params.valid) {
|
|
49
49
|
return client.getTreatmentWithConfig(params.key, params.splitOrSplits, params.attributes);
|
|
50
50
|
}
|
|
@@ -52,8 +52,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
52
52
|
return wrapResult((0, objectAssign_1.objectAssign)({}, constants_1.CONTROL_WITH_CONFIG));
|
|
53
53
|
}
|
|
54
54
|
}
|
|
55
|
-
function getTreatments(maybeKey,
|
|
56
|
-
var params = validateEvaluationParams(maybeKey,
|
|
55
|
+
function getTreatments(maybeKey, maybeFeatureFlagNames, maybeAttributes) {
|
|
56
|
+
var params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes, 'getTreatments');
|
|
57
57
|
if (params.valid) {
|
|
58
58
|
return client.getTreatments(params.key, params.splitOrSplits, params.attributes);
|
|
59
59
|
}
|
|
@@ -64,8 +64,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
64
64
|
return wrapResult(res_1);
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
|
-
function getTreatmentsWithConfig(maybeKey,
|
|
68
|
-
var params = validateEvaluationParams(maybeKey,
|
|
67
|
+
function getTreatmentsWithConfig(maybeKey, maybeFeatureFlagNames, maybeAttributes) {
|
|
68
|
+
var params = validateEvaluationParams(maybeKey, maybeFeatureFlagNames, maybeAttributes, 'getTreatmentsWithConfig');
|
|
69
69
|
if (params.valid) {
|
|
70
70
|
return client.getTreatmentsWithConfig(params.key, params.splitOrSplits, params.attributes);
|
|
71
71
|
}
|
|
@@ -52,7 +52,7 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
52
52
|
// Cleanup event listeners
|
|
53
53
|
sdkReadinessManager.readinessManager.destroy();
|
|
54
54
|
signalListener && signalListener.stop();
|
|
55
|
-
// Release the
|
|
55
|
+
// Release the SDK Key if it is the main client
|
|
56
56
|
if (!isSharedClient)
|
|
57
57
|
(0, apiKey_1.releaseApiKey)(settings.core.authorizationKey);
|
|
58
58
|
if (uniqueKeysTracker)
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -21,7 +21,7 @@ var constants_3 = require("../utils/constants");
|
|
|
21
21
|
function sdkFactory(params) {
|
|
22
22
|
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, filterAdapterFactory = params.filterAdapterFactory;
|
|
23
23
|
var log = settings.log, impressionsMode = settings.sync.impressionsMode;
|
|
24
|
-
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid
|
|
24
|
+
// @TODO handle non-recoverable errors, such as, global `fetch` not available, invalid SDK Key, etc.
|
|
25
25
|
// On non-recoverable errors, we should mark the SDK as destroyed and not start synchronization.
|
|
26
26
|
// We will just log and allow for the SDK to end up throwing an SDK_TIMEOUT event for devs to handle.
|
|
27
27
|
(0, apiKey_1.validateAndTrackApiKey)(log, settings.core.authorizationKey);
|
package/cjs/sdkManager/index.js
CHANGED
|
@@ -5,6 +5,9 @@ var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
|
5
5
|
var thenable_1 = require("../utils/promise/thenable");
|
|
6
6
|
var lang_1 = require("../utils/lang");
|
|
7
7
|
var inputValidation_1 = require("../utils/inputValidation");
|
|
8
|
+
var SPLIT_FN_LABEL = 'split';
|
|
9
|
+
var SPLITS_FN_LABEL = 'splits';
|
|
10
|
+
var NAMES_FN_LABEL = 'names';
|
|
8
11
|
function collectTreatments(splitObject) {
|
|
9
12
|
var conditions = splitObject.conditions;
|
|
10
13
|
// Rollout conditions are supposed to have the entire partitions list, so we find the first one.
|
|
@@ -38,15 +41,14 @@ function objectsToViews(splitObjects) {
|
|
|
38
41
|
}
|
|
39
42
|
function sdkManagerFactory(log, splits, _a) {
|
|
40
43
|
var readinessManager = _a.readinessManager, sdkStatus = _a.sdkStatus;
|
|
41
|
-
var SPLIT_FN_LABEL = 'split';
|
|
42
44
|
return (0, objectAssign_1.objectAssign)(
|
|
43
45
|
// Proto-linkage of the readiness Event Emitter
|
|
44
46
|
Object.create(sdkStatus), {
|
|
45
47
|
/**
|
|
46
|
-
* Get the
|
|
48
|
+
* Get the feature flag object corresponding to the given feature flag name if valid
|
|
47
49
|
*/
|
|
48
|
-
split: function (
|
|
49
|
-
var splitName = (0, inputValidation_1.validateSplit)(log,
|
|
50
|
+
split: function (featureFlagName) {
|
|
51
|
+
var splitName = (0, inputValidation_1.validateSplit)(log, featureFlagName, SPLIT_FN_LABEL);
|
|
50
52
|
if (!(0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, SPLIT_FN_LABEL) || !(0, inputValidation_1.validateIfOperational)(log, readinessManager, SPLIT_FN_LABEL) || !splitName) {
|
|
51
53
|
return null;
|
|
52
54
|
}
|
|
@@ -61,10 +63,10 @@ function sdkManagerFactory(log, splits, _a) {
|
|
|
61
63
|
return objectToView(split);
|
|
62
64
|
},
|
|
63
65
|
/**
|
|
64
|
-
* Get the
|
|
66
|
+
* Get the feature flag objects present on the factory storage
|
|
65
67
|
*/
|
|
66
68
|
splits: function () {
|
|
67
|
-
if (!(0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager,
|
|
69
|
+
if (!(0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, SPLITS_FN_LABEL) || !(0, inputValidation_1.validateIfOperational)(log, readinessManager, SPLITS_FN_LABEL)) {
|
|
68
70
|
return [];
|
|
69
71
|
}
|
|
70
72
|
var currentSplits = splits.getAll();
|
|
@@ -73,10 +75,10 @@ function sdkManagerFactory(log, splits, _a) {
|
|
|
73
75
|
objectsToViews(currentSplits);
|
|
74
76
|
},
|
|
75
77
|
/**
|
|
76
|
-
* Get the
|
|
78
|
+
* Get the feature flag names present on the factory storage
|
|
77
79
|
*/
|
|
78
80
|
names: function () {
|
|
79
|
-
if (!(0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager,
|
|
81
|
+
if (!(0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, NAMES_FN_LABEL) || !(0, inputValidation_1.validateIfOperational)(log, readinessManager, NAMES_FN_LABEL)) {
|
|
80
82
|
return [];
|
|
81
83
|
}
|
|
82
84
|
var splitNames = splits.getSplitNames();
|
package/cjs/services/splitApi.js
CHANGED
|
@@ -20,6 +20,7 @@ function splitApiFactory(settings, platform, telemetryTracker) {
|
|
|
20
20
|
var SplitSDKImpressionsMode = settings.sync.impressionsMode;
|
|
21
21
|
var splitHttpClient = (0, splitHttpClient_1.splitHttpClientFactory)(settings, platform.getFetch, platform.getOptions);
|
|
22
22
|
return {
|
|
23
|
+
// @TODO throw errors if health check requests fail, to log them in the Synchronizer
|
|
23
24
|
getSdkAPIHealthCheck: function () {
|
|
24
25
|
var url = urls.sdk + "/version";
|
|
25
26
|
return splitHttpClient(url).then(function () { return true; }).catch(function () { return false; });
|
|
@@ -53,7 +53,7 @@ function splitHttpClientFactory(settings, getFetch, getOptions) {
|
|
|
53
53
|
if (resp) { // An HTTP error
|
|
54
54
|
switch (resp.status) {
|
|
55
55
|
case 404:
|
|
56
|
-
msg = 'Invalid
|
|
56
|
+
msg = 'Invalid SDK key or resource not found.';
|
|
57
57
|
break;
|
|
58
58
|
// Don't use resp.statusText since reason phrase is removed in HTTP/2
|
|
59
59
|
default:
|
|
@@ -37,10 +37,8 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
37
37
|
SplitsCacheInLocal.prototype._decrementCounts = function (split) {
|
|
38
38
|
try {
|
|
39
39
|
if (split) {
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
this._decrementCount(ttKey);
|
|
43
|
-
}
|
|
40
|
+
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
41
|
+
this._decrementCount(ttKey);
|
|
44
42
|
if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
|
|
45
43
|
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
46
44
|
this._decrementCount(segmentsCountKey);
|
|
@@ -54,11 +52,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
54
52
|
SplitsCacheInLocal.prototype._incrementCounts = function (split) {
|
|
55
53
|
try {
|
|
56
54
|
if (split) {
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
|
|
61
|
-
}
|
|
55
|
+
var ttKey = this.keys.buildTrafficTypeKey(split.trafficTypeName);
|
|
56
|
+
// @ts-expect-error
|
|
57
|
+
localStorage.setItem(ttKey, (0, lang_1.toNumber)(localStorage.getItem(ttKey)) + 1);
|
|
62
58
|
if ((0, AbstractSplitsCacheSync_1.usesSegments)(split)) {
|
|
63
59
|
var segmentsCountKey = this.keys.buildSplitsWithSegmentCountKey();
|
|
64
60
|
// @ts-expect-error
|
|
@@ -95,9 +91,9 @@ var SplitsCacheInLocal = /** @class */ (function (_super) {
|
|
|
95
91
|
var splitKey = this.keys.buildSplitKey(name);
|
|
96
92
|
var splitFromLocalStorage = localStorage.getItem(splitKey);
|
|
97
93
|
var previousSplit = splitFromLocalStorage ? JSON.parse(splitFromLocalStorage) : null;
|
|
98
|
-
this._decrementCounts(previousSplit);
|
|
99
94
|
localStorage.setItem(splitKey, JSON.stringify(split));
|
|
100
95
|
this._incrementCounts(split);
|
|
96
|
+
this._decrementCounts(previousSplit);
|
|
101
97
|
return true;
|
|
102
98
|
}
|
|
103
99
|
catch (e) {
|
|
@@ -27,12 +27,10 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
27
27
|
SplitsCacheInMemory.prototype.addSplit = function (name, split) {
|
|
28
28
|
var previousSplit = this.getSplit(name);
|
|
29
29
|
if (previousSplit) { // We had this Split already
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
delete this.ttCache[previousTtName];
|
|
35
|
-
}
|
|
30
|
+
var previousTtName = previousSplit.trafficTypeName;
|
|
31
|
+
this.ttCache[previousTtName]--;
|
|
32
|
+
if (!this.ttCache[previousTtName])
|
|
33
|
+
delete this.ttCache[previousTtName];
|
|
36
34
|
if ((0, AbstractSplitsCacheSync_1.usesSegments)(previousSplit)) { // Substract from segments count for the previous version of this Split.
|
|
37
35
|
this.splitsWithSegmentsCount--;
|
|
38
36
|
}
|
|
@@ -42,11 +40,7 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
42
40
|
this.splitsCache[name] = split;
|
|
43
41
|
// Update TT cache
|
|
44
42
|
var ttName = split.trafficTypeName;
|
|
45
|
-
|
|
46
|
-
if (!this.ttCache[ttName])
|
|
47
|
-
this.ttCache[ttName] = 0;
|
|
48
|
-
this.ttCache[ttName]++;
|
|
49
|
-
}
|
|
43
|
+
this.ttCache[ttName] = (this.ttCache[ttName] || 0) + 1;
|
|
50
44
|
// Add to segments count for the new version of the Split
|
|
51
45
|
if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
|
|
52
46
|
this.splitsWithSegmentsCount++;
|
|
@@ -62,11 +56,9 @@ var SplitsCacheInMemory = /** @class */ (function (_super) {
|
|
|
62
56
|
// Delete the Split
|
|
63
57
|
delete this.splitsCache[name];
|
|
64
58
|
var ttName = split.trafficTypeName;
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
delete this.ttCache[ttName];
|
|
69
|
-
}
|
|
59
|
+
this.ttCache[ttName]--; // Update tt cache
|
|
60
|
+
if (!this.ttCache[ttName])
|
|
61
|
+
delete this.ttCache[ttName];
|
|
70
62
|
// Update the segments count.
|
|
71
63
|
if ((0, AbstractSplitsCacheSync_1.usesSegments)(split))
|
|
72
64
|
this.splitsWithSegmentsCount--;
|