@splitsoftware/splitio-commons 2.3.0 → 2.3.1-rc.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.
Files changed (157) hide show
  1. package/CHANGES.txt +4 -0
  2. package/README.md +1 -0
  3. package/cjs/evaluator/Engine.js +40 -61
  4. package/cjs/evaluator/combiners/and.js +2 -6
  5. package/cjs/evaluator/combiners/ifelseif.js +6 -6
  6. package/cjs/evaluator/condition/index.js +6 -5
  7. package/cjs/evaluator/index.js +11 -11
  8. package/cjs/evaluator/matchers/index.js +3 -1
  9. package/cjs/evaluator/matchers/matcherTypes.js +1 -0
  10. package/cjs/evaluator/matchers/prerequisites.js +22 -0
  11. package/cjs/evaluator/matchers/rbsegment.js +56 -0
  12. package/cjs/evaluator/matchersTransform/index.js +4 -0
  13. package/cjs/evaluator/parser/index.js +2 -2
  14. package/cjs/evaluator/value/sanitize.js +1 -0
  15. package/cjs/logger/constants.js +5 -3
  16. package/cjs/logger/messages/debug.js +4 -2
  17. package/cjs/logger/messages/warn.js +1 -1
  18. package/cjs/sdkManager/index.js +2 -1
  19. package/cjs/services/splitApi.js +3 -4
  20. package/cjs/services/splitHttpClient.js +1 -1
  21. package/cjs/storages/AbstractSplitsCacheSync.js +5 -2
  22. package/cjs/storages/KeyBuilder.js +9 -0
  23. package/cjs/storages/KeyBuilderCS.js +3 -0
  24. package/cjs/storages/KeyBuilderSS.js +3 -0
  25. package/cjs/storages/inLocalStorage/RBSegmentsCacheInLocal.js +117 -0
  26. package/cjs/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
  27. package/cjs/storages/inLocalStorage/index.js +5 -1
  28. package/cjs/storages/inLocalStorage/validateCache.js +2 -1
  29. package/cjs/storages/inMemory/InMemoryStorage.js +3 -0
  30. package/cjs/storages/inMemory/InMemoryStorageCS.js +4 -0
  31. package/cjs/storages/inMemory/RBSegmentsCacheInMemory.js +61 -0
  32. package/cjs/storages/inMemory/SplitsCacheInMemory.js +1 -0
  33. package/cjs/storages/inRedis/RBSegmentsCacheInRedis.js +64 -0
  34. package/cjs/storages/inRedis/index.js +2 -0
  35. package/cjs/storages/pluggable/RBSegmentsCachePluggable.js +64 -0
  36. package/cjs/storages/pluggable/index.js +2 -0
  37. package/cjs/sync/polling/fetchers/splitChangesFetcher.js +54 -4
  38. package/cjs/sync/polling/pollingManagerCS.js +7 -7
  39. package/cjs/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  40. package/cjs/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  41. package/cjs/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  42. package/cjs/sync/polling/updaters/splitChangesUpdater.js +59 -33
  43. package/cjs/sync/streaming/SSEHandler/index.js +1 -0
  44. package/cjs/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +106 -77
  45. package/cjs/sync/streaming/constants.js +2 -1
  46. package/cjs/sync/streaming/pushManager.js +3 -16
  47. package/cjs/sync/syncManagerOnline.js +2 -2
  48. package/cjs/utils/constants/index.js +6 -2
  49. package/cjs/utils/labels/index.js +2 -1
  50. package/esm/evaluator/Engine.js +40 -62
  51. package/esm/evaluator/combiners/and.js +2 -6
  52. package/esm/evaluator/combiners/ifelseif.js +7 -7
  53. package/esm/evaluator/condition/index.js +6 -5
  54. package/esm/evaluator/index.js +12 -12
  55. package/esm/evaluator/matchers/index.js +3 -1
  56. package/esm/evaluator/matchers/matcherTypes.js +1 -0
  57. package/esm/evaluator/matchers/prerequisites.js +18 -0
  58. package/esm/evaluator/matchers/rbsegment.js +52 -0
  59. package/esm/evaluator/matchersTransform/index.js +4 -0
  60. package/esm/evaluator/parser/index.js +2 -2
  61. package/esm/evaluator/value/sanitize.js +1 -0
  62. package/esm/logger/constants.js +2 -0
  63. package/esm/logger/messages/debug.js +4 -2
  64. package/esm/logger/messages/warn.js +1 -1
  65. package/esm/sdkManager/index.js +2 -1
  66. package/esm/services/splitApi.js +3 -4
  67. package/esm/services/splitHttpClient.js +1 -1
  68. package/esm/storages/AbstractSplitsCacheSync.js +5 -2
  69. package/esm/storages/KeyBuilder.js +9 -0
  70. package/esm/storages/KeyBuilderCS.js +3 -0
  71. package/esm/storages/KeyBuilderSS.js +3 -0
  72. package/esm/storages/inLocalStorage/RBSegmentsCacheInLocal.js +114 -0
  73. package/esm/storages/inLocalStorage/SplitsCacheInLocal.js +9 -14
  74. package/esm/storages/inLocalStorage/index.js +5 -1
  75. package/esm/storages/inLocalStorage/validateCache.js +2 -1
  76. package/esm/storages/inMemory/InMemoryStorage.js +3 -0
  77. package/esm/storages/inMemory/InMemoryStorageCS.js +4 -0
  78. package/esm/storages/inMemory/RBSegmentsCacheInMemory.js +58 -0
  79. package/esm/storages/inMemory/SplitsCacheInMemory.js +1 -0
  80. package/esm/storages/inRedis/RBSegmentsCacheInRedis.js +61 -0
  81. package/esm/storages/inRedis/index.js +2 -0
  82. package/esm/storages/pluggable/RBSegmentsCachePluggable.js +61 -0
  83. package/esm/storages/pluggable/index.js +2 -0
  84. package/esm/sync/polling/fetchers/splitChangesFetcher.js +54 -4
  85. package/esm/sync/polling/pollingManagerCS.js +7 -7
  86. package/esm/sync/polling/syncTasks/splitsSyncTask.js +1 -1
  87. package/esm/sync/polling/updaters/mySegmentsUpdater.js +2 -2
  88. package/esm/sync/polling/updaters/segmentChangesUpdater.js +1 -1
  89. package/esm/sync/polling/updaters/splitChangesUpdater.js +59 -33
  90. package/esm/sync/streaming/SSEHandler/index.js +2 -1
  91. package/esm/sync/streaming/UpdateWorkers/SplitsUpdateWorker.js +102 -73
  92. package/esm/sync/streaming/constants.js +1 -0
  93. package/esm/sync/streaming/pushManager.js +6 -19
  94. package/esm/sync/syncManagerOnline.js +2 -2
  95. package/esm/utils/constants/index.js +5 -1
  96. package/esm/utils/labels/index.js +1 -0
  97. package/package.json +1 -1
  98. package/src/dtos/types.ts +41 -8
  99. package/src/evaluator/Engine.ts +42 -69
  100. package/src/evaluator/combiners/and.ts +5 -4
  101. package/src/evaluator/combiners/ifelseif.ts +7 -9
  102. package/src/evaluator/condition/engineUtils.ts +1 -1
  103. package/src/evaluator/condition/index.ts +12 -12
  104. package/src/evaluator/index.ts +12 -14
  105. package/src/evaluator/matchers/index.ts +3 -1
  106. package/src/evaluator/matchers/matcherTypes.ts +1 -0
  107. package/src/evaluator/matchers/prerequisites.ts +24 -0
  108. package/src/evaluator/matchers/rbsegment.ts +74 -0
  109. package/src/evaluator/matchersTransform/index.ts +3 -0
  110. package/src/evaluator/parser/index.ts +3 -3
  111. package/src/evaluator/types.ts +2 -2
  112. package/src/evaluator/value/index.ts +2 -2
  113. package/src/evaluator/value/sanitize.ts +5 -4
  114. package/src/logger/constants.ts +2 -0
  115. package/src/logger/messages/debug.ts +4 -2
  116. package/src/logger/messages/warn.ts +1 -1
  117. package/src/sdkManager/index.ts +3 -2
  118. package/src/services/splitApi.ts +3 -4
  119. package/src/services/splitHttpClient.ts +1 -1
  120. package/src/services/types.ts +1 -1
  121. package/src/storages/AbstractSplitsCacheSync.ts +6 -3
  122. package/src/storages/KeyBuilder.ts +12 -0
  123. package/src/storages/KeyBuilderCS.ts +4 -0
  124. package/src/storages/KeyBuilderSS.ts +4 -0
  125. package/src/storages/inLocalStorage/RBSegmentsCacheInLocal.ts +136 -0
  126. package/src/storages/inLocalStorage/SplitsCacheInLocal.ts +10 -14
  127. package/src/storages/inLocalStorage/index.ts +5 -1
  128. package/src/storages/inLocalStorage/validateCache.ts +3 -1
  129. package/src/storages/inMemory/InMemoryStorage.ts +3 -0
  130. package/src/storages/inMemory/InMemoryStorageCS.ts +4 -0
  131. package/src/storages/inMemory/RBSegmentsCacheInMemory.ts +68 -0
  132. package/src/storages/inMemory/SplitsCacheInMemory.ts +1 -0
  133. package/src/storages/inRedis/RBSegmentsCacheInRedis.ts +79 -0
  134. package/src/storages/inRedis/index.ts +2 -0
  135. package/src/storages/pluggable/RBSegmentsCachePluggable.ts +76 -0
  136. package/src/storages/pluggable/index.ts +2 -0
  137. package/src/storages/types.ts +33 -1
  138. package/src/sync/polling/fetchers/splitChangesFetcher.ts +65 -4
  139. package/src/sync/polling/fetchers/types.ts +1 -0
  140. package/src/sync/polling/pollingManagerCS.ts +7 -7
  141. package/src/sync/polling/syncTasks/splitsSyncTask.ts +1 -1
  142. package/src/sync/polling/types.ts +2 -2
  143. package/src/sync/polling/updaters/mySegmentsUpdater.ts +2 -2
  144. package/src/sync/polling/updaters/segmentChangesUpdater.ts +1 -1
  145. package/src/sync/polling/updaters/splitChangesUpdater.ts +70 -43
  146. package/src/sync/streaming/SSEHandler/index.ts +2 -1
  147. package/src/sync/streaming/SSEHandler/types.ts +2 -2
  148. package/src/sync/streaming/UpdateWorkers/SplitsUpdateWorker.ts +98 -68
  149. package/src/sync/streaming/constants.ts +1 -0
  150. package/src/sync/streaming/parseUtils.ts +2 -2
  151. package/src/sync/streaming/pushManager.ts +6 -18
  152. package/src/sync/streaming/types.ts +3 -2
  153. package/src/sync/syncManagerOnline.ts +2 -2
  154. package/src/utils/constants/index.ts +6 -1
  155. package/src/utils/labels/index.ts +1 -0
  156. package/src/utils/lang/index.ts +1 -1
  157. package/types/splitio.d.ts +5 -1
