@splitsoftware/splitio-commons 3.1.1-rc.0 → 3.1.1-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 CHANGED
@@ -1,4 +1,4 @@
1
- 3.2.0 (July 31, 2026)
1
+ 3.2.0 (August 10, 2026)
2
2
  - Added support for AI configs.
3
3
  - Removed Configs SDK-related types and modules and moved them to the Configs SDK repository.
4
4
 
@@ -23,7 +23,7 @@ function conditionContext(log, matcherEvaluator, treatments, label, conditionTyp
23
23
  // Whitelisting has more priority than traffic allocation, so we don't apply this filtering to those conditions.
24
24
  if (conditionType === 'ROLLOUT' && !(0, engineUtils_1.shouldApplyRollout)(trafficAllocation, key.bucketingKey, trafficAllocationSeed)) {
25
25
  return {
26
- treatment: undefined,
26
+ // treatment value is assigned later, at Engine's evaluationResult
27
27
  label: labels_1.NOT_IN_SPLIT
28
28
  };
29
29
  }
@@ -7,6 +7,7 @@ var labels_1 = require("../utils/labels");
7
7
  var constants_1 = require("../utils/constants");
8
8
  var sets_1 = require("../utils/lang/sets");
9
9
  var constants_2 = require("../logger/constants");
10
+ var objectAssign_1 = require("../utils/lang/objectAssign");
10
11
  var EVALUATION_EXCEPTION = {
11
12
  treatment: constants_1.CONTROL,
12
13
  label: labels_1.EXCEPTION,
@@ -24,7 +25,7 @@ function treatmentsException(definitionNames) {
24
25
  });
25
26
  return evaluations;
26
27
  }
27
- function evaluateFeature(log, key, definitionName, attributes, storage, options) {
28
+ function evaluateFeature(log, key, definitionName, attributes, storage) {
28
29
  var definition;
29
30
  try {
30
31
  definition = storage.definitions.get(definitionName);
@@ -34,15 +35,15 @@ function evaluateFeature(log, key, definitionName, attributes, storage, options)
34
35
  return EVALUATION_EXCEPTION;
35
36
  }
36
37
  return (0, thenable_1.thenable)(definition) ?
37
- definition.then(function (definition) { return getEvaluation(log, key, definition, attributes, storage, options); })
38
+ definition.then(function (definition) { return getEvaluation(log, key, definition, attributes, storage); })
38
39
  .catch(
39
40
  // Exception on async storage. For example, when the storage is redis or
40
41
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
41
42
  function () { return EVALUATION_EXCEPTION; }) :
42
- getEvaluation(log, key, definition, attributes, storage, options);
43
+ getEvaluation(log, key, definition, attributes, storage);
43
44
  }
44
45
  exports.evaluateFeature = evaluateFeature;
45
- function evaluateFeatures(log, key, definitionNames, attributes, storage, options) {
46
+ function evaluateFeatures(log, key, definitionNames, attributes, storage) {
46
47
  var definitions;
47
48
  try {
48
49
  definitions = storage.definitions.getMany(definitionNames);
@@ -52,15 +53,15 @@ function evaluateFeatures(log, key, definitionNames, attributes, storage, option
52
53
  return treatmentsException(definitionNames);
53
54
  }
54
55
  return (0, thenable_1.thenable)(definitions) ?
55
- definitions.then(function (definitions) { return getEvaluations(log, key, definitionNames, definitions, attributes, storage, options); })
56
+ definitions.then(function (definitions) { return getEvaluations(log, key, definitionNames, definitions, attributes, storage); })
56
57
  .catch(
57
58
  // Exception on async storage. For example, when the storage is redis or
58
59
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
59
60
  function () { return treatmentsException(definitionNames); }) :
60
- getEvaluations(log, key, definitionNames, definitions, attributes, storage, options);
61
+ getEvaluations(log, key, definitionNames, definitions, attributes, storage);
61
62
  }
62
63
  exports.evaluateFeatures = evaluateFeatures;
63
- function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method, options) {
64
+ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
64
65
  var storedFlagNames;
65
66
  function evaluate(featureFlagsByFlagSets) {
66
67
  var featureFlags = new Set();
@@ -74,7 +75,7 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, met
74
75
  }
75
76
  }
76
77
  return featureFlags.size ?
77
- evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage, options) :
78
+ evaluateFeatures(log, key, (0, sets_1.setToArray)(featureFlags), attributes, storage) :
78
79
  {};
79
80
  }
80
81
  // get features by flag sets
@@ -92,30 +93,21 @@ function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, met
92
93
  evaluate(storedFlagNames);
93
94
  }
94
95
  exports.evaluateFeaturesByFlagSets = evaluateFeaturesByFlagSets;
