@splitsoftware/splitio-commons 2.9.1-rc.1 → 2.10.0
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 +3 -0
- package/cjs/evaluator/index.js +15 -13
- package/cjs/sdkClient/client.js +3 -3
- package/cjs/utils/inputValidation/eventProperties.js +7 -1
- package/esm/evaluator/index.js +15 -13
- package/esm/sdkClient/client.js +3 -3
- package/esm/utils/inputValidation/eventProperties.js +7 -1
- package/package.json +1 -1
- package/src/evaluator/index.ts +16 -6
- package/src/sdkClient/client.ts +3 -3
- package/src/utils/inputValidation/eventProperties.ts +7 -1
- package/types/splitio.d.ts +8 -0
package/CHANGES.txt
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
2.10.0 (December 16, 2025)
|
|
2
|
+
- Added property `impressionsDisabled` in getTreatment(s) `evaluationOptions` parameter, to disable impressions per evaluations.
|
|
3
|
+
|
|
1
4
|
2.9.0 (November 26, 2025)
|
|
2
5
|
- Updated the SDK’s initial synchronization in Node.js (server-side) to use the `startup.requestTimeoutBeforeReady` and `startup.retriesOnFailureBeforeReady` options to control the timeout and retry behavior of segment requests.
|
|
3
6
|
- Updated the order of storage operations to prevent inconsistent states when using the `LOCALSTORAGE` storage type and the browser’s `localStorage` fails due to quota limits.
|
package/cjs/evaluator/index.js
CHANGED
|
@@ -19,7 +19,7 @@ function treatmentsException(splitNames) {
|
|
|
19
19
|
});
|
|
20
20
|
return evaluations;
|
|
21
21
|
}
|
|
22
|
-
function evaluateFeature(log, key, splitName, attributes, storage) {
|
|
22
|
+
function evaluateFeature(log, key, splitName, attributes, storage, options) {
|
|
23
23
|
var parsedSplit;
|
|
24
24
|
try {
|
|
25
25
|
parsedSplit = storage.splits.getSplit(splitName);
|
|
@@ -29,15 +29,15 @@ function evaluateFeature(log, key, splitName, attributes, storage) {
|
|
|
29
29
|
return treatmentException;
|
|
30
30
|
}
|
|
31
31
|
if ((0, thenable_1.thenable)(parsedSplit)) {
|
|
32
|
-
return parsedSplit.then(function (split) { return getEvaluation(log, key, split, attributes, storage); }).catch(
|
|
32
|
+
return parsedSplit.then(function (split) { return getEvaluation(log, key, split, attributes, storage, options); }).catch(
|
|
33
33
|
// Exception on async `getSplit` storage. For example, when the storage is redis or
|
|
34
34
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
35
35
|
function () { return treatmentException; });
|
|
36
36
|
}
|
|
37
|
-
return getEvaluation(log, key, parsedSplit, attributes, storage);
|
|
37
|
+
return getEvaluation(log, key, parsedSplit, attributes, storage, options);
|
|
38
38
|
}
|
|
39
39
|
exports.evaluateFeature = evaluateFeature;
|
|
40
|
-
function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
40
|
+
function evaluateFeatures(log, key, splitNames, attributes, storage, options) {
|
|
41
41
|
var parsedSplits;
|
|
42
42
|
try {
|
|
43
43
|
parsedSplits = storage.splits.getSplits(splitNames);
|
|
@@ -47,16 +47,16 @@ function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
|
47
47
|
return treatmentsException(splitNames);
|
|
48
48
|
}
|
|
49
49
|
return (0, thenable_1.thenable)(parsedSplits) ?
|
|
50
|
-
parsedSplits.then(function (splits) { return getEvaluations(log, key, splitNames, splits, attributes, storage); })
|
|
50
|
+
parsedSplits.then(function (splits) { return getEvaluations(log, key, splitNames, splits, attributes, storage, options); })
|
|
51
51
|
.catch(function () {
|
|
52
52
|
// Exception on async `getSplits` storage. For example, when the storage is redis or
|
|
53
53
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
54
54
|
return treatmentsException(splitNames);
|
|
55
55
|
}) :
|
|
56
|
-
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage);
|
|
56
|
+
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage, options);
|
|
57
57
|
}
|
|
58
58
|
exports.evaluateFeatures = evaluateFeatures;
|
|
59
|
-
function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
|
|
59
|
+
function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method, options) {
|
|
60
60
|
var storedFlagNames;
|
|
61
61
|
function evaluate(featureFlagsByFlagSets) {
|
|
62
62
|
var featureFlags = new Set();
|
|
@@ -70,7 +70,7 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, met
|
|
|
70
70
|
}
|
|
71
71
|
}
|
|
72
72
|
return featureFlags.size ?
|
|
73
|
-
evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage) :
|
|
73
|
+
evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage, options) :
|
|
74
74
|
{};
|
|
75
75
|
}
|
|
76
76
|
// get features by flag sets
|
|
@@ -90,7 +90,7 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, met
|
|
|
90
90
|
evaluate(storedFlagNames);
|
|
91
91
|
}
|
|
92
92
|
exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
|
|
93
|
-
function getEvaluation(log, key, splitJSON, attributes, storage) {
|
|
93
|
+
function getEvaluation(log, key, splitJSON, attributes, storage, options) {
|
|
94
94
|
var evaluation = {
|
|
95
95
|
treatment: constants_1.CONTROL,
|
|
96
96
|
label: labels_1.SPLIT_NOT_FOUND,
|
|
@@ -104,23 +104,25 @@ function getEvaluation(log, key, splitJSON, attributes, storage) {
|
|
|
104
104
|
return evaluation.then(function (result) {
|
|
105
105
|
result.changeNumber = splitJSON.changeNumber;
|
|
106
106
|
result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
|
|
107
|
-
|
|
107
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
108
|
+
result.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || splitJSON.impressionsDisabled;
|
|
108
109
|
return result;
|
|
109
110
|
});
|
|
110
111
|
}
|
|
111
112
|
else {
|
|
112
113
|
evaluation.changeNumber = splitJSON.changeNumber;
|
|
113
114
|
evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
|
|
114
|
-
|
|
115
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
116
|
+
evaluation.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || splitJSON.impressionsDisabled;
|
|
115
117
|
}
|
|
116
118
|
}
|
|
117
119
|
return evaluation;
|
|
118
120
|
}
|
|
119
|
-
function getEvaluations(log, key, splitNames, splits, attributes, storage) {
|
|
121
|
+
function getEvaluations(log, key, splitNames, splits, attributes, storage, options) {
|
|
120
122
|
var result = {};
|
|
121
123
|
var thenables = [];
|
|
122
124
|
splitNames.forEach(function (splitName) {
|
|
123
|
-
var evaluation = getEvaluation(log, key, splits[splitName], attributes, storage);
|
|
125
|
+
var evaluation = getEvaluation(log, key, splits[splitName], attributes, storage, options);
|
|
124
126
|
if ((0, thenable_1.thenable)(evaluation)) {
|
|
125
127
|
thenables.push(evaluation.then(function (res) {
|
|
126
128
|
result[splitName] = res;
|
package/cjs/sdkClient/client.js
CHANGED
|
@@ -45,7 +45,7 @@ function clientFactory(params) {
|
|
|
45
45
|
return treatment;
|
|
46
46
|
};
|
|
47
47
|
var evaluation = readinessManager.isReadyFromCache() ?
|
|
48
|
-
(0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage) :
|
|
48
|
+
(0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage, options) :
|
|
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) :
|
|
51
51
|
treatmentNotReady;
|
|
@@ -70,7 +70,7 @@ function clientFactory(params) {
|
|
|
70
70
|
return treatments;
|
|
71
71
|
};
|
|
72
72
|
var evaluations = readinessManager.isReadyFromCache() ?
|
|
73
|
-
(0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage) :
|
|
73
|
+
(0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage, options) :
|
|
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)) :
|
|
76
76
|
treatmentsNotReady(featureFlagNames);
|
|
@@ -96,7 +96,7 @@ function clientFactory(params) {
|
|
|
96
96
|
return treatments;
|
|
97
97
|
};
|
|
98
98
|
var evaluations = readinessManager.isReadyFromCache() ?
|
|
99
|
-
(0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, methodName) :
|
|
99
|
+
(0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, methodName, options) :
|
|
100
100
|
isAsync ?
|
|
101
101
|
Promise.resolve({}) :
|
|
102
102
|
{};
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.validateEvaluationOptions = exports.validateEventProperties = void 0;
|
|
4
|
+
var tslib_1 = require("tslib");
|
|
4
5
|
var lang_1 = require("../lang");
|
|
5
6
|
var objectAssign_1 = require("../lang/objectAssign");
|
|
6
7
|
var constants_1 = require("../../logger/constants");
|
|
@@ -64,7 +65,12 @@ exports.validateEventProperties = validateEventProperties;
|
|
|
64
65
|
function validateEvaluationOptions(log, maybeOptions, method) {
|
|
65
66
|
if ((0, lang_1.isObject)(maybeOptions)) {
|
|
66
67
|
var properties = validateEventProperties(log, maybeOptions.properties, method).properties;
|
|
67
|
-
|
|
68
|
+
var options = properties && Object.keys(properties).length > 0 ? { properties: properties } : undefined;
|
|
69
|
+
var impressionsDisabled = maybeOptions.impressionsDisabled;
|
|
70
|
+
if (!impressionsDisabled)
|
|
71
|
+
return options;
|
|
72
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
73
|
+
return options ? (0, tslib_1.__assign)((0, tslib_1.__assign)({}, options), { impressionsDisabled: impressionsDisabled }) : { impressionsDisabled: impressionsDisabled };
|
|
68
74
|
}
|
|
69
75
|
else if (maybeOptions) {
|
|
70
76
|
log.error(constants_1.ERROR_NOT_PLAIN_OBJECT, [method, 'evaluation options']);
|
package/esm/evaluator/index.js
CHANGED
|
@@ -16,7 +16,7 @@ function treatmentsException(splitNames) {
|
|
|
16
16
|
});
|
|
17
17
|
return evaluations;
|
|
18
18
|
}
|
|
19
|
-
export function evaluateFeature(log, key, splitName, attributes, storage) {
|
|
19
|
+
export function evaluateFeature(log, key, splitName, attributes, storage, options) {
|
|
20
20
|
var parsedSplit;
|
|
21
21
|
try {
|
|
22
22
|
parsedSplit = storage.splits.getSplit(splitName);
|
|
@@ -26,14 +26,14 @@ export function evaluateFeature(log, key, splitName, attributes, storage) {
|
|
|
26
26
|
return treatmentException;
|
|
27
27
|
}
|
|
28
28
|
if (thenable(parsedSplit)) {
|
|
29
|
-
return parsedSplit.then(function (split) { return getEvaluation(log, key, split, attributes, storage); }).catch(
|
|
29
|
+
return parsedSplit.then(function (split) { return getEvaluation(log, key, split, attributes, storage, options); }).catch(
|
|
30
30
|
// Exception on async `getSplit` storage. For example, when the storage is redis or
|
|
31
31
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
32
32
|
function () { return treatmentException; });
|
|
33
33
|
}
|
|
34
|
-
return getEvaluation(log, key, parsedSplit, attributes, storage);
|
|
34
|
+
return getEvaluation(log, key, parsedSplit, attributes, storage, options);
|
|
35
35
|
}
|
|
36
|
-
export function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
36
|
+
export function evaluateFeatures(log, key, splitNames, attributes, storage, options) {
|
|
37
37
|
var parsedSplits;
|
|
38
38
|
try {
|
|
39
39
|
parsedSplits = storage.splits.getSplits(splitNames);
|
|
@@ -43,15 +43,15 @@ export function evaluateFeatures(log, key, splitNames, attributes, storage) {
|
|
|
43
43
|
return treatmentsException(splitNames);
|
|
44
44
|
}
|
|
45
45
|
return thenable(parsedSplits) ?
|
|
46
|
-
parsedSplits.then(function (splits) { return getEvaluations(log, key, splitNames, splits, attributes, storage); })
|
|
46
|
+
parsedSplits.then(function (splits) { return getEvaluations(log, key, splitNames, splits, attributes, storage, options); })
|
|
47
47
|
.catch(function () {
|
|
48
48
|
// Exception on async `getSplits` storage. For example, when the storage is redis or
|
|
49
49
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
50
50
|
return treatmentsException(splitNames);
|
|
51
51
|
}) :
|
|
52
|
-
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage);
|
|
52
|
+
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage, options);
|
|
53
53
|
}
|
|
54
|
-
export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
|
|
54
|
+
export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method, options) {
|
|
55
55
|
var storedFlagNames;
|
|
56
56
|
function evaluate(featureFlagsByFlagSets) {
|
|
57
57
|
var featureFlags = new Set();
|
|
@@ -65,7 +65,7 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
|
|
|
65
65
|
}
|
|
66
66
|
}
|
|
67
67
|
return featureFlags.size ?
|
|
68
|
-
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
|
|
68
|
+
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage, options) :
|
|
69
69
|
{};
|
|
70
70
|
}
|
|
71
71
|
// get features by flag sets
|
|
@@ -84,7 +84,7 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
|
|
|
84
84
|
}) :
|
|
85
85
|
evaluate(storedFlagNames);
|
|
86
86
|
}
|
|
87
|
-
function getEvaluation(log, key, splitJSON, attributes, storage) {
|
|
87
|
+
function getEvaluation(log, key, splitJSON, attributes, storage, options) {
|
|
88
88
|
var evaluation = {
|
|
89
89
|
treatment: CONTROL,
|
|
90
90
|
label: SPLIT_NOT_FOUND,
|
|
@@ -98,23 +98,25 @@ function getEvaluation(log, key, splitJSON, attributes, storage) {
|
|
|
98
98
|
return evaluation.then(function (result) {
|
|
99
99
|
result.changeNumber = splitJSON.changeNumber;
|
|
100
100
|
result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
|
|
101
|
-
|
|
101
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
102
|
+
result.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || splitJSON.impressionsDisabled;
|
|
102
103
|
return result;
|
|
103
104
|
});
|
|
104
105
|
}
|
|
105
106
|
else {
|
|
106
107
|
evaluation.changeNumber = splitJSON.changeNumber;
|
|
107
108
|
evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
|
|
108
|
-
|
|
109
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
110
|
+
evaluation.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || splitJSON.impressionsDisabled;
|
|
109
111
|
}
|
|
110
112
|
}
|
|
111
113
|
return evaluation;
|
|
112
114
|
}
|
|
113
|
-
function getEvaluations(log, key, splitNames, splits, attributes, storage) {
|
|
115
|
+
function getEvaluations(log, key, splitNames, splits, attributes, storage, options) {
|
|
114
116
|
var result = {};
|
|
115
117
|
var thenables = [];
|
|
116
118
|
splitNames.forEach(function (splitName) {
|
|
117
|
-
var evaluation = getEvaluation(log, key, splits[splitName], attributes, storage);
|
|
119
|
+
var evaluation = getEvaluation(log, key, splits[splitName], attributes, storage, options);
|
|
118
120
|
if (thenable(evaluation)) {
|
|
119
121
|
thenables.push(evaluation.then(function (res) {
|
|
120
122
|
result[splitName] = res;
|
package/esm/sdkClient/client.js
CHANGED
|
@@ -42,7 +42,7 @@ export function clientFactory(params) {
|
|
|
42
42
|
return treatment;
|
|
43
43
|
};
|
|
44
44
|
var evaluation = readinessManager.isReadyFromCache() ?
|
|
45
|
-
evaluateFeature(log, key, featureFlagName, attributes, storage) :
|
|
45
|
+
evaluateFeature(log, key, featureFlagName, attributes, storage, options) :
|
|
46
46
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
47
47
|
Promise.resolve(treatmentNotReady) :
|
|
48
48
|
treatmentNotReady;
|
|
@@ -67,7 +67,7 @@ export function clientFactory(params) {
|
|
|
67
67
|
return treatments;
|
|
68
68
|
};
|
|
69
69
|
var evaluations = readinessManager.isReadyFromCache() ?
|
|
70
|
-
evaluateFeatures(log, key, featureFlagNames, attributes, storage) :
|
|
70
|
+
evaluateFeatures(log, key, featureFlagNames, attributes, storage, options) :
|
|
71
71
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
72
72
|
Promise.resolve(treatmentsNotReady(featureFlagNames)) :
|
|
73
73
|
treatmentsNotReady(featureFlagNames);
|
|
@@ -93,7 +93,7 @@ export function clientFactory(params) {
|
|
|
93
93
|
return treatments;
|
|
94
94
|
};
|
|
95
95
|
var evaluations = readinessManager.isReadyFromCache() ?
|
|
96
|
-
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) :
|
|
96
|
+
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName, options) :
|
|
97
97
|
isAsync ?
|
|
98
98
|
Promise.resolve({}) :
|
|
99
99
|
{};
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { __assign } from "tslib";
|
|
1
2
|
import { isObject, isString, isFiniteNumber, isBoolean } from '../lang';
|
|
2
3
|
import { objectAssign } from '../lang/objectAssign';
|
|
3
4
|
import { ERROR_NOT_PLAIN_OBJECT, ERROR_SIZE_EXCEEDED, WARN_SETTING_NULL, WARN_TRIMMING_PROPERTIES } from '../../logger/constants';
|
|
@@ -60,7 +61,12 @@ export function validateEventProperties(log, maybeProperties, method) {
|
|
|
60
61
|
export function validateEvaluationOptions(log, maybeOptions, method) {
|
|
61
62
|
if (isObject(maybeOptions)) {
|
|
62
63
|
var properties = validateEventProperties(log, maybeOptions.properties, method).properties;
|
|
63
|
-
|
|
64
|
+
var options = properties && Object.keys(properties).length > 0 ? { properties: properties } : undefined;
|
|
65
|
+
var impressionsDisabled = maybeOptions.impressionsDisabled;
|
|
66
|
+
if (!impressionsDisabled)
|
|
67
|
+
return options;
|
|
68
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
69
|
+
return options ? __assign(__assign({}, options), { impressionsDisabled: impressionsDisabled }) : { impressionsDisabled: impressionsDisabled };
|
|
64
70
|
}
|
|
65
71
|
else if (maybeOptions) {
|
|
66
72
|
log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'evaluation options']);
|
package/package.json
CHANGED
package/src/evaluator/index.ts
CHANGED
|
@@ -30,6 +30,7 @@ export function evaluateFeature(
|
|
|
30
30
|
splitName: string,
|
|
31
31
|
attributes: SplitIO.Attributes | undefined,
|
|
32
32
|
storage: IStorageSync | IStorageAsync,
|
|
33
|
+
options?: SplitIO.EvaluationOptions
|
|
33
34
|
): MaybeThenable<IEvaluationResult> {
|
|
34
35
|
let parsedSplit;
|
|
35
36
|
|
|
@@ -47,6 +48,7 @@ export function evaluateFeature(
|
|
|
47
48
|
split,
|
|
48
49
|
attributes,
|
|
49
50
|
storage,
|
|
51
|
+
options,
|
|
50
52
|
)).catch(
|
|
51
53
|
// Exception on async `getSplit` storage. For example, when the storage is redis or
|
|
52
54
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
@@ -60,6 +62,7 @@ export function evaluateFeature(
|
|
|
60
62
|
parsedSplit,
|
|
61
63
|
attributes,
|
|
62
64
|
storage,
|
|
65
|
+
options,
|
|
63
66
|
);
|
|
64
67
|
}
|
|
65
68
|
|
|
@@ -69,6 +72,7 @@ export function evaluateFeatures(
|
|
|
69
72
|
splitNames: string[],
|
|
70
73
|
attributes: SplitIO.Attributes | undefined,
|
|
71
74
|
storage: IStorageSync | IStorageAsync,
|
|
75
|
+
options?: SplitIO.EvaluationOptions,
|
|
72
76
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
73
77
|
let parsedSplits;
|
|
74
78
|
|
|
@@ -80,13 +84,13 @@ export function evaluateFeatures(
|
|
|
80
84
|
}
|
|
81
85
|
|
|
82
86
|
return thenable(parsedSplits) ?
|
|
83
|
-
parsedSplits.then(splits => getEvaluations(log, key, splitNames, splits, attributes, storage))
|
|
87
|
+
parsedSplits.then(splits => getEvaluations(log, key, splitNames, splits, attributes, storage, options))
|
|
84
88
|
.catch(() => {
|
|
85
89
|
// Exception on async `getSplits` storage. For example, when the storage is redis or
|
|
86
90
|
// pluggable and there is a connection issue and we can't retrieve the split to be evaluated
|
|
87
91
|
return treatmentsException(splitNames);
|
|
88
92
|
}) :
|
|
89
|
-
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage);
|
|
93
|
+
getEvaluations(log, key, splitNames, parsedSplits, attributes, storage, options);
|
|
90
94
|
}
|
|
91
95
|
|
|
92
96
|
export function evaluateFeaturesByFlagSets(
|
|
@@ -96,6 +100,7 @@ export function evaluateFeaturesByFlagSets(
|
|
|
96
100
|
attributes: SplitIO.Attributes | undefined,
|
|
97
101
|
storage: IStorageSync | IStorageAsync,
|
|
98
102
|
method: string,
|
|
103
|
+
options?: SplitIO.EvaluationOptions,
|
|
99
104
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
100
105
|
let storedFlagNames: MaybeThenable<Set<string>[]>;
|
|
101
106
|
|
|
@@ -111,7 +116,7 @@ export function evaluateFeaturesByFlagSets(
|
|
|
111
116
|
}
|
|
112
117
|
|
|
113
118
|
return featureFlags.size ?
|
|
114
|
-
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
|
|
119
|
+
evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage, options) :
|
|
115
120
|
{};
|
|
116
121
|
}
|
|
117
122
|
|
|
@@ -138,6 +143,7 @@ function getEvaluation(
|
|
|
138
143
|
splitJSON: ISplit | null,
|
|
139
144
|
attributes: SplitIO.Attributes | undefined,
|
|
140
145
|
storage: IStorageSync | IStorageAsync,
|
|
146
|
+
options?: SplitIO.EvaluationOptions,
|
|
141
147
|
): MaybeThenable<IEvaluationResult> {
|
|
142
148
|
let evaluation: MaybeThenable<IEvaluationResult> = {
|
|
143
149
|
treatment: CONTROL,
|
|
@@ -154,14 +160,16 @@ function getEvaluation(
|
|
|
154
160
|
return evaluation.then(result => {
|
|
155
161
|
result.changeNumber = splitJSON.changeNumber;
|
|
156
162
|
result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
|
|
157
|
-
|
|
163
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
164
|
+
result.impressionsDisabled = options?.impressionsDisabled || splitJSON.impressionsDisabled;
|
|
158
165
|
|
|
159
166
|
return result;
|
|
160
167
|
});
|
|
161
168
|
} else {
|
|
162
169
|
evaluation.changeNumber = splitJSON.changeNumber;
|
|
163
170
|
evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
|
|
164
|
-
|
|
171
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
172
|
+
evaluation.impressionsDisabled = options?.impressionsDisabled || splitJSON.impressionsDisabled;
|
|
165
173
|
}
|
|
166
174
|
}
|
|
167
175
|
|
|
@@ -175,6 +183,7 @@ function getEvaluations(
|
|
|
175
183
|
splits: Record<string, ISplit | null>,
|
|
176
184
|
attributes: SplitIO.Attributes | undefined,
|
|
177
185
|
storage: IStorageSync | IStorageAsync,
|
|
186
|
+
options?: SplitIO.EvaluationOptions,
|
|
178
187
|
): MaybeThenable<Record<string, IEvaluationResult>> {
|
|
179
188
|
const result: Record<string, IEvaluationResult> = {};
|
|
180
189
|
const thenables: Promise<void>[] = [];
|
|
@@ -184,7 +193,8 @@ function getEvaluations(
|
|
|
184
193
|
key,
|
|
185
194
|
splits[splitName],
|
|
186
195
|
attributes,
|
|
187
|
-
storage
|
|
196
|
+
storage,
|
|
197
|
+
options
|
|
188
198
|
);
|
|
189
199
|
if (thenable(evaluation)) {
|
|
190
200
|
thenables.push(evaluation.then(res => {
|
package/src/sdkClient/client.ts
CHANGED
|
@@ -52,7 +52,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
52
52
|
};
|
|
53
53
|
|
|
54
54
|
const evaluation = readinessManager.isReadyFromCache() ?
|
|
55
|
-
evaluateFeature(log, key, featureFlagName, attributes, storage) :
|
|
55
|
+
evaluateFeature(log, key, featureFlagName, attributes, storage, options) :
|
|
56
56
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
57
57
|
Promise.resolve(treatmentNotReady) :
|
|
58
58
|
treatmentNotReady;
|
|
@@ -81,7 +81,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
81
81
|
};
|
|
82
82
|
|
|
83
83
|
const evaluations = readinessManager.isReadyFromCache() ?
|
|
84
|
-
evaluateFeatures(log, key, featureFlagNames, attributes, storage) :
|
|
84
|
+
evaluateFeatures(log, key, featureFlagNames, attributes, storage, options) :
|
|
85
85
|
isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
|
|
86
86
|
Promise.resolve(treatmentsNotReady(featureFlagNames)) :
|
|
87
87
|
treatmentsNotReady(featureFlagNames);
|
|
@@ -110,7 +110,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
|
|
|
110
110
|
};
|
|
111
111
|
|
|
112
112
|
const evaluations = readinessManager.isReadyFromCache() ?
|
|
113
|
-
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) :
|
|
113
|
+
evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName, options) :
|
|
114
114
|
isAsync ?
|
|
115
115
|
Promise.resolve({}) :
|
|
116
116
|
{};
|
|
@@ -70,7 +70,13 @@ export function validateEventProperties(log: ILogger, maybeProperties: any, meth
|
|
|
70
70
|
export function validateEvaluationOptions(log: ILogger, maybeOptions: any, method: string): SplitIO.EvaluationOptions | undefined {
|
|
71
71
|
if (isObject(maybeOptions)) {
|
|
72
72
|
const properties = validateEventProperties(log, maybeOptions.properties, method).properties;
|
|
73
|
-
|
|
73
|
+
let options = properties && Object.keys(properties).length > 0 ? { properties } : undefined;
|
|
74
|
+
|
|
75
|
+
const impressionsDisabled = maybeOptions.impressionsDisabled;
|
|
76
|
+
if (!impressionsDisabled) return options;
|
|
77
|
+
|
|
78
|
+
// @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
|
|
79
|
+
return options ? { ...options, impressionsDisabled } : { impressionsDisabled };
|
|
74
80
|
} else if (maybeOptions) {
|
|
75
81
|
log.error(ERROR_NOT_PLAIN_OBJECT, [method, 'evaluation options']);
|
|
76
82
|
}
|
package/types/splitio.d.ts
CHANGED
|
@@ -918,8 +918,16 @@ declare namespace SplitIO {
|
|
|
918
918
|
* Evaluation options object for getTreatment methods.
|
|
919
919
|
*/
|
|
920
920
|
type EvaluationOptions = {
|
|
921
|
+
/**
|
|
922
|
+
* Whether the evaluation/s will track impressions or not.
|
|
923
|
+
*
|
|
924
|
+
* @defaultValue `false`
|
|
925
|
+
*/
|
|
926
|
+
// impressionsDisabled?: boolean;
|
|
921
927
|
/**
|
|
922
928
|
* Optional properties to append to the generated impression object sent to Split backend.
|
|
929
|
+
*
|
|
930
|
+
* @defaultValue `undefined`
|
|
923
931
|
*/
|
|
924
932
|
properties?: Properties;
|
|
925
933
|
}
|