@splitsoftware/splitio-commons 2.2.1-rc.0 → 2.2.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,6 +1,5 @@
1
1
  2.3.0 (April XXX, 2025)
2
2
  - Added support for targeting rules based on rule-based segments.
3
- - Added support for feature flag prerequisites.
4
3
 
5
4
  2.2.0 (March 28, 2025)
6
5
  - Added a new optional argument to the client `getTreatment` methods to allow passing additional evaluation options, such as a map of properties to append to the generated impressions sent to Split backend. Read more in our docs.
@@ -1,58 +1,79 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.engineParser = void 0;
3
+ exports.Engine = void 0;
4
4
  var lang_1 = require("../utils/lang");
5
5
  var parser_1 = require("./parser");
6
6
  var key_1 = require("../utils/key");
7
7
  var thenable_1 = require("../utils/promise/thenable");
8
8
  var labels_1 = require("../utils/labels");
9
9
  var constants_1 = require("../utils/constants");
10
- var constants_2 = require("../logger/constants");
11
- var prerequisites_1 = require("./matchers/prerequisites");
12
10
  function evaluationResult(result, defaultTreatment) {
13
11
  return {
14
12
  treatment: (0, lang_1.get)(result, 'treatment', defaultTreatment),
15
13
  label: (0, lang_1.get)(result, 'label', labels_1.NO_CONDITION_MATCH)
16
14
  };
17
15
  }