@@ -1,12 +1,13 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.splitChangesUpdaterFactory = exports.computeSplitsMutation = exports.parseSegments = void 0;
3
+ exports.splitChangesUpdaterFactory = exports.computeMutation = exports.parseSegments = void 0;
4
4
  var timeout_1 = require("../../../utils/promise/timeout");
5
5
  var constants_1 = require("../../../readiness/constants");
6
6
  var constants_2 = require("../../../logger/constants");
7
7
  var lang_1 = require("../../../utils/lang");
8
8
  var constants_3 = require("../../../utils/constants");
9
9
  var sets_1 = require("../../../utils/lang/sets");
10
+ var constants_4 = require("../../streaming/constants");
10
11
  // Checks that all registered segments have been fetched (changeNumber !== -1 for every segment).
11
12
  // Returns a promise that could be rejected.
12
13
  // @TODO review together with Segments and MySegments storage APIs
@@ -18,16 +19,25 @@ function checkAllSegmentsExist(segments) {
18
19
  });
19
20
  }
20
21
  /**
21
- * Collect segments from a raw split definition.
22
+ * Collect segments from a raw FF or RBS definition.
22
23
  * Exported for testing purposes.
23
24
  */
24
- function parseSegments(_a) {
25
- var conditions = _a.conditions;
25
+ function parseSegments(ruleEntity, matcherType) {
26
+ if (matcherType === void 0) { matcherType = constants_3.IN_SEGMENT; }
27
+ var _a = ruleEntity, _b = _a.conditions, conditions = _b === void 0 ? [] : _b, excluded = _a.excluded;
26
28
  var segments = new Set();
29
+ if (excluded && excluded.segments) {
30
+ excluded.segments.forEach(function (_a) {
31
+ var type = _a.type, name = _a.name;
32
+ if ((type === constants_3.STANDARD_SEGMENT && matcherType === constants_3.IN_SEGMENT) || (type === constants_3.RULE_BASED_SEGMENT && matcherType === constants_3.IN_RULE_BASED_SEGMENT)) {
33
+ segments.add(name);
34
+ }
35
+ });
36
+ }
27
37
  for (var i = 0; i < conditions.length; i++) {
28
38
  var matchers = conditions[i].matcherGroup.matchers;
29
39
  matchers.forEach(function (matcher) {
30
- if (matcher.matcherType === constants_3.IN_SEGMENT)
40
+ if (matcher.matcherType === matcherType)
31
41
  segments.add(matcher.userDefinedSegmentMatcherData.segmentName);
32
42
  });
33
43
  }
@@ -58,24 +68,21 @@ function matchFilters(featureFlag, filters) {
58
68
  * i.e., an object with added splits, removed splits and used segments.
59
69
  * Exported for testing purposes.
60
70
  */
61
- function computeSplitsMutation(entries, filters) {
62
- var segments = new Set();
63
- var computed = entries.reduce(function (accum, split) {
64
- if (split.status === 'ACTIVE' && matchFilters(split, filters)) {
65
- accum.added.push(split);
66
- parseSegments(split).forEach(function (segmentName) {
71
+ function computeMutation(rules, segments, filters) {
72
+ return rules.reduce(function (accum, ruleEntity) {
73
+ if (ruleEntity.status === 'ACTIVE' && (!filters || matchFilters(ruleEntity, filters))) {
74
+ accum.added.push(ruleEntity);
75
+ parseSegments(ruleEntity).forEach(function (segmentName) {
67
76
  segments.add(segmentName);
68
77
  });
69
78
  }
70
79
  else {
71
- accum.removed.push(split);
80
+ accum.removed.push(ruleEntity);
72
81
  }
73
82
  return accum;
74
- }, { added: [], removed: [], segments: [] });
75
- computed.segments = (0, sets_1.setToArray)(segments);
76
- return computed;
83
+ }, { added: [], removed: [] });
77
84
  }
78
- exports.computeSplitsMutation = computeSplitsMutation;
85
+ exports.computeMutation = computeMutation;
79
86
  /**
80
87
  * factory of SplitChanges updater, a task that:
81
88
  * - fetches split changes using `splitChangesFetcher`
@@ -93,7 +100,7 @@ exports.computeSplitsMutation = computeSplitsMutation;
93
100
  function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFiltersValidation, splitsEventEmitter, requestTimeoutBeforeReady, retriesOnFailureBeforeReady, isClientSide) {
94
101
  if (requestTimeoutBeforeReady === void 0) { requestTimeoutBeforeReady = 0; }
95
102
  if (retriesOnFailureBeforeReady === void 0) { retriesOnFailureBeforeReady = 0; }
96
- var splits = storage.splits, segments = storage.segments;
103
+ var splits = storage.splits, rbSegments = storage.rbSegments, segments = storage.segments;
97
104
  var startingUp = true;
98
105
  /** timeout decorator for `splitChangesFetcher` promise */
99
106
  function _promiseDecorator(promise) {
@@ -108,29 +115,48 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
108
115
  * @param noCache - true to revalidate data to fetch
109
116
  * @param till - query param to bypass CDN requests
110
117
  */
111
- return function splitChangesUpdater(noCache, till, splitUpdateNotification) {
118
+ return function splitChangesUpdater(noCache, till, instantUpdate) {
112
119
  /**
113
120
  * @param since - current changeNumber at splitsCache
114
121
  * @param retry - current number of retry attempts
115
122
  */
116
- function _splitChangesUpdater(since, retry) {
123
+ function _splitChangesUpdater(sinces, retry) {
117
124
  if (retry === void 0) { retry = 0; }
118
- log.debug(constants_2.SYNC_SPLITS_FETCH, [since]);
119
- return Promise.resolve(splitUpdateNotification ?
120
- { splits: [splitUpdateNotification.payload], till: splitUpdateNotification.changeNumber } :
121
- splitChangesFetcher(since, noCache, till, _promiseDecorator))
125
+ var since = sinces[0], rbSince = sinces[1];
126
+ log.debug(constants_2.SYNC_SPLITS_FETCH, sinces);
127
+ return Promise.resolve(instantUpdate ?
128
+ instantUpdate.type === constants_4.SPLIT_UPDATE ?
129
+ // IFFU edge case: a change to a flag that adds an IN_RULE_BASED_SEGMENT matcher that is not present yet
130
+ Promise.resolve(rbSegments.contains(parseSegments(instantUpdate.payload, constants_3.IN_RULE_BASED_SEGMENT))).then(function (contains) {
131
+ return contains ?
132
+ { ff: { d: [instantUpdate.payload], t: instantUpdate.changeNumber } } :
133
+ splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator);
134
+ }) :
135
+ { rbs: { d: [instantUpdate.payload], t: instantUpdate.changeNumber } } :
136
+ splitChangesFetcher(since, noCache, till, rbSince, _promiseDecorator))
122
137
  .then(function (splitChanges) {
123
138
  startingUp = false;
124
- var mutation = computeSplitsMutation(splitChanges.splits, splitFiltersValidation);
125
- log.debug(constants_2.SYNC_SPLITS_UPDATE, [mutation.added.length, mutation.removed.length, mutation.segments.length]);
126
- return Promise.all([
127
- splits.update(mutation.added, mutation.removed, splitChanges.till),
128
- segments.registerSegments(mutation.segments)
139
+ var usedSegments = new Set();
140
+ var ffUpdate = false;
141
+ if (splitChanges.ff) {
142
+ var _a = computeMutation(splitChanges.ff.d, usedSegments, splitFiltersValidation), added = _a.added, removed = _a.removed;
143
+ log.debug(constants_2.SYNC_SPLITS_UPDATE, [added.length, removed.length]);
144
+ ffUpdate = splits.update(added, removed, splitChanges.ff.t);
145
+ }
146
+ var rbsUpdate = false;
147
+ if (splitChanges.rbs) {
148
+ var _b = computeMutation(splitChanges.rbs.d, usedSegments), added = _b.added, removed = _b.removed;
149
+ log.debug(constants_2.SYNC_RBS_UPDATE, [added.length, removed.length]);
150
+ rbsUpdate = rbSegments.update(added, removed, splitChanges.rbs.t);
151
+ }
152
+ return Promise.all([ffUpdate, rbsUpdate,
153
+ // @TODO if at least 1 segment fetch fails due to 404 and other segments are updated in the storage, SDK_UPDATE is not emitted
154
+ segments.registerSegments((0, sets_1.setToArray)(usedSegments))
129
155
  ]).then(function (_a) {
130
- var isThereUpdate = _a[0];
156
+ var ffChanged = _a[0], rbsChanged = _a[1];
131
157
  if (splitsEventEmitter) {
132
158
  // To emit SDK_SPLITS_ARRIVED for server-side SDK, we must check that all registered segments have been fetched
133
- return Promise.resolve(!splitsEventEmitter.splitsArrived || (since !== splitChanges.till && isThereUpdate && (isClientSide || checkAllSegmentsExist(segments))))
159
+ return Promise.resolve(!splitsEventEmitter.splitsArrived || ((ffChanged || rbsChanged) && (isClientSide || checkAllSegmentsExist(segments))))
134
160
  .catch(function () { return false; } /** noop. just to handle a possible `checkAllSegmentsExist` rejection, before emitting SDK event */)
135
161
  .then(function (emitSplitsArrivedEvent) {
136
162
  // emit SDK events
@@ -147,7 +173,7 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
147
173
  if (startingUp && retriesOnFailureBeforeReady > retry) {
148
174
  retry += 1;
149
175
  log.info(constants_2.SYNC_SPLITS_FETCH_RETRY, [retry, error]);
150
- return _splitChangesUpdater(since, retry);
176
+ return _splitChangesUpdater(sinces, retry);
151
177
  }
152
178
  else {
153
179
  startingUp = false;
@@ -155,8 +181,8 @@ function splitChangesUpdaterFactory(log, splitChangesFetcher, storage, splitFilt
155
181
  return false;
156
182
  });
157
183
  }
158
- var sincePromise = Promise.resolve(splits.getChangeNumber()); // `getChangeNumber` never rejects or throws error
159
- return sincePromise.then(_splitChangesUpdater);
184
+ // `getChangeNumber` never rejects or throws error
185
+ return Promise.all([splits.getChangeNumber(), rbSegments.getChangeNumber()]).then(_splitChangesUpdater);
160
186
  };
161
187
  }
162
188
  exports.splitChangesUpdaterFactory = splitChangesUpdaterFactory;
@@ -78,6 +78,7 @@ function SSEHandlerFactory(log, pushEmitter, telemetryTracker) {
78
78
  case constants_1.MEMBERSHIPS_MS_UPDATE:
79
79
  case constants_1.MEMBERSHIPS_LS_UPDATE:
80
80
  case constants_1.SPLIT_KILL:
81
+ case constants_1.RB_SEGMENT_UPDATE:
81
82
  pushEmitter.emit(parsedData.type, parsedData);
82
83
  break;
83
84
  /* occupancy & control events, handled by NotificationManagerKeeper */
@@ -1,106 +1,135 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SplitsUpdateWorker = void 0;
4
- var constants_1 = require("../../../readiness/constants");
4
+ var constants_1 = require("../../../logger/constants");
5
+ var constants_2 = require("../../../readiness/constants");
5
6
  var Backoff_1 = require("../../../utils/Backoff");
6
- var constants_2 = require("../../../utils/constants");
7
- var constants_3 = require("./constants");
7
+ var constants_3 = require("../../../utils/constants");
8
+ var constants_4 = require("../constants");
9
+ var parseUtils_1 = require("../parseUtils");
10
+ var constants_5 = require("./constants");
8
11
  /**
9
12
  * SplitsUpdateWorker factory
10
13
  */
11
- function SplitsUpdateWorker(log, splitsCache, splitsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) {
12
- var maxChangeNumber = 0;
13
- var handleNewEvent = false;
14
- var isHandlingEvent;
15
- var cdnBypass;
16
- var payload;
17
- var backoff = new Backoff_1.Backoff(__handleSplitUpdateCall, constants_3.FETCH_BACKOFF_BASE, constants_3.FETCH_BACKOFF_MAX_WAIT);
18
- function __handleSplitUpdateCall() {
19
- isHandlingEvent = true;
20
- if (maxChangeNumber > splitsCache.getChangeNumber()) {
21
- handleNewEvent = false;
22
- var splitUpdateNotification_1 = payload ? { payload: payload, changeNumber: maxChangeNumber } : undefined;
23
- // fetch splits revalidating data if cached
24
- splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, splitUpdateNotification_1).then(function () {
25
- if (!isHandlingEvent)
26
- return; // halt if `stop` has been called
27
- if (handleNewEvent) {
28
- __handleSplitUpdateCall();
29
- }
30
- else {
31
- if (splitUpdateNotification_1)
32
- telemetryTracker.trackUpdatesFromSSE(constants_2.SPLITS);
33
- // fetch new registered segments for server-side API. Not retrying on error
34
- if (segmentsSyncTask)
35
- segmentsSyncTask.execute(true);
36
- var attempts = backoff.attempts + 1;
37
- if (maxChangeNumber <= splitsCache.getChangeNumber()) {
38
- log.debug("Refresh completed" + (cdnBypass ? ' bypassing the CDN' : '') + " in " + attempts + " attempts.");
39
- isHandlingEvent = false;
40
- return;
41
- }
42
- if (attempts < constants_3.FETCH_BACKOFF_MAX_RETRIES) {
43
- backoff.scheduleCall();
44
- return;
45
- }
46
- if (cdnBypass) {
47
- log.debug("No changes fetched after " + attempts + " attempts with CDN bypassed.");
48
- isHandlingEvent = false;
14
+ function SplitsUpdateWorker(log, storage, splitsSyncTask, splitsEventEmitter, telemetryTracker, segmentsSyncTask) {
15
+ var ff = SplitsUpdateWorker(storage.splits);
16
+ var rbs = SplitsUpdateWorker(storage.rbSegments);
17
+ function SplitsUpdateWorker(cache) {
18
+ var maxChangeNumber = -1;
19
+ var handleNewEvent = false;
20
+ var isHandlingEvent;
21
+ var cdnBypass;
22
+ var instantUpdate;
23
+ var backoff = new Backoff_1.Backoff(__handleSplitUpdateCall, constants_5.FETCH_BACKOFF_BASE, constants_5.FETCH_BACKOFF_MAX_WAIT);
24
+ function __handleSplitUpdateCall() {
25
+ isHandlingEvent = true;
26
+ if (maxChangeNumber > cache.getChangeNumber()) {
27
+ handleNewEvent = false;
28
+ // fetch splits revalidating data if cached
29
+ splitsSyncTask.execute(true, cdnBypass ? maxChangeNumber : undefined, instantUpdate).then(function () {
30
+ if (!isHandlingEvent)
31
+ return; // halt if `stop` has been called
32
+ if (handleNewEvent) {
33
+ __handleSplitUpdateCall();
49
34
  }
50
35
  else {
51
- backoff.reset();
52
- cdnBypass = true;
53
- __handleSplitUpdateCall();
36
+ if (instantUpdate)
37
+ telemetryTracker.trackUpdatesFromSSE(constants_3.SPLITS);
38
+ // fetch new registered segments for server-side API. Not retrying on error
39
+ if (segmentsSyncTask)
40
+ segmentsSyncTask.execute(true);
41
+ var attempts = backoff.attempts + 1;
42
+ if (ff.isSync() && rbs.isSync()) {
43
+ log.debug("Refresh completed" + (cdnBypass ? ' bypassing the CDN' : '') + " in " + attempts + " attempts.");
44
+ isHandlingEvent = false;
45
+ return;
46
+ }
47
+ if (attempts < constants_5.FETCH_BACKOFF_MAX_RETRIES) {
48
+ backoff.scheduleCall();
49
+ return;
50
+ }
51
+ if (cdnBypass) {
52
+ log.debug("No changes fetched after " + attempts + " attempts with CDN bypassed.");
53
+ isHandlingEvent = false;
54
+ }
55
+ else {
56
+ backoff.reset();
57
+ cdnBypass = true;
58
+ __handleSplitUpdateCall();
59
+ }
54
60
  }
55
- }
56
- });
57
- }
58
- else {
59
- isHandlingEvent = false;
60
- }
61
- }
62
- /**
63
- * Invoked by NotificationProcessor on SPLIT_UPDATE event
64
- *
65
- * @param changeNumber - change number of the SPLIT_UPDATE notification
66
- */
67
- function put(_a, _payload) {
68
- var changeNumber = _a.changeNumber, pcn = _a.pcn;
69
- var currentChangeNumber = splitsCache.getChangeNumber();
70
- if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
71
- return;
72
- maxChangeNumber = changeNumber;
73
- handleNewEvent = true;
74
- cdnBypass = false;
75
- payload = undefined;
76
- if (_payload && currentChangeNumber === pcn) {
77
- payload = _payload;
61
+ });
62
+ }
63
+ else {
64
+ isHandlingEvent = false;
65
+ }
78
66
  }
79
- if (backoff.timeoutID || !isHandlingEvent)
80
- __handleSplitUpdateCall();
81
- backoff.reset();
67
+ return {
68
+ /**
69
+ * Invoked by NotificationProcessor on SPLIT_UPDATE or RB_SEGMENT_UPDATE event
70
+ *
71
+ * @param changeNumber - change number of the notification
72
+ */
73
+ put: function (_a, payload) {
74
+ var changeNumber = _a.changeNumber, pcn = _a.pcn, type = _a.type;
75
+ var currentChangeNumber = cache.getChangeNumber();
76
+ if (changeNumber <= currentChangeNumber || changeNumber <= maxChangeNumber)
77
+ return;
78
+ maxChangeNumber = changeNumber;
79
+ handleNewEvent = true;
80
+ cdnBypass = false;
81
+ instantUpdate = undefined;
82
+ if (payload && currentChangeNumber === pcn) {
83
+ instantUpdate = { payload: payload, changeNumber: changeNumber, type: type };
84
+ }
85
+ if (backoff.timeoutID || !isHandlingEvent)
86
+ __handleSplitUpdateCall();
87
+ backoff.reset();
88
+ },
89
+ stop: function () {
90
+ isHandlingEvent = false;
91
+ backoff.reset();
92
+ },
93
+ isSync: function () {
94
+ return maxChangeNumber <= cache.getChangeNumber();
95
+ }
96
+ };
82
97
  }
83
98
  return {
84
- put: put,
99
+ put: function (parsedData) {
100
+ if (parsedData.d && parsedData.c !== undefined) {
101
+ try {
102
+ var payload = (0, parseUtils_1.parseFFUpdatePayload)(parsedData.c, parsedData.d);
103
+ if (payload) {
104
+ (parsedData.type === constants_4.RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData, payload);
105
+ return;
106
+ }
107
+ }
108
+ catch (e) {
109
+ log.warn(constants_1.STREAMING_PARSING_SPLIT_UPDATE, [parsedData.type, e]);
110
+ }
111
+ }
112
+ (parsedData.type === constants_4.RB_SEGMENT_UPDATE ? rbs : ff).put(parsedData);
113
+ },
85
114
  /**
86
115
  * Invoked by NotificationProcessor on SPLIT_KILL event
87
116
  *
88
- * @param changeNumber - change number of the SPLIT_UPDATE notification
117
+ * @param changeNumber - change number of the notification
89
118
  * @param splitName - name of split to kill
90
119
  * @param defaultTreatment - default treatment value
91
120
  */
92
121
  killSplit: function (_a) {
93
122
  var changeNumber = _a.changeNumber, splitName = _a.splitName, defaultTreatment = _a.defaultTreatment;
94
- if (splitsCache.killLocally(splitName, defaultTreatment, changeNumber)) {
123
+ if (storage.splits.killLocally(splitName, defaultTreatment, changeNumber)) {
95
124
  // trigger an SDK_UPDATE if Split was killed locally
96
- splitsEventEmitter.emit(constants_1.SDK_SPLITS_ARRIVED, true);
125
+ splitsEventEmitter.emit(constants_2.SDK_SPLITS_ARRIVED, true);
97
126
  }
98
127
  // queues the SplitChanges fetch (only if changeNumber is newer)
99
- put({ changeNumber: changeNumber });
128
+ ff.put({ changeNumber: changeNumber });
100
129
  },
101
130
  stop: function () {
102
- isHandlingEvent = false;
103
- backoff.reset();
131
+ ff.stop();
132
+ rbs.stop();
104
133
  }
105
134
  };
106
135
  }
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MEMBERSHIPS_LS_UPDATE = exports.MEMBERSHIPS_MS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.PUSH_NONRETRYABLE_ERROR = exports.SECONDS_BEFORE_EXPIRATION = void 0;
3
+ exports.ControlType = exports.OCCUPANCY = exports.CONTROL = exports.RB_SEGMENT_UPDATE = exports.SPLIT_UPDATE = exports.SPLIT_KILL = exports.SEGMENT_UPDATE = exports.MEMBERSHIPS_LS_UPDATE = exports.MEMBERSHIPS_MS_UPDATE = exports.PUSH_SUBSYSTEM_DOWN = exports.PUSH_SUBSYSTEM_UP = exports.PUSH_RETRYABLE_ERROR = exports.PUSH_NONRETRYABLE_ERROR = exports.SECONDS_BEFORE_EXPIRATION = void 0;
4
4
  // time for refresh token
5
5
  exports.SECONDS_BEFORE_EXPIRATION = 600;
6
6
  // Internal SDK events, subscribed by SyncManager and PushManager
@@ -30,6 +30,7 @@ exports.MEMBERSHIPS_LS_UPDATE = 'MEMBERSHIPS_LS_UPDATE';
30
30
  exports.SEGMENT_UPDATE = 'SEGMENT_UPDATE';
31
31
  exports.SPLIT_KILL = 'SPLIT_KILL';
32
32
  exports.SPLIT_UPDATE = 'SPLIT_UPDATE';
33
+ exports.RB_SEGMENT_UPDATE = 'RB_SEGMENT_UPDATE';
33
34
  // Control-type push notifications, handled by NotificationKeeper
34
35
  exports.CONTROL = 'CONTROL';
35
36
  exports.OCCUPANCY = 'OCCUPANCY';
@@ -46,7 +46,7 @@ function pushManagerFactory(params, pollingManager) {
46
46
  // MySegmentsUpdateWorker (client-side) are initiated in `add` method
47
47
  var segmentsUpdateWorker = userKey ? undefined : (0, SegmentsUpdateWorker_1.SegmentsUpdateWorker)(log, pollingManager.segmentsSyncTask, storage.segments);
48
48
  // For server-side we pass the segmentsSyncTask, used by SplitsUpdateWorker to fetch new segments
49
- var splitsUpdateWorker = (0, SplitsUpdateWorker_1.SplitsUpdateWorker)(log, storage.splits, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
49
+ var splitsUpdateWorker = (0, SplitsUpdateWorker_1.SplitsUpdateWorker)(log, storage, pollingManager.splitsSyncTask, readiness.splits, telemetryTracker, userKey ? undefined : pollingManager.segmentsSyncTask);
50
50
  // [Only for client-side] map of hashes to user keys, to dispatch membership update events to the corresponding MySegmentsUpdateWorker
51
51
  var userKeyHashes = {};
52
52
  // [Only for client-side] map of user keys to their corresponding hash64 and MySegmentsUpdateWorkers.
@@ -182,21 +182,8 @@ function pushManagerFactory(params, pollingManager) {
182
182
  });
183
183
  /** Functions related to synchronization (Queues and Workers in the spec) */
184
184
  pushEmitter.on(constants_1.SPLIT_KILL, splitsUpdateWorker.killSplit);
185
- pushEmitter.on(constants_1.SPLIT_UPDATE, function (parsedData) {
186
- if (parsedData.d && parsedData.c !== undefined) {
187
- try {
188
- var payload = (0, parseUtils_1.parseFFUpdatePayload)(parsedData.c, parsedData.d);
189
- if (payload) {
190
- splitsUpdateWorker.put(parsedData, payload);
191
- return;
192
- }
193
- }
194
- catch (e) {
195
- log.warn(constants_2.STREAMING_PARSING_SPLIT_UPDATE, [e]);
196
- }
197
- }
198
- splitsUpdateWorker.put(parsedData);
199
- });
185
+ pushEmitter.on(constants_1.SPLIT_UPDATE, splitsUpdateWorker.put);
186
+ pushEmitter.on(constants_1.RB_SEGMENT_UPDATE, splitsUpdateWorker.put);
200
187
  function handleMySegmentsUpdate(parsedData) {
201
188
  switch (parsedData.u) {
202
189
  case types_1.UpdateStrategy.BoundedFetchRequest: {
@@ -130,7 +130,7 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
130
130
  if (pushManager) {
131
131
  if (pollingManager.isRunning()) {
132
132
  // if doing polling, we must start the periodic fetch of data
133
- if (storage.splits.usesSegments())
133
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments())
134
134
  mySegmentsSyncTask.start();
135
135
  }
136
136
  else {
@@ -140,7 +140,7 @@ function syncManagerOnlineFactory(pollingManagerFactory, pushManagerFactory) {
140
140
  }
141
141
  }
142
142
  else {
143
- if (storage.splits.usesSegments())
143
+ if (storage.splits.usesSegments() || storage.rbSegments.usesSegments())
144
144
  mySegmentsSyncTask.start();
145
145
  }
146
146
  }
@@ -1,7 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.MEMBERSHIPS = exports.SEGMENT = exports.TOKEN = exports.TELEMETRY = exports.EVENTS = exports.IMPRESSIONS_COUNT = exports.IMPRESSIONS = exports.SPLITS = exports.NONE_ENUM = exports.DEBUG_ENUM = exports.OPTIMIZED_ENUM = exports.CONSUMER_PARTIAL_ENUM = exports.CONSUMER_ENUM = exports.STANDALONE_ENUM = exports.DEDUPED = exports.DROPPED = exports.QUEUED = exports.NAMES_FN_LABEL = exports.SPLITS_FN_LABEL = exports.SPLIT_FN_LABEL = exports.TRACK_FN_LABEL = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SETS = exports.GET_TREATMENTS_WITH_CONFIG_BY_FLAG_SET = exports.GET_TREATMENTS_BY_FLAG_SETS = exports.GET_TREATMENTS_BY_FLAG_SET = exports.GET_TREATMENTS_WITH_CONFIG = exports.GET_TREATMENT_WITH_CONFIG = exports.GET_TREATMENTS = exports.GET_TREATMENT = exports.CONSENT_UNKNOWN = exports.CONSENT_DECLINED = exports.CONSENT_GRANTED = exports.STORAGE_PLUGGABLE = exports.STORAGE_REDIS = exports.STORAGE_LOCALSTORAGE = exports.STORAGE_MEMORY = exports.CONSUMER_PARTIAL_MODE = exports.CONSUMER_MODE = exports.PRODUCER_MODE = exports.STANDALONE_MODE = exports.LOCALHOST_MODE = exports.NONE = exports.OPTIMIZED = exports.DEBUG = exports.SPLIT_EVENT = exports.SPLIT_IMPRESSION = exports.NA = exports.UNKNOWN = exports.CONTROL_WITH_CONFIG = exports.CONTROL = void 0;
4
- exports.IN_LARGE_SEGMENT = exports.IN_SEGMENT = exports.FLAG_SPEC_VERSION = exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = exports.OCCUPANCY_SEC = exports.OCCUPANCY_PRI = exports.CONNECTION_ESTABLISHED = exports.TRACK = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSETS = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSET = exports.TREATMENTS_BY_FLAGSETS = exports.TREATMENTS_BY_FLAGSET = exports.TREATMENTS_WITH_CONFIG = exports.TREATMENT_WITH_CONFIG = exports.TREATMENTS = exports.TREATMENT = void 0;
4
+ exports.RULE_BASED_SEGMENT = exports.LARGE_SEGMENT = exports.STANDARD_SEGMENT = exports.IN_RULE_BASED_SEGMENT = exports.IN_LARGE_SEGMENT = exports.IN_SEGMENT = exports.FLAG_SPEC_VERSION = exports.PAUSED = exports.ENABLED = exports.DISABLED = exports.NON_REQUESTED = exports.REQUESTED = exports.POLLING = exports.STREAMING = exports.AUTH_REJECTION = exports.SYNC_MODE_UPDATE = exports.ABLY_ERROR = exports.TOKEN_REFRESH = exports.SSE_CONNECTION_ERROR = exports.STREAMING_STATUS = exports.OCCUPANCY_SEC = exports.OCCUPANCY_PRI = exports.CONNECTION_ESTABLISHED = exports.TRACK = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSETS = exports.TREATMENTS_WITH_CONFIG_BY_FLAGSET = exports.TREATMENTS_BY_FLAGSETS = exports.TREATMENTS_BY_FLAGSET = exports.TREATMENTS_WITH_CONFIG = exports.TREATMENT_WITH_CONFIG = exports.TREATMENTS = exports.TREATMENT = void 0;
5
5
  // Special treatments
6
6
  exports.CONTROL = 'control';
7
7
  exports.CONTROL_WITH_CONFIG = {
@@ -90,7 +90,11 @@ exports.NON_REQUESTED = 1;
90
90
  exports.DISABLED = 0;
91
91
  exports.ENABLED = 1;
92
92
  exports.PAUSED = 2;
93
- exports.FLAG_SPEC_VERSION = '1.2';
93
+ exports.FLAG_SPEC_VERSION = '1.3';
94
94
  // Matcher types
95
95
  exports.IN_SEGMENT = 'IN_SEGMENT';
96
96
  exports.IN_LARGE_SEGMENT = 'IN_LARGE_SEGMENT';
97
+ exports.IN_RULE_BASED_SEGMENT = 'IN_RULE_BASED_SEGMENT';
98
+ exports.STANDARD_SEGMENT = 'standard';
99
+ exports.LARGE_SEGMENT = 'large';
100
+ exports.RULE_BASED_SEGMENT = 'rule-based';
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
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;
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;
4
4
  exports.SPLIT_KILLED = 'killed';
5
5
  exports.NO_CONDITION_MATCH = 'default rule';
6
6
  exports.SPLIT_NOT_FOUND = 'definition not found';
@@ -9,3 +9,4 @@ 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,76 +1,54 @@
1
- import { get } from '../utils/lang';
1
+ import { get, isString } 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 { EXCEPTION, NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED } from '../utils/labels';
5
+ import { NO_CONDITION_MATCH, SPLIT_ARCHIVED, SPLIT_KILLED, PREREQUISITES_NOT_MET } from '../utils/labels';
6
6
  import { CONTROL } from '../utils/constants';
7
+ import { ENGINE_DEFAULT } from '../logger/constants';
8
+ import { prerequisitesMatcherContext } from './matchers/prerequisites';
7
9
  function evaluationResult(result, defaultTreatment) {
8
10
  return {
9
11
  treatment: get(result, 'treatment', defaultTreatment),
10
12
  label: get(result, 'label', NO_CONDITION_MATCH)
11
13
  };
12
14
  }
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); });
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);
58
35
  }
59
- else {
60
- return evaluationResult(evaluation, defaultTreatment);
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
+ };
61
47
  }
48
+ var prerequisitesMet = prerequisiteMatcher({ key: key, attributes: attributes }, splitEvaluator);
49
+ return thenable(prerequisitesMet) ?
50
+ prerequisitesMet.then(evaluate) :
51
+ evaluate(prerequisitesMet);
62
52
  }
63
- return {
64
- treatment: treatment,
65
- label: label
66
- };
67
- };
68
- Engine.prototype.isGarbage = function () {
69
- return this.baseInfo.status === 'ARCHIVED';
70
53
  };
71
- Engine.prototype.getChangeNumber = function () {
72
- return this.baseInfo.changeNumber;
73
- };
74
- return Engine;
75
- }());
76
- export { Engine };
54
+ }
@@ -8,12 +8,8 @@ export function andCombinerContext(log, matchers) {
8
8
  log.debug(ENGINE_COMBINER_AND, [hasMatchedAll]);
9
9
  return hasMatchedAll;
10
10
  }
11
- return function andCombiner() {
12
- var params = [];
13
- for (var _i = 0; _i < arguments.length; _i++) {
14
- params[_i] = arguments[_i];
15
- }
16
- var matcherResults = matchers.map(function (matcher) { return matcher.apply(void 0, params); });
11
+ return function andCombiner(key, attributes, splitEvaluator) {
12
+ var matcherResults = matchers.map(function (matcher) { return matcher(key, attributes, splitEvaluator); });
17
13
  // If any matching result is a thenable we should use Promise.all
18
14
  if (findIndex(matcherResults, thenable) !== -1) {
19
15
  return Promise.all(matcherResults).then(andResults);