@splitsoftware/splitio-commons 2.7.2-rc.0 → 2.7.9-rc.1
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 +4 -2
- package/cjs/evaluator/fallbackTreatmentsCalculator/constants.js +8 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +47 -0
- package/cjs/evaluator/fallbackTreatmentsCalculator/index.js +48 -0
- package/cjs/logger/constants.js +2 -2
- package/cjs/logger/messages/info.js +1 -1
- package/cjs/logger/messages/warn.js +3 -3
- package/cjs/readiness/readinessManager.js +3 -5
- package/cjs/readiness/sdkReadinessManager.js +33 -0
- package/cjs/sdkClient/client.js +12 -5
- package/cjs/sdkClient/clientInputValidation.js +18 -7
- package/cjs/sdkClient/sdkClient.js +1 -1
- package/cjs/sdkFactory/index.js +3 -1
- package/cjs/sdkManager/index.js +3 -3
- package/cjs/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
- package/cjs/sync/polling/updaters/segmentChangesUpdater.js +5 -16
- package/cjs/sync/polling/updaters/splitChangesUpdater.js +2 -2
- package/cjs/sync/streaming/SSEHandler/index.js +1 -1
- package/cjs/sync/submitters/telemetrySubmitter.js +3 -3
- package/cjs/trackers/telemetryTracker.js +6 -6
- package/cjs/utils/inputValidation/index.js +2 -1
- package/cjs/utils/inputValidation/isOperational.js +9 -4
- package/cjs/utils/inputValidation/splitExistence.js +3 -3
- package/cjs/utils/labels/index.js +3 -1
- package/esm/evaluator/fallbackTreatmentsCalculator/constants.js +5 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.js +44 -0
- package/esm/evaluator/fallbackTreatmentsCalculator/index.js +45 -0
- package/esm/logger/constants.js +1 -1
- package/esm/logger/messages/info.js +1 -1
- package/esm/logger/messages/warn.js +3 -3
- package/esm/readiness/readinessManager.js +3 -5
- package/esm/readiness/sdkReadinessManager.js +33 -0
- package/esm/sdkClient/client.js +12 -5
- package/esm/sdkClient/clientInputValidation.js +20 -9
- package/esm/sdkClient/sdkClient.js +1 -1
- package/esm/sdkFactory/index.js +3 -1
- package/esm/sdkManager/index.js +4 -4
- package/esm/sync/polling/syncTasks/segmentsSyncTask.js +1 -1
- package/esm/sync/polling/updaters/segmentChangesUpdater.js +5 -16
- package/esm/sync/polling/updaters/splitChangesUpdater.js +2 -2
- package/esm/sync/streaming/SSEHandler/index.js +1 -1
- package/esm/sync/submitters/telemetrySubmitter.js +3 -3
- package/esm/trackers/telemetryTracker.js +6 -6
- package/esm/utils/inputValidation/index.js +1 -1
- package/esm/utils/inputValidation/isOperational.js +8 -4
- package/esm/utils/inputValidation/splitExistence.js +4 -4
- package/esm/utils/labels/index.js +2 -0
- package/package.json +1 -1
- package/src/evaluator/fallbackTreatmentsCalculator/constants.ts +4 -0
- package/src/evaluator/fallbackTreatmentsCalculator/fallbackSanitizer/index.ts +62 -0
- package/src/evaluator/fallbackTreatmentsCalculator/index.ts +57 -0
- package/src/logger/constants.ts +1 -1
- package/src/logger/messages/info.ts +1 -1
- package/src/logger/messages/warn.ts +3 -3
- package/src/readiness/readinessManager.ts +3 -4
- package/src/readiness/sdkReadinessManager.ts +30 -0
- package/src/sdkClient/client.ts +14 -5
- package/src/sdkClient/clientInputValidation.ts +24 -9
- package/src/sdkClient/sdkClient.ts +2 -1
- package/src/sdkFactory/index.ts +4 -1
- package/src/sdkFactory/types.ts +2 -0
- package/src/sdkManager/index.ts +4 -4
- package/src/sync/polling/syncTasks/segmentsSyncTask.ts +0 -2
- package/src/sync/polling/updaters/segmentChangesUpdater.ts +4 -17
- package/src/sync/polling/updaters/splitChangesUpdater.ts +5 -4
- package/src/sync/streaming/SSEHandler/index.ts +1 -1
- package/src/sync/submitters/telemetrySubmitter.ts +3 -3
- package/src/trackers/telemetryTracker.ts +6 -6
- package/src/utils/inputValidation/index.ts +1 -1
- package/src/utils/inputValidation/isOperational.ts +9 -4
- package/src/utils/inputValidation/splitExistence.ts +4 -4
- package/src/utils/labels/index.ts +3 -0
- package/types/splitio.d.ts +37 -6
package/CHANGES.txt
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
|
-
2.8.0 (October
|
|
2
|
-
-
|
|
1
|
+
2.8.0 (October 28, 2025)
|
|
2
|
+
- Added new configuration for Fallback Treatments, which allows setting a treatment value and optional config to be returned in place of "control", either globally or by flag. Read more in our docs.
|
|
3
|
+
- Added `client.whenReady()` and `client.whenReadyFromCache()` methods to replace the deprecated `client.ready()` method, which has an issue causing the returned promise to hang when using async/await syntax if it was rejected.
|
|
4
|
+
- Updated the SDK_READY_FROM_CACHE event to be emitted alongside the SDK_READY event if it hasn’t already been emitted.
|
|
3
5
|
|
|
4
6
|
2.7.1 (October 8, 2025)
|
|
5
7
|
- Bugfix - Update `debug` option to support log levels when `logger` option is used.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FallbackDiscardReason = void 0;
|
|
4
|
+
var FallbackDiscardReason;
|
|
5
|
+
(function (FallbackDiscardReason) {
|
|
6
|
+
FallbackDiscardReason["FlagName"] = "Invalid flag name (max 100 chars, no spaces)";
|
|
7
|
+
FallbackDiscardReason["Treatment"] = "Invalid treatment (max 100 chars and must match pattern)";
|
|
8
|
+
})(FallbackDiscardReason = exports.FallbackDiscardReason || (exports.FallbackDiscardReason = {}));
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FallbacksSanitizer = void 0;
|
|
4
|
+
var lang_1 = require("../../../utils/lang");
|
|
5
|
+
var constants_1 = require("../constants");
|
|
6
|
+
var FallbacksSanitizer = /** @class */ (function () {
|
|
7
|
+
function FallbacksSanitizer() {
|
|
8
|
+
}
|
|
9
|
+
FallbacksSanitizer.isValidFlagName = function (name) {
|
|
10
|
+
return name.length <= 100 && !name.includes(' ');
|
|
11
|
+
};
|
|
12
|
+
FallbacksSanitizer.isValidTreatment = function (t) {
|
|
13
|
+
var treatment = (0, lang_1.isObject)(t) ? t.treatment : t;
|
|
14
|
+
if (!(0, lang_1.isString)(treatment) || treatment.length > 100) {
|
|
15
|
+
return false;
|
|
16
|
+
}
|
|
17
|
+
return FallbacksSanitizer.pattern.test(treatment);
|
|
18
|
+
};
|
|
19
|
+
FallbacksSanitizer.sanitizeGlobal = function (logger, treatment) {
|
|
20
|
+
if (!this.isValidTreatment(treatment)) {
|
|
21
|
+
logger.error("Fallback treatments - Discarded fallback: " + constants_1.FallbackDiscardReason.Treatment);
|
|
22
|
+
return undefined;
|
|
23
|
+
}
|
|
24
|
+
return treatment;
|
|
25
|
+
};
|
|
26
|
+
FallbacksSanitizer.sanitizeByFlag = function (logger, byFlagFallbacks) {
|
|
27
|
+
var _this = this;
|
|
28
|
+
var sanitizedByFlag = {};
|
|
29
|
+
var entries = Object.keys(byFlagFallbacks);
|
|
30
|
+
entries.forEach(function (flag) {
|
|
31
|
+
var t = byFlagFallbacks[flag];
|
|
32
|
+
if (!_this.isValidFlagName(flag)) {
|
|
33
|
+
logger.error("Fallback treatments - Discarded flag '" + flag + "': " + constants_1.FallbackDiscardReason.FlagName);
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
if (!_this.isValidTreatment(t)) {
|
|
37
|
+
logger.error("Fallback treatments - Discarded treatment for flag '" + flag + "': " + constants_1.FallbackDiscardReason.Treatment);
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
40
|
+
sanitizedByFlag[flag] = t;
|
|
41
|
+
});
|
|
42
|
+
return sanitizedByFlag;
|
|
43
|
+
};
|
|
44
|
+
FallbacksSanitizer.pattern = /^[0-9]+[.a-zA-Z0-9_-]*$|^[a-zA-Z]+[a-zA-Z0-9_-]*$/;
|
|
45
|
+
return FallbacksSanitizer;
|
|
46
|
+
}());
|
|
47
|
+
exports.FallbacksSanitizer = FallbacksSanitizer;
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.FallbackTreatmentsCalculator = exports.FALLBACK_PREFIX = void 0;
|
|
4
|
+
var fallbackSanitizer_1 = require("./fallbackSanitizer");
|
|
5
|
+
var constants_1 = require("../../utils/constants");
|
|
6
|
+
var lang_1 = require("../../utils/lang");
|
|
7
|
+
exports.FALLBACK_PREFIX = 'fallback - ';
|
|
8
|
+
var FallbackTreatmentsCalculator = /** @class */ (function () {
|
|
9
|
+
function FallbackTreatmentsCalculator(logger, fallbacks) {
|
|
10
|
+
var sanitizedGlobal = (fallbacks === null || fallbacks === void 0 ? void 0 : fallbacks.global) ? fallbackSanitizer_1.FallbacksSanitizer.sanitizeGlobal(logger, fallbacks.global) : undefined;
|
|
11
|
+
var sanitizedByFlag = (fallbacks === null || fallbacks === void 0 ? void 0 : fallbacks.byFlag) ? fallbackSanitizer_1.FallbacksSanitizer.sanitizeByFlag(logger, fallbacks.byFlag) : {};
|
|
12
|
+
this.fallbacks = {
|
|
13
|
+
global: sanitizedGlobal,
|
|
14
|
+
byFlag: sanitizedByFlag
|
|
15
|
+
};
|
|
16
|
+
}
|
|
17
|
+
FallbackTreatmentsCalculator.prototype.resolve = function (flagName, label) {
|
|
18
|
+
var _a;
|
|
19
|
+
var treatment = (_a = this.fallbacks.byFlag) === null || _a === void 0 ? void 0 : _a[flagName];
|
|
20
|
+
if (treatment) {
|
|
21
|
+
return this.copyWithLabel(treatment, label);
|
|
22
|
+
}
|
|
23
|
+
if (this.fallbacks.global) {
|
|
24
|
+
return this.copyWithLabel(this.fallbacks.global, label);
|
|
25
|
+
}
|
|
26
|
+
return {
|
|
27
|
+
treatment: constants_1.CONTROL,
|
|
28
|
+
config: null,
|
|
29
|
+
label: label,
|
|
30
|
+
};
|
|
31
|
+
};
|
|
32
|
+
FallbackTreatmentsCalculator.prototype.copyWithLabel = function (fallback, label) {
|
|
33
|
+
if ((0, lang_1.isString)(fallback)) {
|
|
34
|
+
return {
|
|
35
|
+
treatment: fallback,
|
|
36
|
+
config: null,
|
|
37
|
+
label: "" + exports.FALLBACK_PREFIX + label,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
return {
|
|
41
|
+
treatment: fallback.treatment,
|
|
42
|
+
config: fallback.config,
|
|
43
|
+
label: "" + exports.FALLBACK_PREFIX + label,
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
return FallbackTreatmentsCalculator;
|
|
47
|
+
}());
|
|
48
|
+
exports.FallbackTreatmentsCalculator = FallbackTreatmentsCalculator;
|
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.SUBMITTERS_PUSH_PAGE_HIDDEN = 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 = 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.ENGINE_DEFAULT = exports.ENGINE_MATCHER_RESULT = exports.SETTINGS_SPLITS_FILTER = exports.SYNC_TASK_STOP = exports.SYNC_TASK_EXECUTE = exports.SYNC_TASK_START = exports.STREAMING_NEW_MESSAGE = exports.SYNC_RBS_UPDATE = exports.SYNC_SPLITS_UPDATE = 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_DEPENDENCY_PRE = exports.ENGINE_MATCHER_DEPENDENCY = exports.ENGINE_BUCKET = exports.ENGINE_COMBINER_IFELSEIF_NO_TREATMENT = exports.ENGINE_COMBINER_IFELSEIF = exports.ENGINE_COMBINER_AND = void 0;
|
|
4
|
-
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 = 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.WARN_FLAGSET_WITHOUT_FLAGS = exports.WARN_FLAGSET_NOT_CONFIGURED = exports.WARN_LOWERCASE_FLAGSET = exports.WARN_INVALID_FLAGSET = exports.STREAMING_PARSING_SPLIT_UPDATE = exports.STREAMING_PARSING_MEMBERSHIPS_UPDATE = 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.
|
|
4
|
+
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 = 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.WARN_FLAGSET_WITHOUT_FLAGS = exports.WARN_FLAGSET_NOT_CONFIGURED = exports.WARN_LOWERCASE_FLAGSET = exports.WARN_INVALID_FLAGSET = exports.STREAMING_PARSING_SPLIT_UPDATE = exports.STREAMING_PARSING_MEMBERSHIPS_UPDATE = 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_FROM_CACHE = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = 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_CLIENT_INSTANTIATION = exports.LOG_PREFIX_INSTANTIATION = exports.LOG_PREFIX_SETTINGS = exports.ENGINE_MATCHER_ERROR = exports.ERROR_SETS_FILTER_EXCLUSIVE = exports.ERROR_TOO_MANY_SETS = exports.ERROR_MIN_CONFIG_PARAM = exports.ERROR_NOT_BOOLEAN = exports.ERROR_STORAGE_INVALID = exports.ERROR_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = void 0;
|
|
6
6
|
/**
|
|
7
7
|
* Message codes used to trim string log messages from commons and client-side API modules,
|
|
@@ -63,7 +63,7 @@ exports.SUBMITTERS_PUSH_PAGE_HIDDEN = 125;
|
|
|
63
63
|
exports.ENGINE_VALUE_INVALID = 200;
|
|
64
64
|
exports.ENGINE_VALUE_NO_ATTRIBUTES = 201;
|
|
65
65
|
exports.CLIENT_NO_LISTENER = 202;
|
|
66
|
-
exports.
|
|
66
|
+
exports.CLIENT_NOT_READY_FROM_CACHE = 203;
|
|
67
67
|
exports.SYNC_MYSEGMENTS_FETCH_RETRY = 204;
|
|
68
68
|
exports.SYNC_SPLITS_FETCH_FAILS = 205;
|
|
69
69
|
exports.STREAMING_PARSING_ERROR_FAILS = 206;
|
|
@@ -23,7 +23,7 @@ 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
|
|
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 resetting timer.'],
|
|
28
28
|
[c.SUBMITTERS_PUSH, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Pushing %s.'],
|
|
29
29
|
[c.SUBMITTERS_PUSH_PAGE_HIDDEN, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Flushing %s because page became hidden.'],
|
|
@@ -9,7 +9,7 @@ exports.codesWarn = error_1.codesError.concat([
|
|
|
9
9
|
[c.ENGINE_VALUE_INVALID, c.LOG_PREFIX_ENGINE_VALUE + 'Value %s doesn\'t match with expected type.'],
|
|
10
10
|
[c.ENGINE_VALUE_NO_ATTRIBUTES, c.LOG_PREFIX_ENGINE_VALUE + 'Defined attribute `%s`. No attributes received.'],
|
|
11
11
|
// synchronizer
|
|
12
|
-
[c.SYNC_MYSEGMENTS_FETCH_RETRY, c.LOG_PREFIX_SYNC_MYSEGMENTS + 'Retrying
|
|
12
|
+
[c.SYNC_MYSEGMENTS_FETCH_RETRY, c.LOG_PREFIX_SYNC_MYSEGMENTS + 'Retrying download of segments #%s. Reason: %s'],
|
|
13
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'],
|
|
@@ -17,8 +17,8 @@ exports.codesWarn = error_1.codesError.concat([
|
|
|
17
17
|
[c.SUBMITTERS_PUSH_FAILS, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Dropping %s after retry. Reason: %s.'],
|
|
18
18
|
[c.SUBMITTERS_PUSH_RETRY, c.LOG_PREFIX_SYNC_SUBMITTERS + 'Failed to push %s, keeping data to retry on next iteration. Reason: %s.'],
|
|
19
19
|
// client status
|
|
20
|
-
[c.
|
|
21
|
-
[c.CLIENT_NO_LISTENER, 'No listeners for
|
|
20
|
+
[c.CLIENT_NOT_READY_FROM_CACHE, '%s: the SDK is not ready to evaluate. Results may be incorrect%s. Make sure to wait for SDK readiness before using this method.'],
|
|
21
|
+
[c.CLIENT_NO_LISTENER, 'No listeners for SDK_READY event detected. Incorrect control treatments could have been logged if you called getTreatment/s while the SDK was not yet synchronized with the backend.'],
|
|
22
22
|
// input validation
|
|
23
23
|
[c.WARN_SETTING_NULL, '%s: Property "%s" is of invalid type. Setting value to null.'],
|
|
24
24
|
[c.WARN_TRIMMING_PROPERTIES, '%s: more than 300 properties were provided. Some of them will be trimmed when processed.'],
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.readinessManagerFactory = void 0;
|
|
4
4
|
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
5
|
var constants_1 = require("./constants");
|
|
6
|
-
var constants_2 = require("../utils/constants");
|
|
7
6
|
function splitsEventEmitterFactory(EventEmitter) {
|
|
8
7
|
var splitsEventEmitter = (0, objectAssign_1.objectAssign)(new EventEmitter(), {
|
|
9
8
|
splitsArrived: false,
|
|
@@ -75,7 +74,7 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
75
74
|
if (!isReady && !isDestroyed) {
|
|
76
75
|
try {
|
|
77
76
|
syncLastUpdate();
|
|
78
|
-
gate.emit(constants_1.SDK_READY_FROM_CACHE);
|
|
77
|
+
gate.emit(constants_1.SDK_READY_FROM_CACHE, isReady);
|
|
79
78
|
}
|
|
80
79
|
catch (e) {
|
|
81
80
|
// throws user callback exceptions in next tick
|
|
@@ -84,7 +83,6 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
84
83
|
}
|
|
85
84
|
}
|
|
86
85
|
function checkIsReadyOrUpdate(diff) {
|
|
87
|
-
var _a;
|
|
88
86
|
if (isDestroyed)
|
|
89
87
|
return;
|
|
90
88
|
if (isReady) {
|
|
@@ -103,9 +101,9 @@ function readinessManagerFactory(EventEmitter, settings, splits, isShared) {
|
|
|
103
101
|
isReady = true;
|
|
104
102
|
try {
|
|
105
103
|
syncLastUpdate();
|
|
106
|
-
if (!isReadyFromCache
|
|
104
|
+
if (!isReadyFromCache) {
|
|
107
105
|
isReadyFromCache = true;
|
|
108
|
-
gate.emit(constants_1.SDK_READY_FROM_CACHE);
|
|
106
|
+
gate.emit(constants_1.SDK_READY_FROM_CACHE, isReady);
|
|
109
107
|
}
|
|
110
108
|
gate.emit(constants_1.SDK_READY);
|
|
111
109
|
}
|
|
@@ -8,6 +8,7 @@ var constants_1 = require("./constants");
|
|
|
8
8
|
var constants_2 = require("../logger/constants");
|
|
9
9
|
var NEW_LISTENER_EVENT = 'newListener';
|
|
10
10
|
var REMOVE_LISTENER_EVENT = 'removeListener';
|
|
11
|
+
var TIMEOUT_ERROR = new Error(constants_1.SDK_READY_TIMED_OUT);
|
|
11
12
|
/**
|
|
12
13
|
* SdkReadinessManager factory, which provides the public status API of SDK clients and manager: ready promise, readiness event emitter and constants (SDK_READY, etc).
|
|
13
14
|
* It also updates logs related warnings and errors.
|
|
@@ -34,6 +35,9 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
34
35
|
readyCbCount++;
|
|
35
36
|
}
|
|
36
37
|
}
|
|
38
|
+
else if (event === constants_1.SDK_READY_FROM_CACHE && readinessManager.isReadyFromCache()) {
|
|
39
|
+
log.error(constants_2.ERROR_CLIENT_LISTENER, ['SDK_READY_FROM_CACHE']);
|
|
40
|
+
}
|
|
37
41
|
});
|
|
38
42
|
/** Ready promise */
|
|
39
43
|
var readyPromise = generateReadyPromise();
|
|
@@ -76,6 +80,7 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
76
80
|
SDK_UPDATE: constants_1.SDK_UPDATE,
|
|
77
81
|
SDK_READY_TIMED_OUT: constants_1.SDK_READY_TIMED_OUT,
|
|
78
82
|
},
|
|
83
|
+
// @TODO: remove in next major
|
|
79
84
|
ready: function () {
|
|
80
85
|
if (readinessManager.hasTimedout()) {
|
|
81
86
|
if (!readinessManager.isReady()) {
|
|
@@ -87,6 +92,34 @@ function sdkReadinessManagerFactory(EventEmitter, settings, readinessManager) {
|
|
|
87
92
|
}
|
|
88
93
|
return readyPromise;
|
|
89
94
|
},
|
|
95
|
+
whenReady: function () {
|
|
96
|
+
return new Promise(function (resolve, reject) {
|
|
97
|
+
if (readinessManager.isReady()) {
|
|
98
|
+
resolve();
|
|
99
|
+
}
|
|
100
|
+
else if (readinessManager.hasTimedout()) {
|
|
101
|
+
reject(TIMEOUT_ERROR);
|
|
102
|
+
}
|
|
103
|
+
else {
|
|
104
|
+
readinessManager.gate.once(constants_1.SDK_READY, resolve);
|
|
105
|
+
readinessManager.gate.once(constants_1.SDK_READY_TIMED_OUT, function () { return reject(TIMEOUT_ERROR); });
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
},
|
|
109
|
+
whenReadyFromCache: function () {
|
|
110
|
+
return new Promise(function (resolve, reject) {
|
|
111
|
+
if (readinessManager.isReadyFromCache()) {
|
|
112
|
+
resolve(readinessManager.isReady());
|
|
113
|
+
}
|
|
114
|
+
else if (readinessManager.hasTimedout()) {
|
|
115
|
+
reject(TIMEOUT_ERROR);
|
|
116
|
+
}
|
|
117
|
+
else {
|
|
118
|
+
readinessManager.gate.once(constants_1.SDK_READY_FROM_CACHE, function () { return resolve(readinessManager.isReady()); });
|
|
119
|
+
readinessManager.gate.once(constants_1.SDK_READY_TIMED_OUT, function () { return reject(TIMEOUT_ERROR); });
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
},
|
|
90
123
|
__getStatus: function () {
|
|
91
124
|
return {
|
|
92
125
|
isReady: readinessManager.isReady(),
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -30,7 +30,7 @@ function stringify(options) {
|
|
|
30
30
|
* Creator of base client with getTreatments and track methods.
|
|
31
31
|
*/
|
|
32
32
|
function clientFactory(params) {
|
|
33
|
-
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker, telemetryTracker = params.telemetryTracker;
|
|
33
|
+
var readinessManager = params.sdkReadinessManager.readinessManager, storage = params.storage, settings = params.settings, impressionsTracker = params.impressionsTracker, eventTracker = params.eventTracker, telemetryTracker = params.telemetryTracker, fallbackTreatmentsCalculator = params.fallbackTreatmentsCalculator;
|
|
34
34
|
var log = settings.log, mode = settings.mode;
|
|
35
35
|
var isAsync = (0, mode_1.isConsumerMode)(mode);
|
|
36
36
|
function getTreatment(key, featureFlagName, attributes, options, withConfig, methodName) {
|
|
@@ -44,7 +44,7 @@ function clientFactory(params) {
|
|
|
44
44
|
stopTelemetryTracker(queue[0] && queue[0].imp.label);
|
|
45
45
|
return treatment;
|
|
46
46
|
};
|
|
47
|
-
var evaluation = readinessManager.
|
|
47
|
+
var evaluation = readinessManager.isReadyFromCache() ?
|
|
48
48
|
(0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage) :
|
|
49
49
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
50
50
|
Promise.resolve(treatmentNotReady) :
|
|
@@ -69,7 +69,7 @@ function clientFactory(params) {
|
|
|
69
69
|
stopTelemetryTracker(queue[0] && queue[0].imp.label);
|
|
70
70
|
return treatments;
|
|
71
71
|
};
|
|
72
|
-
var evaluations = readinessManager.
|
|
72
|
+
var evaluations = readinessManager.isReadyFromCache() ?
|
|
73
73
|
(0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage) :
|
|
74
74
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
75
75
|
Promise.resolve(treatmentsNotReady(featureFlagNames)) :
|
|
@@ -95,7 +95,7 @@ function clientFactory(params) {
|
|
|
95
95
|
stopTelemetryTracker(queue[0] && queue[0].imp.label);
|
|
96
96
|
return treatments;
|
|
97
97
|
};
|
|
98
|
-
var evaluations = readinessManager.
|
|
98
|
+
var evaluations = readinessManager.isReadyFromCache() ?
|
|
99
99
|
(0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, methodName) :
|
|
100
100
|
isAsync ?
|
|
101
101
|
Promise.resolve({}) :
|
|
@@ -115,7 +115,14 @@ function clientFactory(params) {
|
|
|
115
115
|
function processEvaluation(evaluation, featureFlagName, key, properties, withConfig, invokingMethodName, queue) {
|
|
116
116
|
var matchingKey = (0, key_1.getMatching)(key);
|
|
117
117
|
var bucketingKey = (0, key_1.getBucketing)(key);
|
|
118
|
-
var
|
|
118
|
+
var changeNumber = evaluation.changeNumber, impressionsDisabled = evaluation.impressionsDisabled;
|
|
119
|
+
var treatment = evaluation.treatment, label = evaluation.label, _a = evaluation.config, config = _a === void 0 ? null : _a;
|
|
120
|
+
if (treatment === constants_1.CONTROL) {
|
|
121
|
+
var fallbackTreatment = fallbackTreatmentsCalculator.resolve(featureFlagName, label);
|
|
122
|
+
treatment = fallbackTreatment.treatment;
|
|
123
|
+
label = fallbackTreatment.label;
|
|
124
|
+
config = fallbackTreatment.config;
|
|
125
|
+
}
|
|
119
126
|
log.info(constants_2.IMPRESSION, [featureFlagName, matchingKey, treatment, label]);
|
|
120
127
|
if ((0, splitExistence_1.validateSplitExistence)(log, readinessManager, featureFlagName, label, invokingMethodName)) {
|
|
121
128
|
log.info(constants_2.IMPRESSION_QUEUEING);
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.clientInputValidationDecorator = void 0;
|
|
4
|
-
var objectAssign_1 = require("../utils/lang/objectAssign");
|
|
5
4
|
var inputValidation_1 = require("../utils/inputValidation");
|
|
6
5
|
var lang_1 = require("../utils/lang");
|
|
7
6
|
var constants_1 = require("../utils/constants");
|
|
@@ -11,7 +10,7 @@ var splitFilters_1 = require("../utils/settingsValidation/splitFilters");
|
|
|
11
10
|
* Decorator that validates the input before actually executing the client methods.
|
|
12
11
|
* We should "guard" the client here, while not polluting the "real" implementation of those methods.
|
|
13
12
|
*/
|
|
14
|
-
function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
13
|
+
function clientInputValidationDecorator(settings, client, readinessManager, fallbackTreatmentsCalculator) {
|
|
15
14
|
var log = settings.log, mode = settings.mode;
|
|
16
15
|
var isAsync = (0, mode_1.isConsumerMode)(mode);
|
|
17
16
|
/**
|
|
@@ -27,7 +26,7 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
27
26
|
var attributes = (0, inputValidation_1.validateAttributes)(log, maybeAttributes, methodName);
|
|
28
27
|
var isNotDestroyed = (0, inputValidation_1.validateIfNotDestroyed)(log, readinessManager, methodName);
|
|
29
28
|
var options = (0, inputValidation_1.validateEvaluationOptions)(log, maybeOptions, methodName);
|
|
30
|
-
(0, inputValidation_1.
|
|
29
|
+
(0, inputValidation_1.validateIfReadyFromCache)(log, readinessManager, methodName, nameOrNames);
|
|
31
30
|
var valid = isNotDestroyed && key && nameOrNames && attributes !== false;
|
|
32
31
|
return {
|
|
33
32
|
valid: valid,
|
|
@@ -37,6 +36,16 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
37
36
|
options: options
|
|
38
37
|
};
|
|
39
38
|
}
|
|
39
|
+
function evaluateFallBackTreatment(featureFlagName, withConfig) {
|
|
40
|
+
var _a = fallbackTreatmentsCalculator.resolve(featureFlagName, ''), treatment = _a.treatment, config = _a.config;
|
|
41
|
+
if (withConfig) {
|
|
42
|
+
return {
|
|
43
|
+
treatment: treatment,
|
|
44
|
+
config: config
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
return treatment;
|
|
48
|
+
}
|
|
40
49
|
function wrapResult(value) {
|
|
41
50
|
return isAsync ? Promise.resolve(value) : value;
|
|
42
51
|
}
|
|
@@ -46,7 +55,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
46
55
|
return client.getTreatment(params.key, params.nameOrNames, params.attributes, params.options);
|
|
47
56
|
}
|
|
48
57
|
else {
|
|
49
|
-
|
|
58
|
+
var result = evaluateFallBackTreatment(params.nameOrNames, false);
|
|
59
|
+
return wrapResult(result);
|
|
50
60
|
}
|
|
51
61
|
}
|
|
52
62
|
function getTreatmentWithConfig(maybeKey, maybeFeatureFlagName, maybeAttributes, maybeOptions) {
|
|
@@ -55,7 +65,8 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
55
65
|
return client.getTreatmentWithConfig(params.key, params.nameOrNames, params.attributes, params.options);
|
|
56
66
|
}
|
|
57
67
|
else {
|
|
58
|
-
|
|
68
|
+
var result = evaluateFallBackTreatment(params.nameOrNames, true);
|
|
69
|
+
return wrapResult(result);
|
|
59
70
|
}
|
|
60
71
|
}
|
|
61
72
|
function getTreatments(maybeKey, maybeFeatureFlagNames, maybeAttributes, maybeOptions) {
|
|
@@ -66,7 +77,7 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
66
77
|
else {
|
|
67
78
|
var res_1 = {};
|
|
68
79
|
if (params.nameOrNames)
|
|
69
|
-
params.nameOrNames.forEach(function (split) { return res_1[split] =
|
|
80
|
+
params.nameOrNames.forEach(function (split) { return res_1[split] = evaluateFallBackTreatment(split, false); });
|
|
70
81
|
return wrapResult(res_1);
|
|
71
82
|
}
|
|
72
83
|
}
|
|
@@ -78,7 +89,7 @@ function clientInputValidationDecorator(settings, client, readinessManager) {
|
|
|
78
89
|
else {
|
|
79
90
|
var res_2 = {};
|
|
80
91
|
if (params.nameOrNames)
|
|
81
|
-
params.nameOrNames.forEach(function (split) { return res_2[split] = (
|
|
92
|
+
params.nameOrNames.forEach(function (split) { return res_2[split] = evaluateFallBackTreatment(split, true); });
|
|
82
93
|
return wrapResult(res_2);
|
|
83
94
|
}
|
|
84
95
|
}
|
|
@@ -35,7 +35,7 @@ function sdkClientFactory(params, isSharedClient) {
|
|
|
35
35
|
// Proto-linkage of the readiness Event Emitter
|
|
36
36
|
Object.create(sdkReadinessManager.sdkStatus),
|
|
37
37
|
// Client API (getTreatment* & track methods)
|
|
38
|
-
(0, clientInputValidation_1.clientInputValidationDecorator)(settings, (0, client_1.clientFactory)(params), sdkReadinessManager.readinessManager),
|
|
38
|
+
(0, clientInputValidation_1.clientInputValidationDecorator)(settings, (0, client_1.clientFactory)(params), sdkReadinessManager.readinessManager, params.fallbackTreatmentsCalculator),
|
|
39
39
|
// Sdk destroy
|
|
40
40
|
{
|
|
41
41
|
flush: function () {
|
package/cjs/sdkFactory/index.js
CHANGED
|
@@ -17,6 +17,7 @@ var uniqueKeysTracker_1 = require("../trackers/uniqueKeysTracker");
|
|
|
17
17
|
var constants_3 = require("../utils/constants");
|
|
18
18
|
var setRolloutPlan_1 = require("../storages/setRolloutPlan");
|
|
19
19
|
var key_1 = require("../utils/key");
|
|
20
|
+
var fallbackTreatmentsCalculator_1 = require("../evaluator/fallbackTreatmentsCalculator");
|
|
20
21
|
/**
|
|
21
22
|
* Modular SDK factory
|
|
22
23
|
*/
|
|
@@ -51,6 +52,7 @@ function sdkFactory(params) {
|
|
|
51
52
|
readiness.splits.emit(constants_2.SDK_SPLITS_CACHE_LOADED);
|
|
52
53
|
}
|
|
53
54
|
});
|
|
55
|
+
var fallbackTreatmentsCalculator = new fallbackTreatmentsCalculator_1.FallbackTreatmentsCalculator(settings.log, settings.fallbackTreatments);
|
|
54
56
|
if (initialRolloutPlan) {
|
|
55
57
|
(0, setRolloutPlan_1.setRolloutPlan)(log, initialRolloutPlan, storage, key && (0, key_1.getMatching)(key));
|
|
56
58
|
if (storage.splits.getChangeNumber() > -1)
|
|
@@ -71,7 +73,7 @@ function sdkFactory(params) {
|
|
|
71
73
|
var eventTracker = (0, eventTracker_1.eventTrackerFactory)(settings, storage.events, whenInit, integrationsManager, storage.telemetry);
|
|
72
74
|
// splitApi is used by SyncManager and Browser signal listener
|
|
73
75
|
var splitApi = splitApiFactory && splitApiFactory(settings, platform, telemetryTracker);
|
|
74
|
-
var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, uniqueKeysTracker: uniqueKeysTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform };
|
|
76
|
+
var ctx = { clients: clients, splitApi: splitApi, eventTracker: eventTracker, impressionsTracker: impressionsTracker, telemetryTracker: telemetryTracker, uniqueKeysTracker: uniqueKeysTracker, sdkReadinessManager: sdkReadinessManager, readiness: readiness, settings: settings, storage: storage, platform: platform, fallbackTreatmentsCalculator: fallbackTreatmentsCalculator };
|
|
75
77
|
var syncManager = syncManagerFactory && syncManagerFactory(ctx);
|
|
76
78
|
ctx.syncManager = syncManager;
|
|
77
79
|
var signalListener = SignalListener && new SignalListener(syncManager, settings, storage, splitApi);
|
package/cjs/sdkManager/index.js
CHANGED
|
@@ -54,7 +54,7 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
54
54
|
*/
|
|
55
55
|
split: function (featureFlagName) {
|
|
56
56
|
var splitName = (0, inputValidation_1.validateSplit)(log, featureFlagName, constants_1.SPLIT_FN_LABEL);
|
|
57
|
-
if (!(0, inputValidation_1.
|
|
57
|
+
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.SPLIT_FN_LABEL) || !splitName) {
|
|
58
58
|
return isAsync ? Promise.resolve(null) : null;
|
|
59
59
|
}
|
|
60
60
|
var split = splits.getSplit(splitName);
|
|
@@ -71,7 +71,7 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
71
71
|
* Get the feature flag objects present on the factory storage
|
|
72
72
|
*/
|
|
73
73
|
splits: function () {
|
|
74
|
-
if (!(0, inputValidation_1.
|
|
74
|
+
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.SPLITS_FN_LABEL)) {
|
|
75
75
|
return isAsync ? Promise.resolve([]) : [];
|
|
76
76
|
}
|
|
77
77
|
var currentSplits = splits.getAll();
|
|
@@ -83,7 +83,7 @@ function sdkManagerFactory(settings, splits, _a) {
|
|
|
83
83
|
* Get the feature flag names present on the factory storage
|
|
84
84
|
*/
|
|
85
85
|
names: function () {
|
|
86
|
-
if (!(0, inputValidation_1.
|
|
86
|
+
if (!(0, inputValidation_1.validateIfOperational)(log, readinessManager, constants_1.NAMES_FN_LABEL)) {
|
|
87
87
|
return isAsync ? Promise.resolve([]) : [];
|
|
88
88
|
}
|
|
89
89
|
var splitNames = splits.getSplitNames();
|
|
@@ -8,6 +8,6 @@ var segmentChangesUpdater_1 = require("../updaters/segmentChangesUpdater");
|
|
|
8
8
|
* Creates a sync task that periodically executes a `segmentChangesUpdater` task
|
|
9
9
|
*/
|
|
10
10
|
function segmentsSyncTaskFactory(fetchSegmentChanges, storage, readiness, settings) {
|
|
11
|
-
return (0, syncTask_1.syncTaskFactory)(settings.log, (0, segmentChangesUpdater_1.segmentChangesUpdaterFactory)(settings.log, (0, segmentChangesFetcher_1.segmentChangesFetcherFactory)(fetchSegmentChanges), storage.segments, readiness
|
|
11
|
+
return (0, syncTask_1.syncTaskFactory)(settings.log, (0, segmentChangesUpdater_1.segmentChangesUpdaterFactory)(settings.log, (0, segmentChangesFetcher_1.segmentChangesFetcherFactory)(fetchSegmentChanges), storage.segments, readiness), settings.scheduler.segmentsRefreshRate, 'segmentChangesUpdater');
|
|
12
12
|
}
|
|
13
13
|
exports.segmentsSyncTaskFactory = segmentsSyncTaskFactory;
|
|
@@ -3,7 +3,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
3
3
|
exports.segmentChangesUpdaterFactory = void 0;
|
|
4
4
|
var constants_1 = require("../../../readiness/constants");
|
|
5
5
|
var constants_2 = require("../../../logger/constants");
|
|
6
|
-
var timeout_1 = require("../../../utils/promise/timeout");
|
|
7
6
|
/**
|
|
8
7
|
* Factory of SegmentChanges updater, a task that:
|
|
9
8
|
* - fetches segment changes using `segmentChangesFetcher`
|
|
@@ -15,33 +14,22 @@ var timeout_1 = require("../../../utils/promise/timeout");
|
|
|
15
14
|
* @param segments - segments storage, with sync or async methods
|
|
16
15
|
* @param readiness - optional readiness manager. Not required for synchronizer or producer mode.
|
|
17
16
|
*/
|
|
18
|
-
function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, readiness
|
|
17
|
+
function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, readiness) {
|
|
19
18
|
var readyOnAlreadyExistentState = true;
|
|
20
|
-
function
|
|
21
|
-
if (readyOnAlreadyExistentState && requestTimeoutBeforeReady)
|
|
22
|
-
promise = (0, timeout_1.timeout)(requestTimeoutBeforeReady, promise);
|
|
23
|
-
return promise;
|
|
24
|
-
}
|
|
25
|
-
function updateSegment(segmentName, noCache, till, fetchOnlyNew, retries) {
|
|
19
|
+
function updateSegment(segmentName, noCache, till, fetchOnlyNew) {
|
|
26
20
|
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing segment " + segmentName);
|
|
27
21
|
var sincePromise = Promise.resolve(segments.getChangeNumber(segmentName));
|
|
28
22
|
return sincePromise.then(function (since) {
|
|
29
23
|
// if fetchOnlyNew flag, avoid processing already fetched segments
|
|
30
24
|
return fetchOnlyNew && since !== undefined ?
|
|
31
25
|
false :
|
|
32
|
-
segmentChangesFetcher(since || -1, segmentName, noCache, till
|
|
26
|
+
segmentChangesFetcher(since || -1, segmentName, noCache, till).then(function (changes) {
|
|
33
27
|
return Promise.all(changes.map(function (x) {
|
|
34
28
|
log.debug(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Processing " + segmentName + " with till = " + x.till + ". Added: " + x.added.length + ". Removed: " + x.removed.length);
|
|
35
29
|
return segments.update(segmentName, x.added, x.removed, x.till);
|
|
36
30
|
})).then(function (updates) {
|
|
37
31
|
return updates.some(function (update) { return update; });
|
|
38
32
|
});
|
|
39
|
-
}).catch(function (error) {
|
|
40
|
-
if (retries) {
|
|
41
|
-
log.warn(constants_2.LOG_PREFIX_SYNC_SEGMENTS + "Retrying fetch of segment " + segmentName + " (attempt #" + retries + "). Reason: " + error);
|
|
42
|
-
return updateSegment(segmentName, noCache, till, fetchOnlyNew, retries - 1);
|
|
43
|
-
}
|
|
44
|
-
throw error;
|
|
45
33
|
});
|
|
46
34
|
});
|
|
47
35
|
}
|
|
@@ -61,7 +49,8 @@ function segmentChangesUpdaterFactory(log, segmentChangesFetcher, segments, read
|
|
|
61
49
|
// If not a segment name provided, read list of available segments names to be updated.
|
|
62
50
|
var segmentsPromise = Promise.resolve(segmentName ? [segmentName] : segments.getRegisteredSegments());
|
|
63
51
|
return segmentsPromise.then(function (segmentNames) {
|
|
64
|
-
|
|
52
|
+
// Async fetchers
|
|
53
|
+
var updaters = segmentNames.map(function (segmentName) { return updateSegment(segmentName, noCache, till, fetchOnlyNew); });
|
|
65
54
|
return Promise.all(updaters).then(function (shouldUpdateFlags) {
|
|
66
55
|
// if at least one segment fetch succeeded, mark segments ready
|
|
67
56
|
if (shouldUpdateFlags.some(function (update) { return update; }) || readyOnAlreadyExistentState) {
|
|
@@ -171,14 +171,14 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
|
|
|
171
171
|
});
|
|
172
172
|
})
|
|
173
173
|
.catch(function (error) {
|
|
174
|
+
log.warn(constants_2.SYNC_SPLITS_FETCH_FAILS, [error]);
|
|
174
175
|
if (startingUp && retriesOnFailureBeforeReady > retry) {
|
|
175
176
|
retry += 1;
|
|
176
|
-
log.
|
|
177
|
+
log.info(constants_2.SYNC_SPLITS_FETCH_RETRY, [retry, error]);
|
|
177
178
|
return _splitChangesUpdater(sinces, retry);
|
|
178
179
|
}
|
|
179
180
|
else {
|
|
180
181
|
startingUp = false;
|
|
181
|
-
log.warn(constants_2.SYNC_SPLITS_FETCH_FAILS, [error]);
|
|
182
182
|
}
|
|
183
183
|
return false;
|
|
184
184
|
});
|
|
@@ -19,7 +19,7 @@ function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
|
|
|
19
19
|
// Ably error
|
|
20
20
|
var code = error.parsedData.code;
|
|
21
21
|
telemetryTracker.streamingEvent(constants_3.ABLY_ERROR, code);
|
|
22
|
-
// 401 errors due to invalid or expired token (e.g., if refresh token
|
|
22
|
+
// 401 errors due to invalid or expired token (e.g., if refresh token couldn't be executed)
|
|
23
23
|
if (40140 <= code && code <= 40149)
|
|
24
24
|
return true;
|
|
25
25
|
// Others 4XX errors (e.g., bad request from the SDK)
|
|
@@ -107,14 +107,14 @@ function telemetrySubmitterFactory(params) {
|
|
|
107
107
|
if (!telemetry || !now)
|
|
108
108
|
return; // No submitter created if telemetry cache is not defined
|
|
109
109
|
var settings = params.settings, _a = params.settings, log = _a.log, telemetryRefreshRate = _a.scheduler.telemetryRefreshRate, splitApi = params.splitApi, readiness = params.readiness, sdkReadinessManager = params.sdkReadinessManager;
|
|
110
|
-
var
|
|
110
|
+
var stopTimer = (0, timer_1.timer)(now);
|
|
111
111
|
var submitter = (0, submitter_1.firstPushWindowDecorator)((0, submitter_1.submitterFactory)(log, splitApi.postMetricsUsage, telemetry, telemetryRefreshRate, undefined, 0, true), telemetryRefreshRate);
|
|
112
112
|
readiness.gate.once(constants_2.SDK_READY_FROM_CACHE, function () {
|
|
113
|
-
telemetry.recordTimeUntilReadyFromCache(
|
|
113
|
+
telemetry.recordTimeUntilReadyFromCache(stopTimer());
|
|
114
114
|
});
|
|
115
115
|
sdkReadinessManager.incInternalReadyCbCount();
|
|
116
116
|
readiness.gate.once(constants_2.SDK_READY, function () {
|
|
117
|
-
telemetry.recordTimeUntilReady(
|
|
117
|
+
telemetry.recordTimeUntilReady(stopTimer());
|
|
118
118
|
// Post config data when the SDK is ready and if the telemetry submitter was started
|
|
119
119
|
if (submitter.isRunning()) {
|
|
120
120
|
var postMetricsConfigTask = (0, submitter_1.submitterFactory)(log, splitApi.postMetricsConfig, telemetryCacheConfigAdapter(telemetry, settings), 0, undefined, 0, true);
|
|
@@ -6,10 +6,10 @@ var timer_1 = require("../utils/timeTracker/timer");
|
|
|
6
6
|
var constants_1 = require("../utils/constants");
|
|
7
7
|
function telemetryTrackerFactory(telemetryCache, now) {
|
|
8
8
|
if (telemetryCache && now) {
|
|
9
|
-
var
|
|
9
|
+
var sessionTimer_1 = (0, timer_1.timer)(now);
|
|
10
10
|
return {
|
|
11
11
|
trackEval: function (method) {
|
|
12
|
-
var
|
|
12
|
+
var evalTimer = (0, timer_1.timer)(now);
|
|
13
13
|
return function (label) {
|
|
14
14
|
switch (label) {
|
|
15
15
|
case labels_1.EXCEPTION:
|
|
@@ -19,13 +19,13 @@ function telemetryTrackerFactory(telemetryCache, now) {
|
|
|
19
19
|
if (telemetryCache.recordNonReadyUsage)
|
|
20
20
|
telemetryCache.recordNonReadyUsage();
|
|
21
21
|
}
|
|
22
|
-
telemetryCache.recordLatency(method,
|
|
22
|
+
telemetryCache.recordLatency(method, evalTimer());
|
|
23
23
|
};
|
|
24
24
|
},
|
|
25
25
|
trackHttp: function (operation) {
|
|
26
|
-
var
|
|
26
|
+
var httpTimer = (0, timer_1.timer)(now);
|
|
27
27
|
return function (error) {
|
|
28
|
-
telemetryCache.recordHttpLatency(operation,
|
|
28
|
+
telemetryCache.recordHttpLatency(operation, httpTimer());
|
|
29
29
|
if (error && error.statusCode)
|
|
30
30
|
telemetryCache.recordHttpError(operation, error.statusCode);
|
|
31
31
|
else
|
|
@@ -34,7 +34,7 @@ function telemetryTrackerFactory(telemetryCache, now) {
|
|
|
34
34
|
},
|
|
35
35
|
sessionLength: function () {
|
|
36
36
|
if (telemetryCache.recordSessionLength)
|
|
37
|
-
telemetryCache.recordSessionLength(
|
|
37
|
+
telemetryCache.recordSessionLength(sessionTimer_1());
|
|
38
38
|
},
|
|
39
39
|
streamingEvent: function (e, d) {
|
|
40
40
|
if (e === constants_1.AUTH_REJECTION) {
|