18
- function engineParser(log, split, storage) {
19
- var killed = split.killed, seed = split.seed, trafficAllocation = split.trafficAllocation, trafficAllocationSeed = split.trafficAllocationSeed, status = split.status, conditions = split.conditions, prerequisites = split.prerequisites;
20
- var defaultTreatment = (0, lang_1.isString)(split.defaultTreatment) ? split.defaultTreatment : constants_1.CONTROL;
21
- var evaluator = (0, parser_1.parser)(log, conditions, storage);
22
- var prerequisiteMatcher = (0, prerequisites_1.prerequisitesMatcherContext)(prerequisites, storage, log);
23
- return {
24
- getTreatment: function (key, attributes, splitEvaluator) {
25
- var parsedKey = (0, key_1.keyParser)(key);
26
- function evaluate(prerequisitesMet) {
27
- if (!prerequisitesMet) {
28
- log.debug(constants_2.ENGINE_DEFAULT, ['Prerequisite not met']);
29
- return {
30
- treatment: defaultTreatment,
31
- label: labels_1.PREREQUISITES_NOT_MET
32
- };
33
- }
34
- var evaluation = evaluator(parsedKey, seed, trafficAllocation, trafficAllocationSeed, attributes, splitEvaluator);
35
- return (0, thenable_1.thenable)(evaluation) ?
36
- evaluation.then(function (result) { return evaluationResult(result, defaultTreatment); }) :
37
- evaluationResult(evaluation, defaultTreatment);
16
+ var Engine = /** @class */ (function () {
17
+ function Engine(baseInfo, evaluator) {
18
+ this.baseInfo = baseInfo;
19
+ this.evaluator = evaluator;
20
+ // in case we don't have a default treatment in the instantiation, use 'control'
21
+ if (typeof this.baseInfo.defaultTreatment !== 'string') {
22
+ this.baseInfo.defaultTreatment = constants_1.CONTROL;
23
+ }
24
+ }
25
+ Engine.parse = function (log, splitFlatStructure, storage) {
26
+ var conditions = splitFlatStructure.conditions;
27
+ var evaluator = (0, parser_1.parser)(log, conditions, storage);
28
+ return new Engine(splitFlatStructure, evaluator);
29
+ };
30
+ Engine.prototype.getKey = function () {
31
+ return this.baseInfo.name;
32
+ };
33
+ Engine.prototype.getTreatment = function (key, attributes, splitEvaluator) {
34
+ var _a = this.baseInfo, killed = _a.killed, seed = _a.seed, defaultTreatment = _a.defaultTreatment, trafficAllocation = _a.trafficAllocation, trafficAllocationSeed = _a.trafficAllocationSeed;
35
+ var parsedKey;
36
+ var treatment;
37
+ var label;
38
+ try {
39
+ parsedKey = (0, key_1.keyParser)(key);
40
+ }
41
+ catch (err) {
42
+ return {
43
+ treatment: constants_1.CONTROL,
44
+ label: labels_1.EXCEPTION
45
+ };
46
+ }
47
+ if (this.isGarbage()) {
48
+ treatment = constants_1.CONTROL;
49
+ label = labels_1.SPLIT_ARCHIVED;
50
+ }
51
+ else if (killed) {
52
+ treatment = defaultTreatment;
53
+ label = labels_1.SPLIT_KILLED;
54
+ }
55
+ else {
56
+ var evaluation = this.evaluator(parsedKey, seed, trafficAllocation, trafficAllocationSeed, attributes, splitEvaluator);
57
+ // Evaluation could be async, so we should handle that case checking for a
58
+ // thenable object
59
+ if ((0, thenable_1.thenable)(evaluation)) {
60
+ return evaluation.then(function (result) { return evaluationResult(result, defaultTreatment); });
38
61
  }
39
- if (status === 'ARCHIVED')
40
- return {
41
- treatment: constants_1.CONTROL,
42
- label: labels_1.SPLIT_ARCHIVED
43
- };
44
- if (killed) {
45
- log.debug(constants_2.ENGINE_DEFAULT, ['Flag is killed']);
46
- return {
47
- treatment: defaultTreatment,
48
- label: labels_1.SPLIT_KILLED
49
- };
62
+ else {
63
+ return evaluationResult(evaluation, defaultTreatment);
50
64
  }
51
- var prerequisitesMet = prerequisiteMatcher({ key: key, attributes: attributes }, splitEvaluator);
52
- return (0, thenable_1.thenable)(prerequisitesMet) ?
53
- prerequisitesMet.then(evaluate) :
54
- evaluate(prerequisitesMet);
55
65
  }
66
+ return {
67
+ treatment: treatment,
68
+ label: label
69
+ };
56
70
  };
57
- }
58
- exports.engineParser = engineParser;
71
+ Engine.prototype.isGarbage = function () {
72
+ return this.baseInfo.status === 'ARCHIVED';
73
+ };
74
+ Engine.prototype.getChangeNumber = function () {
75
+ return this.baseInfo.changeNumber;
76
+ };
77
+ return Engine;
78
+ }());
79
+ exports.Engine = Engine;
@@ -97,19 +97,19 @@ function getEvaluation(log, key, splitJSON, attributes, storage) {
97
97
  config: null
98
98
  };
99
99
  if (splitJSON) {
100
- var split = (0, Engine_1.engineParser)(log, splitJSON, storage);
101
- evaluation = split.getTreatment(key, attributes, evaluateFeature);
100
+ var split_1 = Engine_1.Engine.parse(log, splitJSON, storage);
101
+ evaluation = split_1.getTreatment(key, attributes, evaluateFeature);
102
102
  // If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
103
103
  if ((0, thenable_1.thenable)(evaluation)) {
104
104
  return evaluation.then(function (result) {
105
- result.changeNumber = splitJSON.changeNumber;
105
+ result.changeNumber = split_1.getChangeNumber();
106
106
  result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
107
107
  result.impressionsDisabled = splitJSON.impressionsDisabled;
108
108
  return result;
109
109
  });
110
110
  }
111
111
  else {
112
- evaluation.changeNumber = splitJSON.changeNumber;
112
+ evaluation.changeNumber = split_1.getChangeNumber(); // Always sync and optional
113
113
  evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
114
114
  evaluation.impressionsDisabled = splitJSON.impressionsDisabled;
115
115
  }
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = 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_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = 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 = exports.CLIENT_NO_LISTENER = exports.ENGINE_VALUE_NO_ATTRIBUTES = void 0;
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 = void 0;
3
+ exports.ENGINE_VALUE_NO_ATTRIBUTES = exports.ENGINE_VALUE_INVALID = exports.USER_CONSENT_INITIAL = exports.USER_CONSENT_NOT_UPDATED = exports.USER_CONSENT_UPDATED = exports.IMPRESSIONS_TRACKER_SUCCESS = exports.EVENTS_TRACKER_SUCCESS = exports.SYNC_STOP_POLLING = exports.SYNC_CONTINUE_POLLING = exports.SYNC_START_POLLING = exports.SUBMITTERS_PUSH = exports.SUBMITTERS_PUSH_FULL_QUEUE = exports.STREAMING_DISCONNECTING = exports.STREAMING_DISABLED = exports.STREAMING_CONNECTING = exports.STREAMING_RECONNECT = exports.STREAMING_REFRESH_TOKEN = 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_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_HTTP = exports.ERROR_INVALID_CONFIG_PARAM = exports.ERROR_EMPTY_ARRAY = exports.ERROR_EMPTY = exports.ERROR_INVALID = exports.ERROR_INVALID_KEY_OBJECT = exports.ERROR_TOO_LONG = exports.ERROR_NULL = exports.ERROR_CLIENT_DESTROYED = exports.ERROR_NOT_FINITE = exports.ERROR_SIZE_EXCEEDED = exports.ERROR_NOT_PLAIN_OBJECT = 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 = exports.CLIENT_NO_LISTENER = void 0;
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 = void 0;
6
6
  /**
7
7
  * Message codes used to trim string log messages from commons and client-side API modules,
8
8
  * in order to reduce the minimal SDK size for Browser and eventually other client-side environments.
@@ -33,7 +33,6 @@ exports.SYNC_TASK_EXECUTE = 37;
33
33
  exports.SYNC_TASK_STOP = 38;
34
34
  exports.SETTINGS_SPLITS_FILTER = 39;
35
35
  exports.ENGINE_MATCHER_RESULT = 40;
36
- exports.ENGINE_DEFAULT = 41;
37
36
  exports.CLIENT_READY_FROM_CACHE = 100;
38
37
  exports.CLIENT_READY = 101;
39
38
  exports.IMPRESSION = 102;
@@ -15,7 +15,6 @@ exports.codesDebug = info_1.codesInfo.concat([
15
15
  [c.ENGINE_VALUE, c.LOG_PREFIX_ENGINE_VALUE + 'Extracted attribute `%s`. %s will be used for matching.'],
16
16
  [c.ENGINE_SANITIZE, c.LOG_PREFIX_ENGINE + ':sanitize: Attempted to sanitize %s which should be of type %s. Sanitized and processed value => %s'],
17
17
  [c.ENGINE_MATCHER_RESULT, c.LOG_PREFIX_ENGINE_MATCHER + '[%s] Result: %s. Rule value: %s. Evaluation value: %s'],
18
- [c.ENGINE_DEFAULT, c.LOG_PREFIX_ENGINE + 'Evaluates to default treatment. %s'],
19
18
  // SDK
20
19
  [c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
21
20
  [c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
@@ -29,8 +29,7 @@ function objectToView(splitObject) {
29
29
  configs: splitObject.configurations || {},
30
30
  sets: splitObject.sets || [],
31
31
  defaultTreatment: splitObject.defaultTreatment,
32
- impressionsDisabled: splitObject.impressionsDisabled === true,
33
- prerequisites: (splitObject.prerequisites || []).map(function (p) { return ({ flagName: p.n, treatments: p.ts }); }),
32
+ impressionsDisabled: splitObject.impressionsDisabled === true
34
33
  };
35
34
  }
36
35
  function objectsToViews(splitObjects) {
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PREREQUISITES_NOT_MET = exports.UNSUPPORTED_MATCHER_TYPE = exports.NOT_IN_SPLIT = exports.SPLIT_ARCHIVED = exports.EXCEPTION = exports.SDK_NOT_READY = exports.SPLIT_NOT_FOUND = exports.NO_CONDITION_MATCH = exports.SPLIT_KILLED = void 0;
3
+ exports.UNSUPPORTED_MATCHER_TYPE = exports.NOT_IN_SPLIT = exports.SPLIT_ARCHIVED = exports.EXCEPTION = exports.SDK_NOT_READY = exports.SPLIT_NOT_FOUND = exports.NO_CONDITION_MATCH = exports.SPLIT_KILLED = void 0;
4
4
  exports.SPLIT_KILLED = 'killed';
5
5
  exports.NO_CONDITION_MATCH = 'default rule';
6
6
  exports.SPLIT_NOT_FOUND = 'definition not found';
@@ -9,4 +9,3 @@ exports.EXCEPTION = 'exception';
9
9
  exports.SPLIT_ARCHIVED = 'archived';
10
10
  exports.NOT_IN_SPLIT = 'not in split';
11
11
  exports.UNSUPPORTED_MATCHER_TYPE = 'targeting rule type unsupported by sdk';
12
- exports.PREREQUISITES_NOT_MET = 'prerequisites not met';
@@ -1,54 +1,76 @@
1
- import { get, isString } from '../utils/lang';
1
+ import { get } from '../utils/lang';
2
2
  import { parser } from './parser';
3
3
  import { keyParser } from '../utils/key';
4
4
  import { thenable } from '../utils/promise/thenable';
5
- import { NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED, PREREQUISITES_NOT_MET } from '../utils/labels';
5
+ import { EXCEPTION, NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED } from '../utils/labels';
6
6
  import { CONTROL } from '../utils/constants';
7
- import { ENGINE_DEFAULT } from '../logger/constants';
8
- import { prerequisitesMatcherContext } from './matchers/prerequisites';
9
7
  function evaluationResult(result, defaultTreatment) {
10
8
  return {
11
9
  treatment: get(result, 'treatment', defaultTreatment),
12
10
  label: get(result, 'label', NO_CONDITION_MATCH)
13
11
  };
14
12
  }
15
- export function engineParser(log, split, storage) {
16
- var killed = split.killed, seed = split.seed, trafficAllocation = split.trafficAllocation, trafficAllocationSeed = split.trafficAllocationSeed, status = split.status, conditions = split.conditions, prerequisites = split.prerequisites;
17
- var defaultTreatment = isString(split.defaultTreatment) ? split.defaultTreatment : CONTROL;
18
- var evaluator = parser(log, conditions, storage);
19
- var prerequisiteMatcher = prerequisitesMatcherContext(prerequisites, storage, log);
20
- return {
21
- getTreatment: function (key, attributes, splitEvaluator) {
22
- var parsedKey = keyParser(key);
23
- function evaluate(prerequisitesMet) {
24
- if (!prerequisitesMet) {
25
- log.debug(ENGINE_DEFAULT, ['Prerequisite not met']);
26
- return {
27
- treatment: defaultTreatment,
28
- label: PREREQUISITES_NOT_MET
29
- };
30
- }
31
- var evaluation = evaluator(parsedKey, seed, trafficAllocation, trafficAllocationSeed, attributes, splitEvaluator);
32
- return thenable(evaluation) ?
33
- evaluation.then(function (result) { return evaluationResult(result, defaultTreatment); }) :
34
- evaluationResult(evaluation, defaultTreatment);
13
+ var Engine = /** @class */ (function () {
14
+ function Engine(baseInfo, evaluator) {
15
+ this.baseInfo = baseInfo;
16
+ this.evaluator = evaluator;
17
+ // in case we don't have a default treatment in the instantiation, use 'control'
18
+ if (typeof this.baseInfo.defaultTreatment !== 'string') {
19
+ this.baseInfo.defaultTreatment = CONTROL;
20
+ }
21
+ }
22
+ Engine.parse = function (log, splitFlatStructure, storage) {
23
+ var conditions = splitFlatStructure.conditions;
24
+ var evaluator = parser(log, conditions, storage);
25
+ return new Engine(splitFlatStructure, evaluator);
26
+ };
27
+ Engine.prototype.getKey = function () {
28
+ return this.baseInfo.name;
29
+ };
30
+ Engine.prototype.getTreatment = function (key, attributes, splitEvaluator) {
31
+ var _a = this.baseInfo, killed = _a.killed, seed = _a.seed, defaultTreatment = _a.defaultTreatment, trafficAllocation = _a.trafficAllocation, trafficAllocationSeed = _a.trafficAllocationSeed;
32
+ var parsedKey;
33
+ var treatment;
34
+ var label;
35
+ try {
36
+ parsedKey = keyParser(key);
37
+ }
38
+ catch (err) {
39
+ return {
40
+ treatment: CONTROL,
41
+ label: EXCEPTION
42
+ };
43
+ }
44
+ if (this.isGarbage()) {
45
+ treatment = CONTROL;
46
+ label = SPLIT_ARCHIVED;
47
+ }
48
+ else if (killed) {
49
+ treatment = defaultTreatment;
50
+ label = SPLIT_KILLED;
51
+ }
52
+ else {
53
+ var evaluation = this.evaluator(parsedKey, seed, trafficAllocation, trafficAllocationSeed, attributes, splitEvaluator);
54
+ // Evaluation could be async, so we should handle that case checking for a
55
+ // thenable object
56
+ if (thenable(evaluation)) {
57
+ return evaluation.then(function (result) { return evaluationResult(result, defaultTreatment); });
35
58
  }
36
- if (status === 'ARCHIVED')
37
- return {
38
- treatment: CONTROL,
39
- label: SPLIT_ARCHIVED
40
- };
41
- if (killed) {
42
- log.debug(ENGINE_DEFAULT, ['Flag is killed']);
43
- return {
44
- treatment: defaultTreatment,
45
- label: SPLIT_KILLED
46
- };
59
+ else {
60
+ return evaluationResult(evaluation, defaultTreatment);
47
61
  }
48
- var prerequisitesMet = prerequisiteMatcher({ key: key, attributes: attributes }, splitEvaluator);
49
- return thenable(prerequisitesMet) ?
50
- prerequisitesMet.then(evaluate) :
51
- evaluate(prerequisitesMet);
52
62
  }
63
+ return {
64
+ treatment: treatment,
65
+ label: label
66
+ };
53
67
  };
54
- }
68
+ Engine.prototype.isGarbage = function () {
69
+ return this.baseInfo.status === 'ARCHIVED';
70
+ };
71
+ Engine.prototype.getChangeNumber = function () {
72
+ return this.baseInfo.changeNumber;
73
+ };
74
+ return Engine;
75
+ }());
76
+ export { Engine };
@@ -1,4 +1,4 @@
1
- import { engineParser } from './Engine';
1
+ import { Engine } from './Engine';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { EXCEPTION, SPLIT_NOT_FOUND } from '../utils/labels';
4
4
  import { CONTROL } from '../utils/constants';
@@ -91,19 +91,19 @@ function getEvaluation(log, key, splitJSON, attributes, storage) {
91
91
  config: null
92
92
  };
93
93
  if (splitJSON) {
94
- var split = engineParser(log, splitJSON, storage);
95
- evaluation = split.getTreatment(key, attributes, evaluateFeature);
94
+ var split_1 = Engine.parse(log, splitJSON, storage);
95
+ evaluation = split_1.getTreatment(key, attributes, evaluateFeature);
96
96
  // If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
97
97
  if (thenable(evaluation)) {
98
98
  return evaluation.then(function (result) {
99
- result.changeNumber = splitJSON.changeNumber;
99
+ result.changeNumber = split_1.getChangeNumber();
100
100
  result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
101
101
  result.impressionsDisabled = splitJSON.impressionsDisabled;
102
102
  return result;
103
103
  });
104
104
  }
105
105
  else {
106
- evaluation.changeNumber = splitJSON.changeNumber;
106
+ evaluation.changeNumber = split_1.getChangeNumber(); // Always sync and optional
107
107
  evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
108
108
  evaluation.impressionsDisabled = splitJSON.impressionsDisabled;
109
109
  }
@@ -28,7 +28,6 @@ export var SYNC_TASK_EXECUTE = 37;
28
28
  export var SYNC_TASK_STOP = 38;
29
29
  export var SETTINGS_SPLITS_FILTER = 39;
30
30
  export var ENGINE_MATCHER_RESULT = 40;
31
- export var ENGINE_DEFAULT = 41;
32
31
  export var CLIENT_READY_FROM_CACHE = 100;
33
32
  export var CLIENT_READY = 101;
34
33
  export var IMPRESSION = 102;
@@ -11,7 +11,6 @@ export var codesDebug = codesInfo.concat([
11
11
  [c.ENGINE_VALUE, c.LOG_PREFIX_ENGINE_VALUE + 'Extracted attribute `%s`. %s will be used for matching.'],
12
12
  [c.ENGINE_SANITIZE, c.LOG_PREFIX_ENGINE + ':sanitize: Attempted to sanitize %s which should be of type %s. Sanitized and processed value => %s'],
13
13
  [c.ENGINE_MATCHER_RESULT, c.LOG_PREFIX_ENGINE_MATCHER + '[%s] Result: %s. Rule value: %s. Evaluation value: %s'],
14
- [c.ENGINE_DEFAULT, c.LOG_PREFIX_ENGINE + 'Evaluates to default treatment. %s'],
15
14
  // SDK
16
15
  [c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
17
16
  [c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
@@ -26,8 +26,7 @@ function objectToView(splitObject) {
26
26
  configs: splitObject.configurations || {},
27
27
  sets: splitObject.sets || [],
28
28
  defaultTreatment: splitObject.defaultTreatment,
29
- impressionsDisabled: splitObject.impressionsDisabled === true,
30
- prerequisites: (splitObject.prerequisites || []).map(function (p) { return ({ flagName: p.n, treatments: p.ts }); }),
29
+ impressionsDisabled: splitObject.impressionsDisabled === true
31
30
  };
32
31
  }
33
32
  function objectsToViews(splitObjects) {
@@ -6,4 +6,3 @@ export var EXCEPTION = 'exception';
6
6
  export var SPLIT_ARCHIVED = 'archived';
7
7
  export var NOT_IN_SPLIT = 'not in split';
8
8
  export var UNSUPPORTED_MATCHER_TYPE = 'targeting rule type unsupported by sdk';
9
- export var PREREQUISITES_NOT_MET = 'prerequisites not met';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@splitsoftware/splitio-commons",
3
- "version": "2.2.1-rc.0",
3
+ "version": "2.2.1-rc.1",
4
4
  "description": "Split JavaScript SDK common components",
5
5
  "main": "cjs/index.js",
6
6
  "module": "esm/index.js",
package/src/dtos/types.ts CHANGED
@@ -215,10 +215,6 @@ export interface ISplit {
215
215
  changeNumber: number,
216
216
  status: 'ACTIVE' | 'ARCHIVED',
217
217
  conditions: ISplitCondition[],
218
- prerequisites?: {
219
- n: string,
220
- ts: string[]
221
- }[]
222
218
  killed: boolean,
223
219
  defaultTreatment: string,
224
220
  trafficTypeName: string,
@@ -1,16 +1,14 @@
1
- import { get, isString } from '../utils/lang';
1
+ import { get } from '../utils/lang';
2
2
  import { parser } from './parser';
3
3
  import { keyParser } from '../utils/key';
4
4
  import { thenable } from '../utils/promise/thenable';
5
- import { NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED, PREREQUISITES_NOT_MET } from '../utils/labels';
5
+ import { EXCEPTION, NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED } from '../utils/labels';
6
6
  import { CONTROL } from '../utils/constants';
7
7
  import { ISplit, MaybeThenable } from '../dtos/types';
8
8
  import SplitIO from '../../types/splitio';
9
9
  import { IStorageAsync, IStorageSync } from '../storages/types';
10
- import { IEvaluation, IEvaluationResult, ISplitEvaluator } from './types';
10
+ import { IEvaluation, IEvaluationResult, IEvaluator, ISplitEvaluator } from './types';
11
11
  import { ILogger } from '../logger/types';
12
- import { ENGINE_DEFAULT } from '../logger/constants';
13
- import { prerequisitesMatcherContext } from './matchers/prerequisites';
14
12
 
15
13
  function evaluationResult(result: IEvaluation | undefined, defaultTreatment: string): IEvaluationResult {
16
14
  return {
@@ -19,55 +17,84 @@ function evaluationResult(result: IEvaluation | undefined, defaultTreatment: str
19
17
  };
20
18
  }
21
19
 
22
- export function engineParser(log: ILogger, split: ISplit, storage: IStorageSync | IStorageAsync) {
23
- const { killed, seed, trafficAllocation, trafficAllocationSeed, status, conditions, prerequisites } = split;
20
+ export class Engine {
24
21
 
25
- const defaultTreatment = isString(split.defaultTreatment) ? split.defaultTreatment : CONTROL;
22
+ constructor(private baseInfo: ISplit, private evaluator: IEvaluator) {
26
23
 
27
- const evaluator = parser(log, conditions, storage);
28
- const prerequisiteMatcher = prerequisitesMatcherContext(prerequisites, storage, log);
29
-
30
- return {
31
-
32
- getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: ISplitEvaluator): MaybeThenable<IEvaluationResult> {
24
+ // in case we don't have a default treatment in the instantiation, use 'control'
25
+ if (typeof this.baseInfo.defaultTreatment !== 'string') {
26
+ this.baseInfo.defaultTreatment = CONTROL;
27
+ }
28
+ }
33
29
 
34
- const parsedKey = keyParser(key);
30
+ static parse(log: ILogger, splitFlatStructure: ISplit, storage: IStorageSync | IStorageAsync) {
31
+ const conditions = splitFlatStructure.conditions;
32
+ const evaluator = parser(log, conditions, storage);
35
33
 
36
- function evaluate(prerequisitesMet: boolean) {
37
- if (!prerequisitesMet) {
38
- log.debug(ENGINE_DEFAULT, ['Prerequisite not met']);
39
- return {
40
- treatment: defaultTreatment,
41
- label: PREREQUISITES_NOT_MET
42
- };
43
- }
34
+ return new Engine(splitFlatStructure, evaluator);
35
+ }
44
36
 
45
- const evaluation = evaluator(parsedKey, seed, trafficAllocation, trafficAllocationSeed, attributes, splitEvaluator) as MaybeThenable<IEvaluation>;
37
+ getKey() {
38
+ return this.baseInfo.name;
39
+ }
46
40
 
47
- return thenable(evaluation) ?
48
- evaluation.then(result => evaluationResult(result, defaultTreatment)) :
49
- evaluationResult(evaluation, defaultTreatment);
50
- }
41
+ getTreatment(key: SplitIO.SplitKey, attributes: SplitIO.Attributes | undefined, splitEvaluator: ISplitEvaluator): MaybeThenable<IEvaluationResult> {
42
+ const {
43
+ killed,
44
+ seed,
45
+ defaultTreatment,
46
+ trafficAllocation,
47
+ trafficAllocationSeed
48
+ } = this.baseInfo;
49
+ let parsedKey;
50
+ let treatment;
51
+ let label;
51
52
 
52
- if (status === 'ARCHIVED') return {
53
+ try {
54
+ parsedKey = keyParser(key);
55
+ } catch (err) {
56
+ return {
53
57
  treatment: CONTROL,
54
- label: SPLIT_ARCHIVED
58
+ label: EXCEPTION
55
59
  };
60
+ }
61
+
62
+ if (this.isGarbage()) {
63
+ treatment = CONTROL;
64
+ label = SPLIT_ARCHIVED;
65
+ } else if (killed) {
66
+ treatment = defaultTreatment;
67
+ label = SPLIT_KILLED;
68
+ } else {
69
+ const evaluation = this.evaluator(
70
+ parsedKey,
71
+ seed,
72
+ trafficAllocation,
73
+ trafficAllocationSeed,
74
+ attributes,
75
+ splitEvaluator
76
+ ) as MaybeThenable<IEvaluation>;
56
77
 
57
- if (killed) {
58
- log.debug(ENGINE_DEFAULT, ['Flag is killed']);
59
- return {
60
- treatment: defaultTreatment,
61
- label: SPLIT_KILLED
62
- };
78
+ // Evaluation could be async, so we should handle that case checking for a
79
+ // thenable object
80
+ if (thenable(evaluation)) {
81
+ return evaluation.then(result => evaluationResult(result, defaultTreatment));
82
+ } else {
83
+ return evaluationResult(evaluation, defaultTreatment);
63
84
  }
85
+ }
64
86
 
65
- const prerequisitesMet = prerequisiteMatcher({ key, attributes }, splitEvaluator);
87
+ return {
88
+ treatment,
89
+ label
90
+ };
91
+ }
66
92
 
67
- return thenable(prerequisitesMet) ?
68
- prerequisitesMet.then(evaluate) :
69
- evaluate(prerequisitesMet);
70
- }
71
- };
93
+ isGarbage() {
94
+ return this.baseInfo.status === 'ARCHIVED';
95
+ }
72
96
 
97
+ getChangeNumber() {
98
+ return this.baseInfo.changeNumber;
99
+ }
73
100
  }
@@ -1,4 +1,4 @@
1
- import { engineParser } from './Engine';
1
+ import { Engine } from './Engine';
2
2
  import { thenable } from '../utils/promise/thenable';
3
3
  import { EXCEPTION, SPLIT_NOT_FOUND } from '../utils/labels';
4
4
  import { CONTROL } from '../utils/constants';
@@ -99,7 +99,9 @@ export function evaluateFeaturesByFlagSets(
99
99
  ): MaybeThenable<Record<string, IEvaluationResult>> {
100
100
  let storedFlagNames: MaybeThenable<Set<string>[]>;
101
101
 
102
- function evaluate(featureFlagsByFlagSets: Set<string>[]) {
102
+ function evaluate(
103
+ featureFlagsByFlagSets: Set<string>[],
104
+ ) {
103
105
  let featureFlags = new Set<string>();
104
106
  for (let i = 0; i < flagSets.length; i++) {
105
107
  const featureFlagByFlagSet = featureFlagsByFlagSets[i];
@@ -146,20 +148,20 @@ function getEvaluation(
146
148
  };
147
149
 
148
150
  if (splitJSON) {
149
- const split = engineParser(log, splitJSON, storage);
151
+ const split = Engine.parse(log, splitJSON, storage);
150
152
  evaluation = split.getTreatment(key, attributes, evaluateFeature);
151
153
 
152
154
  // If the storage is async and the evaluated flag uses segments or dependencies, evaluation is thenable
153
155
  if (thenable(evaluation)) {
154
156
  return evaluation.then(result => {
155
- result.changeNumber = splitJSON.changeNumber;
157
+ result.changeNumber = split.getChangeNumber();
156
158
  result.config = splitJSON.configurations && splitJSON.configurations[result.treatment] || null;
157
159
  result.impressionsDisabled = splitJSON.impressionsDisabled;
158
160
 
159
161
  return result;
160
162
  });
161
163
  } else {
162
- evaluation.changeNumber = splitJSON.changeNumber;
164
+ evaluation.changeNumber = split.getChangeNumber(); // Always sync and optional
163
165
  evaluation.config = splitJSON.configurations && splitJSON.configurations[evaluation.treatment] || null;
164
166
  evaluation.impressionsDisabled = splitJSON.impressionsDisabled;
165
167
  }
@@ -28,7 +28,6 @@ export const SYNC_TASK_EXECUTE = 37;
28
28
  export const SYNC_TASK_STOP = 38;
29
29
  export const SETTINGS_SPLITS_FILTER = 39;
30
30
  export const ENGINE_MATCHER_RESULT = 40;
31
- export const ENGINE_DEFAULT = 41;
32
31
 
33
32
  export const CLIENT_READY_FROM_CACHE = 100;
34
33
  export const CLIENT_READY = 101;
@@ -12,7 +12,6 @@ export const codesDebug: [number, string][] = codesInfo.concat([
12
12
  [c.ENGINE_VALUE, c.LOG_PREFIX_ENGINE_VALUE + 'Extracted attribute `%s`. %s will be used for matching.'],
13
13
  [c.ENGINE_SANITIZE, c.LOG_PREFIX_ENGINE + ':sanitize: Attempted to sanitize %s which should be of type %s. Sanitized and processed value => %s'],
14
14
  [c.ENGINE_MATCHER_RESULT, c.LOG_PREFIX_ENGINE_MATCHER + '[%s] Result: %s. Rule value: %s. Evaluation value: %s'],
15
- [c.ENGINE_DEFAULT, c.LOG_PREFIX_ENGINE + 'Evaluates to default treatment. %s'],
16
15
  // SDK
17
16
  [c.CLEANUP_REGISTERING, c.LOG_PREFIX_CLEANUP + 'Registering cleanup handler %s'],
18
17
  [c.CLEANUP_DEREGISTERING, c.LOG_PREFIX_CLEANUP + 'Deregistering cleanup handler %s'],
@@ -32,8 +32,7 @@ function objectToView(splitObject: ISplit | null): SplitIO.SplitView | null {
32
32
  configs: splitObject.configurations || {},
33
33
  sets: splitObject.sets || [],
34
34
  defaultTreatment: splitObject.defaultTreatment,
35
- impressionsDisabled: splitObject.impressionsDisabled === true,
36
- prerequisites: (splitObject.prerequisites || []).map(p => ({ flagName: p.n, treatments: p.ts })),
35
+ impressionsDisabled: splitObject.impressionsDisabled === true
37
36
  };
38
37
  }
39
38
 
@@ -6,4 +6,3 @@ export const EXCEPTION = 'exception';
6
6
  export const SPLIT_ARCHIVED = 'archived';
7
7
  export const NOT_IN_SPLIT = 'not in split';
8
8
  export const UNSUPPORTED_MATCHER_TYPE = 'targeting rule type unsupported by sdk';
9
- export const PREREQUISITES_NOT_MET = 'prerequisites not met';
@@ -879,7 +879,7 @@ declare namespace SplitIO {
879
879
  /**
880
880
  * The list of treatments available for the feature flag.
881
881
  */
882
- treatments: string[];
882
+ treatments: Array<string>;
883
883
  /**
884
884
  * Current change number of the feature flag.
885
885
  */
@@ -903,10 +903,6 @@ declare namespace SplitIO {
903
903
  * Whether the feature flag has impressions tracking disabled or not.
904
904
  */
905
905
  impressionsDisabled: boolean;
906
- /**
907
- * Prerequisites for the feature flag.
908
- */
909
- prerequisites: Array<{ flagName: string, treatments: string[] }>;
910
906
  };
911
907
  /**
912
908
  * A promise that resolves to a feature flag view or null if the feature flag is not found.
@@ -1,22 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.prerequisitesMatcherContext = void 0;
4
- var thenable_1 = require("../../utils/promise/thenable");
5
- function prerequisitesMatcherContext(prerequisites, storage, log) {
6
- if (prerequisites === void 0) { prerequisites = []; }
7
- return function prerequisitesMatcher(_a, splitEvaluator) {
8
- var key = _a.key, attributes = _a.attributes;
9
- function evaluatePrerequisite(prerequisite) {
10
- var evaluation = splitEvaluator(log, key, prerequisite.n, attributes, storage);
11
- return (0, thenable_1.thenable)(evaluation) ?
12
- evaluation.then(function (evaluation) { return prerequisite.ts.indexOf(evaluation.treatment) !== -1; }) :
13
- prerequisite.ts.indexOf(evaluation.treatment) !== -1;
14
- }
15
- return prerequisites.reduce(function (prerequisitesMet, prerequisite) {
16
- return (0, thenable_1.thenable)(prerequisitesMet) ?
17
- prerequisitesMet.then(function (prerequisitesMet) { return prerequisitesMet ? evaluatePrerequisite(prerequisite) : false; }) :
18
- prerequisitesMet ? evaluatePrerequisite(prerequisite) : false;
19
- }, true);
20
- };
21
- }
22
- exports.prerequisitesMatcherContext = prerequisitesMatcherContext;
@@ -1,18 +0,0 @@
1
- import { thenable } from '../../utils/promise/thenable';
2
- export function prerequisitesMatcherContext(prerequisites, storage, log) {
3
- if (prerequisites === void 0) { prerequisites = []; }
4
- return function prerequisitesMatcher(_a, splitEvaluator) {
5
- var key = _a.key, attributes = _a.attributes;
6
- function evaluatePrerequisite(prerequisite) {
7
- var evaluation = splitEvaluator(log, key, prerequisite.n, attributes, storage);
8
- return thenable(evaluation) ?
9
- evaluation.then(function (evaluation) { return prerequisite.ts.indexOf(evaluation.treatment) !== -1; }) :
10
- prerequisite.ts.indexOf(evaluation.treatment) !== -1;
11
- }
12
- return prerequisites.reduce(function (prerequisitesMet, prerequisite) {
13
- return thenable(prerequisitesMet) ?
14
- prerequisitesMet.then(function (prerequisitesMet) { return prerequisitesMet ? evaluatePrerequisite(prerequisite) : false; }) :
15
- prerequisitesMet ? evaluatePrerequisite(prerequisite) : false;
16
- }, true);
17
- };
18
- }
@@ -1,24 +0,0 @@
1
- import { ISplit, MaybeThenable } from '../../dtos/types';
2
- import { IStorageAsync, IStorageSync } from '../../storages/types';
3
- import { ILogger } from '../../logger/types';
4
- import { thenable } from '../../utils/promise/thenable';
5
- import { IDependencyMatcherValue, ISplitEvaluator } from '../types';
6
-
7
- export function prerequisitesMatcherContext(prerequisites: ISplit['prerequisites'] = [], storage: IStorageSync | IStorageAsync, log: ILogger) {
8
-
9
- return function prerequisitesMatcher({ key, attributes }: IDependencyMatcherValue, splitEvaluator: ISplitEvaluator): MaybeThenable<boolean> {
10
-
11
- function evaluatePrerequisite(prerequisite: { n: string; ts: string[] }): MaybeThenable<boolean> {
12
- const evaluation = splitEvaluator(log, key, prerequisite.n, attributes, storage);
13
- return thenable(evaluation) ?
14
- evaluation.then(evaluation => prerequisite.ts.indexOf(evaluation.treatment!) !== -1) :
15
- prerequisite.ts.indexOf(evaluation.treatment!) !== -1;
16
- }
17
-
18
- return prerequisites.reduce<MaybeThenable<boolean>>((prerequisitesMet, prerequisite) => {
19
- return thenable(prerequisitesMet) ?
20
- prerequisitesMet.then(prerequisitesMet => prerequisitesMet ? evaluatePrerequisite(prerequisite) : false) :
21
- prerequisitesMet ? evaluatePrerequisite(prerequisite) : false;
22
- }, true);
23
- };
24
- }