@featurevisor/core 0.14.1 → 0.16.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/json-schema/README.md +5 -0
- package/json-schema/attribute.json +24 -0
- package/json-schema/feature.json +289 -0
- package/json-schema/segment.json +102 -0
- package/lib/allocator.d.ts +3 -0
- package/lib/allocator.js +40 -0
- package/lib/allocator.js.map +1 -0
- package/lib/allocator.spec.d.ts +1 -0
- package/lib/allocator.spec.js +85 -0
- package/lib/allocator.spec.js.map +1 -0
- package/lib/builder.js +58 -23
- package/lib/builder.js.map +1 -1
- package/lib/config.d.ts +2 -0
- package/lib/config.js +3 -1
- package/lib/config.js.map +1 -1
- package/lib/linter.d.ts +1 -0
- package/lib/linter.js +122 -41
- package/lib/linter.js.map +1 -1
- package/lib/tester.js +3 -8
- package/lib/tester.js.map +1 -1
- package/lib/traffic.d.ts +8 -2
- package/lib/traffic.js +99 -88
- package/lib/traffic.js.map +1 -1
- package/lib/traffic.spec.js +166 -14
- package/lib/traffic.spec.js.map +1 -1
- package/package.json +5 -5
- package/src/allocator.spec.ts +104 -0
- package/src/allocator.ts +44 -0
- package/src/builder.ts +53 -23
- package/src/config.ts +3 -0
- package/src/linter.ts +100 -16
- package/src/tester.ts +3 -8
- package/src/traffic.spec.ts +167 -16
- package/src/traffic.ts +123 -109
package/lib/traffic.js
CHANGED
|
@@ -1,111 +1,122 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.getTraffic = exports.detectIfRangesChanged = exports.getRulePercentageDiff = exports.detectIfVariationsChanged = void 0;
|
|
4
4
|
var sdk_1 = require("@featurevisor/sdk");
|
|
5
|
-
|
|
5
|
+
var allocator_1 = require("./allocator");
|
|
6
|
+
function detectIfVariationsChanged(yamlVariations, // as exists in latest YAML
|
|
7
|
+
existingFeature) {
|
|
8
|
+
if (!existingFeature) {
|
|
9
|
+
return false;
|
|
10
|
+
}
|
|
11
|
+
return (JSON.stringify(existingFeature.variations.map(function (_a) {
|
|
12
|
+
var value = _a.value, weight = _a.weight;
|
|
13
|
+
return ({
|
|
14
|
+
value: value,
|
|
15
|
+
weight: weight,
|
|
16
|
+
});
|
|
17
|
+
})) !== JSON.stringify(yamlVariations.map(function (_a) {
|
|
18
|
+
var value = _a.value, weight = _a.weight;
|
|
19
|
+
return ({ value: value, weight: weight });
|
|
20
|
+
})));
|
|
21
|
+
}
|
|
22
|
+
exports.detectIfVariationsChanged = detectIfVariationsChanged;
|
|
23
|
+
function getRulePercentageDiff(trafficPercentage, // 0 to 100k
|
|
24
|
+
existingTrafficRule) {
|
|
25
|
+
if (!existingTrafficRule) {
|
|
26
|
+
return 0;
|
|
27
|
+
}
|
|
28
|
+
var existingPercentage = existingTrafficRule.percentage;
|
|
29
|
+
return trafficPercentage - existingPercentage;
|
|
30
|
+
}
|
|
31
|
+
exports.getRulePercentageDiff = getRulePercentageDiff;
|
|
32
|
+
function detectIfRangesChanged(availableRanges, // as exists in latest YAML
|
|
33
|
+
existingFeature) {
|
|
34
|
+
if (!existingFeature) {
|
|
35
|
+
return false;
|
|
36
|
+
}
|
|
37
|
+
if (!existingFeature.ranges) {
|
|
38
|
+
return false;
|
|
39
|
+
}
|
|
40
|
+
return JSON.stringify(existingFeature.ranges) !== JSON.stringify(availableRanges);
|
|
41
|
+
}
|
|
42
|
+
exports.detectIfRangesChanged = detectIfRangesChanged;
|
|
43
|
+
function getTraffic(
|
|
6
44
|
// from current YAML
|
|
7
45
|
variations, parsedRules,
|
|
8
46
|
// from previous release
|
|
9
|
-
existingFeature
|
|
47
|
+
existingFeature,
|
|
48
|
+
// ranges from group slots
|
|
49
|
+
ranges) {
|
|
10
50
|
var result = [];
|
|
11
|
-
|
|
12
|
-
|
|
51
|
+
// @TODO: may be pass from builder directly?
|
|
52
|
+
var availableRanges = ranges && ranges.length > 0 ? ranges : [{ start: 0, end: sdk_1.MAX_BUCKETED_NUMBER }];
|
|
53
|
+
parsedRules.forEach(function (parsedRule) {
|
|
54
|
+
var rulePercentage = parsedRule.percentage; // 0 - 100
|
|
13
55
|
var traffic = {
|
|
14
|
-
key:
|
|
15
|
-
segments: typeof
|
|
16
|
-
? JSON.stringify(
|
|
17
|
-
:
|
|
18
|
-
percentage:
|
|
56
|
+
key: parsedRule.key,
|
|
57
|
+
segments: typeof parsedRule.segments !== "string"
|
|
58
|
+
? JSON.stringify(parsedRule.segments)
|
|
59
|
+
: parsedRule.segments,
|
|
60
|
+
percentage: rulePercentage * (sdk_1.MAX_BUCKETED_NUMBER / 100),
|
|
19
61
|
allocation: [],
|
|
20
62
|
};
|
|
21
|
-
|
|
22
|
-
|
|
63
|
+
// overrides
|
|
64
|
+
if (parsedRule.variables) {
|
|
65
|
+
traffic.variables = parsedRule.variables;
|
|
23
66
|
}
|
|
24
|
-
if (
|
|
25
|
-
traffic.variation =
|
|
67
|
+
if (parsedRule.variation) {
|
|
68
|
+
traffic.variation = parsedRule.variation;
|
|
26
69
|
}
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
//
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
var
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
variation: variation,
|
|
58
|
-
percentage: percentage,
|
|
59
|
-
};
|
|
60
|
-
});
|
|
61
|
-
}
|
|
70
|
+
// detect changes
|
|
71
|
+
var variationsChanged = detectIfVariationsChanged(variations, existingFeature);
|
|
72
|
+
var existingTrafficRule = existingFeature === null || existingFeature === void 0 ? void 0 : existingFeature.traffic.find(function (t) { return t.key === parsedRule.key; });
|
|
73
|
+
var rulePercentageDiff = getRulePercentageDiff(traffic.percentage, existingTrafficRule);
|
|
74
|
+
var rangesChanged = detectIfRangesChanged(availableRanges, existingFeature);
|
|
75
|
+
var needsRebucketing = !existingTrafficRule || // new rule
|
|
76
|
+
variationsChanged || // variations changed
|
|
77
|
+
rulePercentageDiff <= 0 || // percentage decreased
|
|
78
|
+
rangesChanged; // belongs to a group, and group ranges changed
|
|
79
|
+
var updatedAvailableRanges = JSON.parse(JSON.stringify(availableRanges));
|
|
80
|
+
var lastEnd = 0;
|
|
81
|
+
if (existingTrafficRule && !needsRebucketing) {
|
|
82
|
+
// increase: build on top of existing allocations
|
|
83
|
+
var existingSum_1 = 0;
|
|
84
|
+
traffic.allocation = existingTrafficRule.allocation.map(function (_a) {
|
|
85
|
+
var variation = _a.variation, percentage = _a.percentage, // @TODO: remove it in next breaking semver
|
|
86
|
+
range = _a.range;
|
|
87
|
+
var result = {
|
|
88
|
+
variation: variation,
|
|
89
|
+
percentage: percentage,
|
|
90
|
+
range: range || {
|
|
91
|
+
start: lastEnd,
|
|
92
|
+
end: percentage,
|
|
93
|
+
},
|
|
94
|
+
};
|
|
95
|
+
existingSum_1 += percentage || 0;
|
|
96
|
+
lastEnd = lastEnd + (percentage || 0);
|
|
97
|
+
return result;
|
|
98
|
+
});
|
|
99
|
+
updatedAvailableRanges = (0, allocator_1.getUpdatedAvailableRangesAfterFilling)(availableRanges, existingSum_1);
|
|
62
100
|
}
|
|
63
101
|
variations.forEach(function (variation) {
|
|
64
|
-
var
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
});
|
|
72
|
-
return;
|
|
73
|
-
}
|
|
74
|
-
// const prevTotalWeightForVariation = existingTrafficRollout.allocation
|
|
75
|
-
// .filter((a) => a.variation === variation.value)
|
|
76
|
-
// .reduce((acc, curr) => acc + curr.percentage, 0);
|
|
77
|
-
// const diffWeightForVariation = (variation.weight as number) - prevTotalWeightForVariation / (MAX_BUCKETED_NUMBER / 100));
|
|
78
|
-
if (diffPercentage === 0) {
|
|
79
|
-
// no change
|
|
80
|
-
traffic.allocation.push({
|
|
81
|
-
variation: variation.value,
|
|
82
|
-
percentage: newPercentage,
|
|
83
|
-
});
|
|
84
|
-
return;
|
|
85
|
-
}
|
|
86
|
-
if (diffPercentage > 0) {
|
|
87
|
-
// increase - need to consistently bucket
|
|
88
|
-
traffic.allocation.push({
|
|
89
|
-
variation: variation.value,
|
|
90
|
-
percentage: parseInt((variation.weight *
|
|
91
|
-
(diffPercentage / 100) *
|
|
92
|
-
(sdk_1.MAX_BUCKETED_NUMBER / 100)).toFixed(2)),
|
|
93
|
-
});
|
|
94
|
-
return;
|
|
95
|
-
}
|
|
96
|
-
if (diffPercentage < 0) {
|
|
97
|
-
// decrease - need to re-bucket
|
|
98
|
-
// @TODO: can we maintain as much pre bucketed values as possible? to be close to consistent bucketing?
|
|
102
|
+
var weight = variation.weight;
|
|
103
|
+
var percentage = weight * (sdk_1.MAX_BUCKETED_NUMBER / 100);
|
|
104
|
+
var toFillValue = needsRebucketing
|
|
105
|
+
? percentage * (rulePercentage / 100) // whole value
|
|
106
|
+
: (weight / 100) * rulePercentageDiff; // incrementing
|
|
107
|
+
var rangesToFill = (0, allocator_1.getAllocation)(updatedAvailableRanges, toFillValue);
|
|
108
|
+
rangesToFill.forEach(function (range) {
|
|
99
109
|
traffic.allocation.push({
|
|
100
110
|
variation: variation.value,
|
|
101
|
-
percentage:
|
|
111
|
+
percentage: toFillValue,
|
|
112
|
+
range: range,
|
|
102
113
|
});
|
|
103
|
-
|
|
104
|
-
|
|
114
|
+
});
|
|
115
|
+
updatedAvailableRanges = (0, allocator_1.getUpdatedAvailableRangesAfterFilling)(updatedAvailableRanges, toFillValue);
|
|
105
116
|
});
|
|
106
117
|
result.push(traffic);
|
|
107
118
|
});
|
|
108
119
|
return result;
|
|
109
120
|
}
|
|
110
|
-
exports.
|
|
121
|
+
exports.getTraffic = getTraffic;
|
|
111
122
|
//# sourceMappingURL=traffic.js.map
|
package/lib/traffic.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"traffic.js","sourceRoot":"","sources":["../src/traffic.ts"],"names":[],"mappings":";;;AACA,yCAAwD;AAExD,SAAgB,
|
|
1
|
+
{"version":3,"file":"traffic.js","sourceRoot":"","sources":["../src/traffic.ts"],"names":[],"mappings":"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"}
|