95
- function setEvaluationDataFromDefinition(evaluation, definition, options) {
96
- evaluation.changeNumber = definition.changeNumber;
97
- evaluation.config = definition.configurations && definition.configurations[evaluation.treatment] || null;
98
- evaluation.type = definition.type;
99
- evaluation.subtype = definition.subtype;
100
- // @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
101
- evaluation.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || definition.impressionsDisabled;
102
- return evaluation;
103
- }
104
- function getEvaluation(log, key, definition, attributes, storage, options) {
96
+ function getEvaluation(log, key, definition, attributes, storage) {
105
97
  if (definition) {
106
98
  var split = (0, Engine_1.engineParser)(log, definition, storage);
107
99
  var evaluation = split.getTreatment(key, attributes, evaluateFeature);
108
100
  return (0, thenable_1.thenable)(evaluation) ?
109
- evaluation.then(function (result) { return setEvaluationDataFromDefinition(result, definition, options); }) :
110
- setEvaluationDataFromDefinition(evaluation, definition, options);
101
+ evaluation.then(function (result) { return (0, objectAssign_1.objectAssign)(result, { definition: definition }); }) :
102
+ (0, objectAssign_1.objectAssign)(evaluation, { definition: definition });
111
103
  }
112
104
  return EVALUATION_DEFINITION_NOT_FOUND;
113
105
  }
114
- function getEvaluations(log, key, definitionNames, definitions, attributes, storage, options) {
106
+ function getEvaluations(log, key, definitionNames, definitions, attributes, storage) {
115
107
  var result = {};
116
108
  var thenables = [];
117
109
  definitionNames.forEach(function (definitionName) {
118
- var evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage, options);
110
+ var evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage);
119
111
  (0, thenable_1.thenable)(evaluation) ?
120
112
  thenables.push(evaluation.then(function (res) {
121
113
  result[definitionName] = res;
@@ -139,10 +131,11 @@ function evaluateDefaultTreatment(definitionName, storage) {
139
131
  exports.evaluateDefaultTreatment = evaluateDefaultTreatment;
140
132
  function getDefaultTreatment(definition) {
141
133
  if (definition) {
142
- return setEvaluationDataFromDefinition({
134
+ return {
143
135
  treatment: definition.defaultTreatment,
144
- label: labels_1.NO_CONDITION_MATCH // "default rule"
145
- }, definition);
136
+ label: labels_1.NO_CONDITION_MATCH,
137
+ definition: definition,
138
+ };
146
139
  }
147
140
  return EVALUATION_DEFINITION_NOT_FOUND;
148
141
  }
@@ -18,10 +18,10 @@ function treatmentsNotReady(featureFlagNames) {
18
18
  });
19
19
  return evaluations;
20
20
  }
21
- function stringify(options) {
22
- if (options && options.properties) {
21
+ function stringify(properties) {
22
+ if (properties) {
23
23
  try {
24
- return JSON.stringify(options.properties);
24
+ return JSON.stringify(properties);
25
25
  }
26
26
  catch ( /* JSON.stringify should never throw with validated options, but handling just in case */_a) { /* JSON.stringify should never throw with validated options, but handling just in case */ }
27
27
  }
@@ -40,13 +40,13 @@ function clientFactory(params) {
40
40
  var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? constants_1.TREATMENT_WITH_CONFIG : constants_1.TREATMENT);
41
41
  var wrapUp = function (evaluationResult) {
42
42
  var queue = [];
43
- var treatment = processEvaluation(evaluationResult, featureFlagName, key, stringify(options), withConfig, methodName, queue);
43
+ var treatment = processEvaluation(evaluationResult, featureFlagName, key, withConfig, methodName, queue, options);
44
44
  impressionsTracker.track(queue, attributes);
45
45
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
46
46
  return treatment;
47
47
  };
48
48
  var evaluation = readinessManager.isReadyFromCache() ?
49
- (0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage, options) :
49
+ (0, evaluator_1.evaluateFeature)(log, key, featureFlagName, attributes, storage) :
50
50
  isAsync ? // If the SDK is not ready, treatment may be incorrect due to having splits but not segments data, or storage is not connected
51
51
  Promise.resolve(treatmentNotReady) :
52
52
  treatmentNotReady;
@@ -62,16 +62,15 @@ function clientFactory(params) {
62
62
  var wrapUp = function (evaluationResults) {
63
63
  var queue = [];
64
64
  var treatments = {};
65
- var properties = stringify(options);
66
65
  Object.keys(evaluationResults).forEach(function (featureFlagName) {
67
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
66
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
68
67
  });
69
68
  impressionsTracker.track(queue, attributes);
70
69
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
71
70
  return treatments;
72
71
  };
73
72
  var evaluations = readinessManager.isReadyFromCache() ?
74
- (0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage, options) :
73
+ (0, evaluator_1.evaluateFeatures)(log, key, featureFlagNames, attributes, storage) :
75
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
76
75
  Promise.resolve(treatmentsNotReady(featureFlagNames)) :
77
76
  treatmentsNotReady(featureFlagNames);
@@ -88,16 +87,15 @@ function clientFactory(params) {
88
87
  var wrapUp = function (evaluationResults) {
89
88
  var queue = [];
90
89
  var treatments = {};
91
- var properties = stringify(options);
92
90
  Object.keys(evaluationResults).forEach(function (featureFlagName) {
93
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
91
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
94
92
  });
95
93
  impressionsTracker.track(queue, attributes);
96
94
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
97
95
  return treatments;
98
96
  };
99
97
  var evaluations = readinessManager.isReadyFromCache() ?
100
- (0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, methodName, options) :
98
+ (0, evaluator_1.evaluateFeaturesByFlagSets)(log, key, flagSetNames, attributes, storage, methodName) :
101
99
  isAsync ?
102
100
  Promise.resolve({}) :
103
101
  {};
@@ -113,11 +111,14 @@ function clientFactory(params) {
113
111
  return getTreatmentsByFlagSets(key, [flagSetName], attributes, options, true, constants_1.TREATMENTS_WITH_CONFIG_BY_FLAGSET, constants_1.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
114
112
  }
115
113
  // Internal function
116
- function processEvaluation(evaluation, featureFlagName, key, properties, withConfig, invokingMethodName, queue) {
114
+ function processEvaluation(evaluation, featureFlagName, key, withConfig, invokingMethodName, queue, options) {
115
+ var _a;
116
+ if (options === void 0) { options = {}; }
117
117
  var matchingKey = (0, key_1.getMatching)(key);
118
118
  var bucketingKey = (0, key_1.getBucketing)(key);
119
- var changeNumber = evaluation.changeNumber, impressionsDisabled = evaluation.impressionsDisabled;
120
- var treatment = evaluation.treatment, label = evaluation.label, _a = evaluation.config, config = _a === void 0 ? null : _a;
119
+ var definition = evaluation.definition;
120
+ var treatment = evaluation.treatment, label = evaluation.label;
121
+ var config = ((_a = definition === null || definition === void 0 ? void 0 : definition.configurations) === null || _a === void 0 ? void 0 : _a[treatment]) || null;
121
122
  if (treatment === constants_1.CONTROL) {
122
123
  var fallbackTreatment = fallbackCalculator(featureFlagName, label);
123
124
  treatment = fallbackTreatment.treatment;
@@ -134,10 +135,10 @@ function clientFactory(params) {
134
135
  time: Date.now(),
135
136
  bucketingKey: bucketingKey,
136
137
  label: label,
137
- changeNumber: changeNumber,
138
- properties: properties
138
+ changeNumber: definition.changeNumber,
139
+ properties: stringify(options.properties)
139
140
  },
140
- disabled: impressionsDisabled
141
+ disabled: options.impressionsDisabled || definition.impressionsDisabled
141
142
  });
142
143
  }
143
144
  if (withConfig) {
@@ -20,7 +20,7 @@ export function conditionContext(log, matcherEvaluator, treatments, label, condi
20
20
  // Whitelisting has more priority than traffic allocation, so we don't apply this filtering to those conditions.
21
21
  if (conditionType === 'ROLLOUT' && !shouldApplyRollout(trafficAllocation, key.bucketingKey, trafficAllocationSeed)) {
22
22
  return {
23
- treatment: undefined,
23
+ // treatment value is assigned later, at Engine's evaluationResult
24
24
  label: NOT_IN_SPLIT
25
25
  };
26
26
  }
@@ -4,6 +4,7 @@ import { EXCEPTION, NO_CONDITION_MATCH, DEFINITION_NOT_FOUND } from '../utils/la
4
4
  import { CONTROL } from '../utils/constants';
5
5
  import { returnSetsUnion, setToArray } from '../utils/lang/sets';
6
6
  import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
7
+ import { objectAssign } from '../utils/lang/objectAssign';
7
8
  var EVALUATION_EXCEPTION = {
8
9
  treatment: CONTROL,
9
10
  label: EXCEPTION,
@@ -21,7 +22,7 @@ function treatmentsException(definitionNames) {
21
22
  });
22
23
  return evaluations;
23
24
  }
24
- export function evaluateFeature(log, key, definitionName, attributes, storage, options) {
25
+ export function evaluateFeature(log, key, definitionName, attributes, storage) {
25
26
  var definition;
26
27
  try {
27
28
  definition = storage.definitions.get(definitionName);
@@ -31,14 +32,14 @@ export function evaluateFeature(log, key, definitionName, attributes, storage, o
31
32
  return EVALUATION_EXCEPTION;
32
33
  }
33
34
  return thenable(definition) ?
34
- definition.then(function (definition) { return getEvaluation(log, key, definition, attributes, storage, options); })
35
+ definition.then(function (definition) { return getEvaluation(log, key, definition, attributes, storage); })
35
36
  .catch(
36
37
  // Exception on async storage. For example, when the storage is redis or
37
38
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
38
39
  function () { return EVALUATION_EXCEPTION; }) :
39
- getEvaluation(log, key, definition, attributes, storage, options);
40
+ getEvaluation(log, key, definition, attributes, storage);
40
41
  }
41
- export function evaluateFeatures(log, key, definitionNames, attributes, storage, options) {
42
+ export function evaluateFeatures(log, key, definitionNames, attributes, storage) {
42
43
  var definitions;
43
44
  try {
44
45
  definitions = storage.definitions.getMany(definitionNames);
@@ -48,14 +49,14 @@ export function evaluateFeatures(log, key, definitionNames, attributes, storage,
48
49
  return treatmentsException(definitionNames);
49
50
  }
50
51
  return thenable(definitions) ?
51
- definitions.then(function (definitions) { return getEvaluations(log, key, definitionNames, definitions, attributes, storage, options); })
52
+ definitions.then(function (definitions) { return getEvaluations(log, key, definitionNames, definitions, attributes, storage); })
52
53
  .catch(
53
54
  // Exception on async storage. For example, when the storage is redis or
54
55
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
55
56
  function () { return treatmentsException(definitionNames); }) :
56
- getEvaluations(log, key, definitionNames, definitions, attributes, storage, options);
57
+ getEvaluations(log, key, definitionNames, definitions, attributes, storage);
57
58
  }
58
- export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method, options) {
59
+ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, storage, method) {
59
60
  var storedFlagNames;
60
61
  function evaluate(featureFlagsByFlagSets) {
61
62
  var featureFlags = new Set();
@@ -69,7 +70,7 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
69
70
  }
70
71
  }
71
72
  return featureFlags.size ?
72
- evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage, options) :
73
+ evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
73
74
  {};
74
75
  }
75
76
  // get features by flag sets
@@ -86,30 +87,21 @@ export function evaluateFeaturesByFlagSets(log, key, flagSets, attributes, stora
86
87
  .catch(function () { return ({}); }) :
87
88
  evaluate(storedFlagNames);
88
89
  }
89
- function setEvaluationDataFromDefinition(evaluation, definition, options) {
90
- evaluation.changeNumber = definition.changeNumber;
91
- evaluation.config = definition.configurations && definition.configurations[evaluation.treatment] || null;
92
- evaluation.type = definition.type;
93
- evaluation.subtype = definition.subtype;
94
- // @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
95
- evaluation.impressionsDisabled = (options === null || options === void 0 ? void 0 : options.impressionsDisabled) || definition.impressionsDisabled;
96
- return evaluation;
97
- }
98
- function getEvaluation(log, key, definition, attributes, storage, options) {
90
+ function getEvaluation(log, key, definition, attributes, storage) {
99
91
  if (definition) {
100
92
  var split = engineParser(log, definition, storage);
101
93
  var evaluation = split.getTreatment(key, attributes, evaluateFeature);
102
94
  return thenable(evaluation) ?
103
- evaluation.then(function (result) { return setEvaluationDataFromDefinition(result, definition, options); }) :
104
- setEvaluationDataFromDefinition(evaluation, definition, options);
95
+ evaluation.then(function (result) { return objectAssign(result, { definition: definition }); }) :
96
+ objectAssign(evaluation, { definition: definition });
105
97
  }
106
98
  return EVALUATION_DEFINITION_NOT_FOUND;
107
99
  }
108
- function getEvaluations(log, key, definitionNames, definitions, attributes, storage, options) {
100
+ function getEvaluations(log, key, definitionNames, definitions, attributes, storage) {
109
101
  var result = {};
110
102
  var thenables = [];
111
103
  definitionNames.forEach(function (definitionName) {
112
- var evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage, options);
104
+ var evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage);
113
105
  thenable(evaluation) ?
114
106
  thenables.push(evaluation.then(function (res) {
115
107
  result[definitionName] = res;
@@ -132,10 +124,11 @@ export function evaluateDefaultTreatment(definitionName, storage) {
132
124
  }
133
125
  function getDefaultTreatment(definition) {
134
126
  if (definition) {
135
- return setEvaluationDataFromDefinition({
127
+ return {
136
128
  treatment: definition.defaultTreatment,
137
- label: NO_CONDITION_MATCH // "default rule"
138
- }, definition);
129
+ label: NO_CONDITION_MATCH,
130
+ definition: definition,
131
+ };
139
132
  }
140
133
  return EVALUATION_DEFINITION_NOT_FOUND;
141
134
  }
@@ -15,10 +15,10 @@ function treatmentsNotReady(featureFlagNames) {
15
15
  });
16
16
  return evaluations;
17
17
  }
18
- export function stringify(options) {
19
- if (options && options.properties) {
18
+ export function stringify(properties) {
19
+ if (properties) {
20
20
  try {
21
- return JSON.stringify(options.properties);
21
+ return JSON.stringify(properties);
22
22
  }
23
23
  catch ( /* JSON.stringify should never throw with validated options, but handling just in case */_a) { /* JSON.stringify should never throw with validated options, but handling just in case */ }
24
24
  }
@@ -36,13 +36,13 @@ export function clientFactory(params) {
36
36
  var stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENT_WITH_CONFIG : TREATMENT);
37
37
  var wrapUp = function (evaluationResult) {
38
38
  var queue = [];
39
- var treatment = processEvaluation(evaluationResult, featureFlagName, key, stringify(options), withConfig, methodName, queue);
39
+ var treatment = processEvaluation(evaluationResult, featureFlagName, key, withConfig, methodName, queue, options);
40
40
  impressionsTracker.track(queue, attributes);
41
41
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
42
42
  return treatment;
43
43
  };
44
44
  var evaluation = readinessManager.isReadyFromCache() ?
45
- evaluateFeature(log, key, featureFlagName, attributes, storage, options) :
45
+ evaluateFeature(log, key, featureFlagName, attributes, storage) :
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;
@@ -58,16 +58,15 @@ export function clientFactory(params) {
58
58
  var wrapUp = function (evaluationResults) {
59
59
  var queue = [];
60
60
  var treatments = {};
61
- var properties = stringify(options);
62
61
  Object.keys(evaluationResults).forEach(function (featureFlagName) {
63
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
62
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
64
63
  });
65
64
  impressionsTracker.track(queue, attributes);
66
65
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
67
66
  return treatments;
68
67
  };
69
68
  var evaluations = readinessManager.isReadyFromCache() ?
70
- evaluateFeatures(log, key, featureFlagNames, attributes, storage, options) :
69
+ evaluateFeatures(log, key, featureFlagNames, attributes, storage) :
71
70
  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
71
  Promise.resolve(treatmentsNotReady(featureFlagNames)) :
73
72
  treatmentsNotReady(featureFlagNames);
@@ -84,16 +83,15 @@ export function clientFactory(params) {
84
83
  var wrapUp = function (evaluationResults) {
85
84
  var queue = [];
86
85
  var treatments = {};
87
- var properties = stringify(options);
88
86
  Object.keys(evaluationResults).forEach(function (featureFlagName) {
89
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
87
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
90
88
  });
91
89
  impressionsTracker.track(queue, attributes);
92
90
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
93
91
  return treatments;
94
92
  };
95
93
  var evaluations = readinessManager.isReadyFromCache() ?
96
- evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName, options) :
94
+ evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) :
97
95
  isAsync ?
98
96
  Promise.resolve({}) :
99
97
  {};
@@ -109,11 +107,14 @@ export function clientFactory(params) {
109
107
  return getTreatmentsByFlagSets(key, [flagSetName], attributes, options, true, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET);
110
108
  }
111
109
  // Internal function
112
- function processEvaluation(evaluation, featureFlagName, key, properties, withConfig, invokingMethodName, queue) {
110
+ function processEvaluation(evaluation, featureFlagName, key, withConfig, invokingMethodName, queue, options) {
111
+ var _a;
112
+ if (options === void 0) { options = {}; }
113
113
  var matchingKey = getMatching(key);
114
114
  var bucketingKey = getBucketing(key);
115
- var changeNumber = evaluation.changeNumber, impressionsDisabled = evaluation.impressionsDisabled;
116
- var treatment = evaluation.treatment, label = evaluation.label, _a = evaluation.config, config = _a === void 0 ? null : _a;
115
+ var definition = evaluation.definition;
116
+ var treatment = evaluation.treatment, label = evaluation.label;
117
+ var config = ((_a = definition === null || definition === void 0 ? void 0 : definition.configurations) === null || _a === void 0 ? void 0 : _a[treatment]) || null;
117
118
  if (treatment === CONTROL) {
118
119
  var fallbackTreatment = fallbackCalculator(featureFlagName, label);
119
120
  treatment = fallbackTreatment.treatment;
@@ -130,10 +131,10 @@ export function clientFactory(params) {
130
131
  time: Date.now(),
131
132
  bucketingKey: bucketingKey,
132
133
  label: label,
133
- changeNumber: changeNumber,
134
- properties: properties
134
+ changeNumber: definition.changeNumber,
135
+ properties: stringify(options.properties)
135
136
  },
136
- disabled: impressionsDisabled
137
+ disabled: options.impressionsDisabled || definition.impressionsDisabled
137
138
  });
138
139
  }
139
140
  if (withConfig) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "3.1.1-rc.0",
3
+ "version": "3.1.1-rc.1",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
@@ -7,12 +7,12 @@ import { CONTROL } from '../utils/constants';
7
7
  import { IDefinition, MaybeThenable } from '../dtos/types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { IStorageAsync, IStorageSync } from '../storages/types';
10
- import { IEvaluation, IEvaluationResult, IDefinitionEvaluator } from './types';
10
+ import { IEvaluation, IDefinitionEvaluator } from './types';
11
11
  import { ILogger } from '../logger/types';
12
12
  import { ENGINE_DEFAULT } from '../logger/constants';
13
13
  import { prerequisitesMatcherContext } from './matchers/prerequisites';
14
14
 
15
- function evaluationResult(result: IEvaluation | undefined, defaultTreatment: string): IEvaluationResult {
15
+ function evaluationResult(result: IEvaluation | undefined, defaultTreatment: string): IEvaluation {
16
16
  return {
17
17
  treatment: get(result, 'treatment', defaultTreatment),
18
18
  label: get(result, 'label', NO_CONDITION_MATCH)
@@ -29,7 +29,7 @@ export function engineParser(log: ILogger, split: IDefinition, storage: IStorage
29
29
 
30
30
  return {
31
31
 
32
- getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: IDefinitionEvaluator): MaybeThenable<IEvaluationResult> {
32
+ getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: IDefinitionEvaluator): MaybeThenable<IEvaluation> {
33
33
 
34
34
  const parsedKey = keyParser(key);
35
35
 
@@ -29,9 +29,9 @@ export function conditionContext(log: ILogger, matcherEvaluator: (key: SplitIO.S
29
29
  // Whitelisting has more priority than traffic allocation, so we don't apply this filtering to those conditions.
30
30
  if (conditionType === 'ROLLOUT' && !shouldApplyRollout(trafficAllocation!, key.bucketingKey, trafficAllocationSeed!)) {
31
31
  return {
32
- treatment: undefined, // treatment value is assigned later
32
+ // treatment value is assigned later, at Engine's evaluationResult
33
33
  label: NOT_IN_SPLIT
34
- };
34
+ } as IEvaluation;
35
35
  }
36
36
 
37
37
  // matcherEvaluator could be Async, this relays on matchers return value, so we need
@@ -4,11 +4,12 @@ import { EXCEPTION, NO_CONDITION_MATCH, DEFINITION_NOT_FOUND } from '../utils/la
4
4
  import { CONTROL } from '../utils/constants';
5
5
  import { IDefinition, MaybeThenable } from '../dtos/types';
6
6
  import { IStorageAsync, IStorageSync } from '../storages/types';
7
- import { IEvaluationResult } from './types';
7
+ import { IEvaluation } from './types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { ILogger } from '../logger/types';
10
10
  import { returnSetsUnion, setToArray } from '../utils/lang/sets';
11
11
  import { WARN_FLAGSET_WITHOUT_FLAGS } from '../logger/constants';
12
+ import { objectAssign } from '../utils/lang/objectAssign';
12
13
 
13
14
  const EVALUATION_EXCEPTION = {
14
15
  treatment: CONTROL,
@@ -23,7 +24,7 @@ const EVALUATION_DEFINITION_NOT_FOUND = {
23
24
  };
24
25
 
25
26
  function treatmentsException(definitionNames: string[]) {
26
- const evaluations: Record<string, IEvaluationResult> = {};
27
+ const evaluations: Record<string, IEvaluation> = {};
27
28
  definitionNames.forEach(definitionName => {
28
29
  evaluations[definitionName] = EVALUATION_EXCEPTION;
29
30
  });
@@ -36,8 +37,7 @@ export function evaluateFeature(
36
37
  definitionName: string,
37
38
  attributes: SplitIO.Attributes | undefined,
38
39
  storage: IStorageSync | IStorageAsync,
39
- options?: SplitIO.EvaluationOptions
40
- ): MaybeThenable<IEvaluationResult> {
40
+ ): MaybeThenable<IEvaluation> {
41
41
  let definition;
42
42
 
43
43
  try {
@@ -48,13 +48,13 @@ export function evaluateFeature(
48
48
  }
49
49
 
50
50
  return thenable(definition) ?
51
- definition.then((definition) => getEvaluation(log, key, definition, attributes, storage, options))
51
+ definition.then((definition) => getEvaluation(log, key, definition, attributes, storage))
52
52
  .catch(
53
53
  // Exception on async storage. For example, when the storage is redis or
54
54
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
55
55
  () => EVALUATION_EXCEPTION
56
56
  ) :
57
- getEvaluation(log, key, definition, attributes, storage, options);
57
+ getEvaluation(log, key, definition, attributes, storage);
58
58
  }
59
59
 
60
60
  export function evaluateFeatures(
@@ -63,8 +63,7 @@ export function evaluateFeatures(
63
63
  definitionNames: string[],
64
64
  attributes: SplitIO.Attributes | undefined,
65
65
  storage: IStorageSync | IStorageAsync,
66
- options?: SplitIO.EvaluationOptions,
67
- ): MaybeThenable<Record<string, IEvaluationResult>> {
66
+ ): MaybeThenable<Record<string, IEvaluation>> {
68
67
  let definitions;
69
68
 
70
69
  try {
@@ -75,13 +74,13 @@ export function evaluateFeatures(
75
74
  }
76
75
 
77
76
  return thenable(definitions) ?
78
- definitions.then(definitions => getEvaluations(log, key, definitionNames, definitions, attributes, storage, options))
77
+ definitions.then(definitions => getEvaluations(log, key, definitionNames, definitions, attributes, storage))
79
78
  .catch(
80
79
  // Exception on async storage. For example, when the storage is redis or
81
80
  // pluggable and there is a connection issue and we can't retrieve the split to be evaluated
82
81
  () => treatmentsException(definitionNames)
83
82
  ) :
84
- getEvaluations(log, key, definitionNames, definitions, attributes, storage, options);
83
+ getEvaluations(log, key, definitionNames, definitions, attributes, storage);
85
84
  }
86
85
 
87
86
  export function evaluateFeaturesByFlagSets(
@@ -91,8 +90,7 @@ export function evaluateFeaturesByFlagSets(
91
90
  attributes: SplitIO.Attributes | undefined,
92
91
  storage: IStorageSync | IStorageAsync,
93
92
  method: string,
94
- options?: SplitIO.EvaluationOptions,
95
- ): MaybeThenable<Record<string, IEvaluationResult>> {
93
+ ): MaybeThenable<Record<string, IEvaluation>> {
96
94
  let storedFlagNames: MaybeThenable<Set<string>[]>;
97
95
 
98
96
  function evaluate(featureFlagsByFlagSets: Set<string>[]) {
@@ -107,7 +105,7 @@ export function evaluateFeaturesByFlagSets(
107
105
  }
108
106
 
109
107
  return featureFlags.size ?
110
- evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage, options) :
108
+ evaluateFeatures(log, key, setToArray(featureFlags), attributes, storage) :
111
109
  {};
112
110
  }
113
111
 
@@ -126,33 +124,21 @@ export function evaluateFeaturesByFlagSets(
126
124
  evaluate(storedFlagNames);
127
125
  }
128
126
 
129
- function setEvaluationDataFromDefinition(evaluation: IEvaluationResult, definition: IDefinition, options?: SplitIO.EvaluationOptions): IEvaluationResult {
130
- evaluation.changeNumber = definition.changeNumber;
131
- evaluation.config = definition.configurations && definition.configurations[evaluation.treatment] || null;
132
- evaluation.type = definition.type;
133
- evaluation.subtype = definition.subtype;
134
- // @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
135
- evaluation.impressionsDisabled = options?.impressionsDisabled || definition.impressionsDisabled;
136
-
137
- return evaluation;
138
- }
139
-
140
127
  function getEvaluation(
141
128
  log: ILogger,
142
129
  key: SplitIO.SplitKey,
143
130
  definition: IDefinition | null,
144
131
  attributes: SplitIO.Attributes | undefined,
145
132
  storage: IStorageSync | IStorageAsync,
146
- options?: SplitIO.EvaluationOptions,
147
- ): MaybeThenable<IEvaluationResult> {
133
+ ): MaybeThenable<IEvaluation> {
148
134
 
149
135
  if (definition) {
150
136
  const split = engineParser(log, definition, storage);
151
137
  const evaluation = split.getTreatment(key, attributes, evaluateFeature);
152
138
 
153
139
  return thenable(evaluation) ?
154
- evaluation.then(result => setEvaluationDataFromDefinition(result, definition, options)) :
155
- setEvaluationDataFromDefinition(evaluation, definition, options);
140
+ evaluation.then(result => objectAssign(result, { definition })) :
141
+ objectAssign(evaluation, { definition });
156
142
  }
157
143
 
158
144
  return EVALUATION_DEFINITION_NOT_FOUND;
@@ -165,12 +151,11 @@ function getEvaluations(
165
151
  definitions: Record<string, IDefinition | null>,
166
152
  attributes: SplitIO.Attributes | undefined,
167
153
  storage: IStorageSync | IStorageAsync,
168
- options?: SplitIO.EvaluationOptions,
169
- ): MaybeThenable<Record<string, IEvaluationResult>> {
170
- const result: Record<string, IEvaluationResult> = {};
154
+ ): MaybeThenable<Record<string, IEvaluation>> {
155
+ const result: Record<string, IEvaluation> = {};
171
156
  const thenables: Promise<void>[] = [];
172
157
  definitionNames.forEach(definitionName => {
173
- const evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage, options);
158
+ const evaluation = getEvaluation(log, key, definitions[definitionName], attributes, storage);
174
159
  thenable(evaluation) ?
175
160
  thenables.push(evaluation.then(res => {
176
161
  result[definitionName] = res;
@@ -184,7 +169,7 @@ function getEvaluations(
184
169
  export function evaluateDefaultTreatment(
185
170
  definitionName: string,
186
171
  storage: IStorageSync | IStorageAsync,
187
- ): MaybeThenable<IEvaluationResult> {
172
+ ): MaybeThenable<IEvaluation> {
188
173
  let definition;
189
174
 
190
175
  try {
@@ -200,12 +185,13 @@ export function evaluateDefaultTreatment(
200
185
 
201
186
  function getDefaultTreatment(
202
187
  definition: IDefinition | null,
203
- ): MaybeThenable<IEvaluationResult> {
188
+ ): MaybeThenable<IEvaluation> {
204
189
  if (definition) {
205
- return setEvaluationDataFromDefinition({
190
+ return {
206
191
  treatment: definition.defaultTreatment,
207
- label: NO_CONDITION_MATCH // "default rule"
208
- }, definition);
192
+ label: NO_CONDITION_MATCH, // "default rule"
193
+ definition,
194
+ };
209
195
  }
210
196
 
211
197
  return EVALUATION_DEFINITION_NOT_FOUND;
@@ -19,16 +19,11 @@ export interface IMatcherDto {
19
19
  }
20
20
 
21
21
  export interface IEvaluation {
22
- treatment?: string,
22
+ treatment: string,
23
23
  label: string,
24
- changeNumber?: number,
25
- config?: string | null | SplitIO.JsonObject
26
- type?: IDefinition['type']
27
- subtype?: IDefinition['subtype']
24
+ definition?: IDefinition
28
25
  }
29
26
 
30
- export type IEvaluationResult = IEvaluation & { treatment: string; impressionsDisabled?: boolean }
31
-
32
27
  export type IDefinitionEvaluator = (log: ILogger, key: SplitIO.SplitKey, definitionName: string, attributes: SplitIO.Attributes | undefined, storage: IStorageSync | IStorageAsync) => MaybeThenable<IEvaluation>
33
28
 
34
29
  export type IEvaluator = (key: SplitIO.SplitKeyObject, seed?: number, trafficAllocation?: number, trafficAllocationSeed?: number, attributes?: SplitIO.Attributes, splitEvaluator?: IDefinitionEvaluator) => MaybeThenable<IEvaluation | boolean | undefined>
@@ -4,7 +4,7 @@ import { getMatching, getBucketing } from '../utils/key';
4
4
  import { validateDefinitionExistence } from '../utils/inputValidation/definitionExistence';
5
5
  import { SDK_NOT_READY } from '../utils/labels';
6
6
  import { CONTROL, TREATMENT, TREATMENTS, TREATMENT_WITH_CONFIG, TREATMENTS_WITH_CONFIG, TREATMENTS_WITH_CONFIG_BY_FLAGSETS, TREATMENTS_BY_FLAGSETS, TREATMENTS_BY_FLAGSET, TREATMENTS_WITH_CONFIG_BY_FLAGSET, GET_TREATMENTS_WITH_CONFIG, GET_TREATMENTS_BY_FLAG_SETS, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS, GET_TREATMENTS_BY_FLAG_SET, GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET, GET_TREATMENT_WITH_CONFIG, GET_TREATMENT, GET_TREATMENTS } from '../utils/constants';
7
- import { IEvaluationResult } from '../evaluator/types';
7
+ import { IEvaluation } from '../evaluator/types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { IMPRESSION_QUEUEING } from '../logger/constants';
10
10
  import { ISdkFactoryContext } from '../sdkFactory/types';
@@ -16,17 +16,17 @@ import { trackMethodFactory } from './trackMethod';
16
16
  const treatmentNotReady = { treatment: CONTROL, label: SDK_NOT_READY };
17
17
 
18
18
  function treatmentsNotReady(featureFlagNames: string[]) {
19
- const evaluations: Record<string, IEvaluationResult> = {};
19
+ const evaluations: Record<string, IEvaluation> = {};
20
20
  featureFlagNames.forEach(featureFlagName => {
21
21
  evaluations[featureFlagName] = treatmentNotReady;
22
22
  });
23
23
  return evaluations;
24
24
  }
25
25
 
26
- export function stringify(options?: SplitIO.EvaluationOptions) {
27
- if (options && options.properties) {
26
+ export function stringify(properties?: SplitIO.Properties) {
27
+ if (properties) {
28
28
  try {
29
- return JSON.stringify(options.properties);
29
+ return JSON.stringify(properties);
30
30
  } catch { /* JSON.stringify should never throw with validated options, but handling just in case */ }
31
31
  }
32
32
  }
@@ -42,9 +42,9 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
42
42
  function getTreatment(key: SplitIO.SplitKey, featureFlagName: string, attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, methodName = GET_TREATMENT) {
43
43
  const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENT_WITH_CONFIG : TREATMENT);
44
44
 
45
- const wrapUp = (evaluationResult: IEvaluationResult) => {
45
+ const wrapUp = (evaluationResult: IEvaluation) => {
46
46
  const queue: ImpressionDecorated[] = [];
47
- const treatment = processEvaluation(evaluationResult, featureFlagName, key, stringify(options), withConfig, methodName, queue);
47
+ const treatment = processEvaluation(evaluationResult, featureFlagName, key, withConfig, methodName, queue, options);
48
48
  impressionsTracker.track(queue, attributes);
49
49
 
50
50
  stopTelemetryTracker(queue[0] && queue[0].imp.label);
@@ -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, options) :
55
+ evaluateFeature(log, key, featureFlagName, attributes, storage) :
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;
@@ -67,12 +67,11 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
67
67
  function getTreatments(key: SplitIO.SplitKey, featureFlagNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, methodName = GET_TREATMENTS) {
68
68
  const stopTelemetryTracker = telemetryTracker.trackEval(withConfig ? TREATMENTS_WITH_CONFIG : TREATMENTS);
69
69
 
70
- const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
70
+ const wrapUp = (evaluationResults: Record<string, IEvaluation>) => {
71
71
  const queue: ImpressionDecorated[] = [];
72
72
  const treatments: SplitIO.Treatments | SplitIO.TreatmentsWithConfig = {};
73
- const properties = stringify(options);
74
73
  Object.keys(evaluationResults).forEach(featureFlagName => {
75
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
74
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
76
75
  });
77
76
  impressionsTracker.track(queue, attributes);
78
77
 
@@ -81,7 +80,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
81
80
  };
82
81
 
83
82
  const evaluations = readinessManager.isReadyFromCache() ?
84
- evaluateFeatures(log, key, featureFlagNames, attributes, storage, options) :
83
+ evaluateFeatures(log, key, featureFlagNames, attributes, storage) :
85
84
  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
85
  Promise.resolve(treatmentsNotReady(featureFlagNames)) :
87
86
  treatmentsNotReady(featureFlagNames);
@@ -96,12 +95,11 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
96
95
  function getTreatmentsByFlagSets(key: SplitIO.SplitKey, flagSetNames: string[], attributes?: SplitIO.Attributes, options?: SplitIO.EvaluationOptions, withConfig = false, method: Method = TREATMENTS_BY_FLAGSETS, methodName = GET_TREATMENTS_BY_FLAG_SETS) {
97
96
  const stopTelemetryTracker = telemetryTracker.trackEval(method);
98
97
 
99
- const wrapUp = (evaluationResults: Record<string, IEvaluationResult>) => {
98
+ const wrapUp = (evaluationResults: Record<string, IEvaluation>) => {
100
99
  const queue: ImpressionDecorated[] = [];
101
100
  const treatments: SplitIO.Treatments | SplitIO.TreatmentsWithConfig = {};
102
- const properties = stringify(options);
103
101
  Object.keys(evaluationResults).forEach(featureFlagName => {
104
- treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, properties, withConfig, methodName, queue);
102
+ treatments[featureFlagName] = processEvaluation(evaluationResults[featureFlagName], featureFlagName, key, withConfig, methodName, queue, options);
105
103
  });
106
104
  impressionsTracker.track(queue, attributes);
107
105
 
@@ -110,7 +108,7 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
110
108
  };
111
109
 
112
110
  const evaluations = readinessManager.isReadyFromCache() ?
113
- evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName, options) :
111
+ evaluateFeaturesByFlagSets(log, key, flagSetNames, attributes, storage, methodName) :
114
112
  isAsync ?
115
113
  Promise.resolve({}) :
116
114
  {};
@@ -132,19 +130,20 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
132
130
 
133
131
  // Internal function
134
132
  function processEvaluation(
135
- evaluation: IEvaluationResult,
133
+ evaluation: IEvaluation,
136
134
  featureFlagName: string,
137
135
  key: SplitIO.SplitKey,
138
- properties: string | undefined,
139
136
  withConfig: boolean,
140
137
  invokingMethodName: string,
141
- queue: ImpressionDecorated[]
138
+ queue: ImpressionDecorated[],
139
+ options: SplitIO.EvaluationOptions = {}
142
140
  ): SplitIO.Treatment | SplitIO.TreatmentWithConfig {
143
141
  const matchingKey = getMatching(key);
144
142
  const bucketingKey = getBucketing(key);
145
143
 
146
- const { changeNumber, impressionsDisabled } = evaluation;
147
- let { treatment, label, config = null } = evaluation;
144
+ const { definition } = evaluation;
145
+ let { treatment, label } = evaluation;
146
+ let config = definition?.configurations?.[treatment] || null;
148
147
 
149
148
  if (treatment === CONTROL) {
150
149
  const fallbackTreatment = fallbackCalculator(featureFlagName, label);
@@ -163,10 +162,10 @@ export function clientFactory(params: ISdkFactoryContext): SplitIO.IClient | Spl
163
162
  time: Date.now(),
164
163
  bucketingKey,
165
164
  label,
166
- changeNumber: changeNumber as number,
167
- properties
168
- },
169
- disabled: impressionsDisabled
165
+ changeNumber: definition!.changeNumber,
166
+ properties: stringify(options.properties)
167
+ }, // @ts-expect-error impressionsDisabled is not exposed in the public typings yet.
168
+ disabled: options.impressionsDisabled || definition!.impressionsDisabled
170
169
  });
171
170
  }
172
171