@kenji71089/evaluation 0.0.1 → 0.0.8
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 +45 -0
- package/README.md +36 -6
- package/lib/bucketeer.d.ts +6 -0
- package/lib/bucketeer.js +65 -0
- package/lib/bucketeer.mjs +38 -0
- package/lib/clauseEvaluator.js +49 -7
- package/lib/clauseEvaluator.mjs +41 -7
- package/lib/evaluation.d.ts +10 -1
- package/lib/evaluation.js +184 -27
- package/lib/evaluation.mjs +141 -10
- package/lib/index.d.ts +12 -10
- package/lib/index.js +61 -40
- package/lib/index.mjs +16 -10
- package/lib/modelFactory.d.ts +1 -0
- package/lib/modelFactory.js +2 -0
- package/lib/modelFactory.mjs +2 -0
- package/lib/proto/event/client/event_pb.d.ts +19 -9
- package/lib/proto/event/client/event_pb.js +22 -12
- package/lib/proto/event/client/event_pb.mjs +100 -90
- package/lib/proto/feature/clause_pb.d.ts +2 -1
- package/lib/proto/feature/clause_pb.js +3 -2
- package/lib/proto/feature/clause_pb.mjs +7 -6
- package/lib/proto/feature/evaluation_pb.d.ts +3 -3
- package/lib/proto/feature/evaluation_pb.js +1 -1
- package/lib/proto/feature/evaluation_pb.mjs +15 -15
- package/lib/proto/feature/feature_last_used_info_pb.d.ts +10 -1
- package/lib/proto/feature/feature_last_used_info_pb.js +12 -1
- package/lib/proto/feature/feature_last_used_info_pb.mjs +18 -7
- package/lib/proto/feature/feature_pb.d.ts +72 -7
- package/lib/proto/feature/feature_pb.js +446 -4
- package/lib/proto/feature/feature_pb.mjs +535 -29
- package/lib/proto/feature/prerequisite_pb.d.ts +1 -1
- package/lib/proto/feature/prerequisite_pb.js +1 -1
- package/lib/proto/feature/prerequisite_pb.mjs +3 -3
- package/lib/proto/feature/reason_pb.d.ts +8 -1
- package/lib/proto/feature/reason_pb.js +9 -2
- package/lib/proto/feature/reason_pb.mjs +11 -4
- package/lib/proto/feature/rule_pb.d.ts +3 -3
- package/lib/proto/feature/rule_pb.js +1 -1
- package/lib/proto/feature/rule_pb.mjs +4 -4
- package/lib/proto/feature/segment_pb.d.ts +3 -3
- package/lib/proto/feature/segment_pb.js +1 -1
- package/lib/proto/feature/segment_pb.mjs +22 -22
- package/lib/proto/feature/strategy_pb.d.ts +31 -1
- package/lib/proto/feature/strategy_pb.js +206 -2
- package/lib/proto/feature/strategy_pb.mjs +242 -9
- package/lib/proto/feature/target_pb.d.ts +1 -1
- package/lib/proto/feature/target_pb.js +1 -1
- package/lib/proto/feature/target_pb.mjs +3 -3
- package/lib/proto/feature/variation_pb.d.ts +1 -1
- package/lib/proto/feature/variation_pb.js +1 -1
- package/lib/proto/feature/variation_pb.mjs +5 -5
- package/lib/proto/user/user_pb.d.ts +53 -1
- package/lib/proto/user/user_pb.js +374 -1
- package/lib/proto/user/user_pb.mjs +427 -7
- package/lib/strategyEvaluator.d.ts +0 -2
- package/lib/strategyEvaluator.js +23 -57
- package/lib/strategyEvaluator.mjs +23 -46
- package/lib/userEvaluation.js +13 -3
- package/lib/userEvaluation.mjs +13 -3
- package/package.json +15 -8
- package/lib/google/api/annotations_pb.d.ts +0 -8
- package/lib/google/api/annotations_pb.js +0 -40
- package/lib/google/api/annotations_pb.mjs +0 -54
- package/lib/google/api/annotations_pb_service.d.ts +0 -3
- package/lib/google/api/annotations_pb_service.js +0 -3
- package/lib/google/api/annotations_pb_service.mjs +0 -3
- package/lib/google/api/http_pb.d.ts +0 -132
- package/lib/google/api/http_pb.js +0 -860
- package/lib/google/api/http_pb.mjs +0 -982
- package/lib/google/api/http_pb_service.d.ts +0 -3
- package/lib/google/api/http_pb_service.js +0 -3
- package/lib/google/api/http_pb_service.mjs +0 -3
- package/lib/google/rpc/code_pb.d.ts +0 -26
- package/lib/google/rpc/code_pb.js +0 -44
- package/lib/google/rpc/code_pb.mjs +0 -48
- package/lib/google/rpc/code_pb_service.d.ts +0 -3
- package/lib/google/rpc/code_pb_service.js +0 -3
- package/lib/google/rpc/code_pb_service.mjs +0 -3
- package/lib/google/rpc/error_details_pb.d.ts +0 -322
- package/lib/google/rpc/error_details_pb.js +0 -2220
- package/lib/google/rpc/error_details_pb.mjs +0 -2499
- package/lib/google/rpc/error_details_pb_service.d.ts +0 -3
- package/lib/google/rpc/error_details_pb_service.js +0 -3
- package/lib/google/rpc/error_details_pb_service.mjs +0 -3
- package/lib/google/rpc/status_pb.d.ts +0 -36
- package/lib/google/rpc/status_pb.js +0 -235
- package/lib/google/rpc/status_pb.mjs +0 -268
- package/lib/google/rpc/status_pb_service.d.ts +0 -3
- package/lib/google/rpc/status_pb_service.js +0 -3
- package/lib/google/rpc/status_pb_service.mjs +0 -3
- package/lib/proto/event/client/event_pb_service.d.ts +0 -3
- package/lib/proto/event/client/event_pb_service.js +0 -3
- package/lib/proto/event/client/event_pb_service.mjs +0 -3
- package/lib/proto/event/domain/event_pb.d.ts +0 -4518
- package/lib/proto/event/domain/event_pb.js +0 -10834
- package/lib/proto/event/domain/event_pb.mjs +0 -33315
- package/lib/proto/event/domain/event_pb_service.d.ts +0 -3
- package/lib/proto/event/domain/event_pb_service.js +0 -3
- package/lib/proto/event/domain/event_pb_service.mjs +0 -3
- package/lib/proto/event/domain/localized_message_pb.d.ts +0 -29
- package/lib/proto/event/domain/localized_message_pb.js +0 -183
- package/lib/proto/event/domain/localized_message_pb.mjs +0 -206
- package/lib/proto/event/domain/localized_message_pb_service.d.ts +0 -3
- package/lib/proto/event/domain/localized_message_pb_service.js +0 -3
- package/lib/proto/event/domain/localized_message_pb_service.mjs +0 -3
- package/lib/proto/event/service/feature_pb.d.ts +0 -44
- package/lib/proto/event/service/feature_pb.js +0 -277
- package/lib/proto/event/service/feature_pb.mjs +0 -319
- package/lib/proto/event/service/feature_pb_service.d.ts +0 -3
- package/lib/proto/event/service/feature_pb_service.js +0 -3
- package/lib/proto/event/service/feature_pb_service.mjs +0 -3
- package/lib/proto/event/service/segment_pb.d.ts +0 -51
- package/lib/proto/event/service/segment_pb.js +0 -324
- package/lib/proto/event/service/segment_pb.mjs +0 -375
- package/lib/proto/event/service/segment_pb_service.d.ts +0 -3
- package/lib/proto/event/service/segment_pb_service.js +0 -3
- package/lib/proto/event/service/segment_pb_service.mjs +0 -3
- package/lib/proto/event/service/user_pb.d.ts +0 -49
- package/lib/proto/event/service/user_pb.js +0 -315
- package/lib/proto/event/service/user_pb.mjs +0 -362
- package/lib/proto/event/service/user_pb_service.d.ts +0 -3
- package/lib/proto/event/service/user_pb_service.js +0 -3
- package/lib/proto/event/service/user_pb_service.mjs +0 -3
- package/lib/proto/feature/clause_pb_service.d.ts +0 -3
- package/lib/proto/feature/clause_pb_service.js +0 -3
- package/lib/proto/feature/clause_pb_service.mjs +0 -3
- package/lib/proto/feature/command_pb.d.ts +0 -1213
- package/lib/proto/feature/command_pb.js +0 -8260
- package/lib/proto/feature/command_pb.mjs +0 -9275
- package/lib/proto/feature/command_pb_service.d.ts +0 -3
- package/lib/proto/feature/command_pb_service.js +0 -3
- package/lib/proto/feature/command_pb_service.mjs +0 -3
- package/lib/proto/feature/evaluation_pb_service.d.ts +0 -3
- package/lib/proto/feature/evaluation_pb_service.js +0 -3
- package/lib/proto/feature/evaluation_pb_service.mjs +0 -3
- package/lib/proto/feature/feature_last_used_info_pb_service.d.ts +0 -3
- package/lib/proto/feature/feature_last_used_info_pb_service.js +0 -3
- package/lib/proto/feature/feature_last_used_info_pb_service.mjs +0 -3
- package/lib/proto/feature/feature_pb_service.d.ts +0 -3
- package/lib/proto/feature/feature_pb_service.js +0 -3
- package/lib/proto/feature/feature_pb_service.mjs +0 -3
- package/lib/proto/feature/flag_trigger_pb.d.ts +0 -84
- package/lib/proto/feature/flag_trigger_pb.js +0 -452
- package/lib/proto/feature/flag_trigger_pb.mjs +0 -525
- package/lib/proto/feature/flag_trigger_pb_service.d.ts +0 -3
- package/lib/proto/feature/flag_trigger_pb_service.js +0 -3
- package/lib/proto/feature/flag_trigger_pb_service.mjs +0 -3
- package/lib/proto/feature/prerequisite_pb_service.d.ts +0 -3
- package/lib/proto/feature/prerequisite_pb_service.js +0 -3
- package/lib/proto/feature/prerequisite_pb_service.mjs +0 -3
- package/lib/proto/feature/reason_pb_service.d.ts +0 -3
- package/lib/proto/feature/reason_pb_service.js +0 -3
- package/lib/proto/feature/reason_pb_service.mjs +0 -3
- package/lib/proto/feature/rule_pb_service.d.ts +0 -3
- package/lib/proto/feature/rule_pb_service.js +0 -3
- package/lib/proto/feature/rule_pb_service.mjs +0 -3
- package/lib/proto/feature/segment_pb_service.d.ts +0 -3
- package/lib/proto/feature/segment_pb_service.js +0 -3
- package/lib/proto/feature/segment_pb_service.mjs +0 -3
- package/lib/proto/feature/service_pb.d.ts +0 -2158
- package/lib/proto/feature/service_pb.js +0 -5363
- package/lib/proto/feature/service_pb.mjs +0 -16348
- package/lib/proto/feature/service_pb_service.d.ts +0 -747
- package/lib/proto/feature/service_pb_service.js +0 -1424
- package/lib/proto/feature/service_pb_service.mjs +0 -1501
- package/lib/proto/feature/strategy_pb_service.d.ts +0 -3
- package/lib/proto/feature/strategy_pb_service.js +0 -3
- package/lib/proto/feature/strategy_pb_service.mjs +0 -3
- package/lib/proto/feature/target_pb_service.d.ts +0 -3
- package/lib/proto/feature/target_pb_service.js +0 -3
- package/lib/proto/feature/target_pb_service.mjs +0 -3
- package/lib/proto/feature/variation_pb_service.d.ts +0 -3
- package/lib/proto/feature/variation_pb_service.js +0 -3
- package/lib/proto/feature/variation_pb_service.mjs +0 -3
- package/lib/proto/gateway/service_pb.d.ts +0 -772
- package/lib/proto/gateway/service_pb.js +0 -5249
- package/lib/proto/gateway/service_pb.mjs +0 -6001
- package/lib/proto/gateway/service_pb_service.d.ts +0 -253
- package/lib/proto/gateway/service_pb_service.js +0 -436
- package/lib/proto/gateway/service_pb_service.mjs +0 -461
- package/lib/proto/user/user_pb_service.d.ts +0 -3
- package/lib/proto/user/user_pb_service.js +0 -3
- package/lib/proto/user/user_pb_service.mjs +0 -3
- package/lib/protoc-gen-openapiv2/options/annotations_pb.d.ts +0 -16
- package/lib/protoc-gen-openapiv2/options/annotations_pb.js +0 -100
- package/lib/protoc-gen-openapiv2/options/annotations_pb.mjs +0 -158
- package/lib/protoc-gen-openapiv2/options/annotations_pb_service.d.ts +0 -3
- package/lib/protoc-gen-openapiv2/options/annotations_pb_service.js +0 -3
- package/lib/protoc-gen-openapiv2/options/annotations_pb_service.mjs +0 -3
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb.d.ts +0 -834
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb.js +0 -5456
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb.mjs +0 -6256
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.d.ts +0 -3
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.js +0 -3
- package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.mjs +0 -3
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.0.7] (2026-01-20)
|
|
4
|
+
|
|
5
|
+
### Fix
|
|
6
|
+
|
|
7
|
+
- fix(evaluation): align equals/in semver fallback behavior with comparison operators [#2355](https://github.com/bucketeer-io/bucketeer/pull/2355)
|
|
8
|
+
|
|
9
|
+
## [0.0.6] (2025-11-19)
|
|
10
|
+
|
|
11
|
+
### Features
|
|
12
|
+
|
|
13
|
+
- add yaml flag type support [#2217](https://github.com/bucketeer-io/bucketeer/pull/2217)
|
|
14
|
+
|
|
15
|
+
## [0.0.5] (2025-09-26)
|
|
16
|
+
|
|
17
|
+
### Fix
|
|
18
|
+
|
|
19
|
+
- fix: resolve missing dependencies in incremental feature flag evaluation [#2315](https://github.com/bucketeer-io/bucketeer/pull/2135)
|
|
20
|
+
|
|
21
|
+
## [0.0.4] (2025-09-01)
|
|
22
|
+
|
|
23
|
+
### Feat
|
|
24
|
+
|
|
25
|
+
- feat: support not equal operator for evaluation [#2095](https://github.com/bucketeer-io/bucketeer/pull/2095)
|
|
26
|
+
|
|
27
|
+
## [0.0.3] (2025-03-07)
|
|
28
|
+
|
|
29
|
+
### Fix
|
|
30
|
+
|
|
31
|
+
- fix(evaluation/typescript): missing proto import when build release lib [#1567]([https://github.com/bucketeer-io/bucketeer/pull/1567)
|
|
32
|
+
|
|
33
|
+
## [0.0.2] (2025-03-04)
|
|
34
|
+
|
|
35
|
+
### Miscellaneous
|
|
36
|
+
|
|
37
|
+
- chore(evaluation/typescript): export function getFeatureIDsDependsOn [#1553](https://github.com/bucketeer-io/bucketeer/pull/1553)
|
|
38
|
+
|
|
39
|
+
- chore: improve bucket hash algorithm using murmurHash3 instead of md5 [#1523](https://github.com/bucketeer-io/bucketeer/pull/1523)
|
|
40
|
+
|
|
41
|
+
## [0.0.1] (2025-01-22)
|
|
42
|
+
|
|
43
|
+
### Features
|
|
44
|
+
|
|
45
|
+
- initial release [#1258](https://github.com/bucketeer-io/bucketeer/pull/1258)
|
package/README.md
CHANGED
|
@@ -1,9 +1,39 @@
|
|
|
1
1
|
# Evaluation module for Node.JS
|
|
2
2
|
|
|
3
|
-
##
|
|
4
|
-
```export NPM_TOKEN="YOUR_NPM_TOKEN"```
|
|
5
|
-
```make init```
|
|
6
|
-
```make copy_proto_generated_code```
|
|
3
|
+
## Development
|
|
7
4
|
|
|
8
|
-
|
|
9
|
-
|
|
5
|
+
### Setup
|
|
6
|
+
|
|
7
|
+
```sh
|
|
8
|
+
export NPM_TOKEN="YOUR_NPM_TOKEN"
|
|
9
|
+
make init
|
|
10
|
+
make gen_proto
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
### Build
|
|
14
|
+
|
|
15
|
+
```sh
|
|
16
|
+
make build
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
### Unit tests
|
|
20
|
+
|
|
21
|
+
```sh
|
|
22
|
+
make test
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
### Lint
|
|
26
|
+
|
|
27
|
+
```sh
|
|
28
|
+
make lint
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Release to NPM
|
|
32
|
+
|
|
33
|
+
```sh
|
|
34
|
+
export NPM_TOKEN="YOUR_NPM_TOKEN"
|
|
35
|
+
make init
|
|
36
|
+
make gen_proto
|
|
37
|
+
make build
|
|
38
|
+
make publish
|
|
39
|
+
```
|
package/lib/bucketeer.js
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
|
|
4
|
+
function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
|
|
5
|
+
function _defineProperties(e, r) { for (var t = 0; t < r.length; t++) { var o = r[t]; o.enumerable = o.enumerable || !1, o.configurable = !0, "value" in o && (o.writable = !0), Object.defineProperty(e, _toPropertyKey(o.key), o); } }
|
|
6
|
+
function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
|
|
7
|
+
function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
|
|
8
|
+
function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
|
|
9
|
+
var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
|
|
10
|
+
return mod && mod.__esModule ? mod : {
|
|
11
|
+
"default": mod
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
Object.defineProperty(exports, "__esModule", {
|
|
15
|
+
value: true
|
|
16
|
+
});
|
|
17
|
+
exports.Bucketeer = void 0;
|
|
18
|
+
var murmurhash3js_1 = __importDefault(require("murmurhash3js"));
|
|
19
|
+
var Bucketeer = /*#__PURE__*/function () {
|
|
20
|
+
function Bucketeer() {
|
|
21
|
+
_classCallCheck(this, Bucketeer);
|
|
22
|
+
}
|
|
23
|
+
return _createClass(Bucketeer, [{
|
|
24
|
+
key: "bucket",
|
|
25
|
+
value:
|
|
26
|
+
// Calculate the input hash of the target property and map it to a float64 between [0,1]
|
|
27
|
+
function bucket(input) {
|
|
28
|
+
var _this$murmur = this.murmur128(input),
|
|
29
|
+
high = _this$murmur.high,
|
|
30
|
+
low = _this$murmur.low;
|
|
31
|
+
return this.toFloat64(high, low);
|
|
32
|
+
}
|
|
33
|
+
// Computes MurmurHash3 (128-bit) hash and returns the high and low parts.
|
|
34
|
+
// The high and low parts of the hash are returned in big-endian format,
|
|
35
|
+
// which is crucial for consistency with the Go implementation that also uses big-endian.
|
|
36
|
+
}, {
|
|
37
|
+
key: "murmur128",
|
|
38
|
+
value: function murmur128(input) {
|
|
39
|
+
var hash = murmurhash3js_1["default"].x64.hash128(input);
|
|
40
|
+
// Convert the hash from hexadecimal to BigInt.
|
|
41
|
+
// The first 16 characters represent the high part (most significant bits),
|
|
42
|
+
// and the last 16 characters represent the low part (least significant bits).
|
|
43
|
+
var high = BigInt('0x' + hash.slice(0, 16)); // High part
|
|
44
|
+
var low = BigInt('0x' + hash.slice(16, 32)); // Low part
|
|
45
|
+
return {
|
|
46
|
+
high: high,
|
|
47
|
+
low: low
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
// Convert a 128-bit hash (two uint64 values) to a float64 in the range [0,1].
|
|
51
|
+
// Because we bucket millions of users, we use the full 128-bit hash to avoid collisions.
|
|
52
|
+
}, {
|
|
53
|
+
key: "toFloat64",
|
|
54
|
+
value: function toFloat64(high, low) {
|
|
55
|
+
// Combine the high and low parts into a single floating-point number.
|
|
56
|
+
// This maintains the full 128-bit range, ensuring a normalized value between [0,1].
|
|
57
|
+
var full = Number(high) * Math.pow(2, 64) + Number(low);
|
|
58
|
+
// Calculate the maximum value for a 128-bit number.
|
|
59
|
+
var maxValue = Math.pow(2, 128) - 1;
|
|
60
|
+
// Normalize the combined value to the range [0,1].
|
|
61
|
+
return full / maxValue;
|
|
62
|
+
}
|
|
63
|
+
}]);
|
|
64
|
+
}();
|
|
65
|
+
exports.Bucketeer = Bucketeer;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Bucketeer = void 0;
|
|
7
|
+
const murmurhash3js_1 = __importDefault(require("murmurhash3js"));
|
|
8
|
+
class Bucketeer {
|
|
9
|
+
// Calculate the input hash of the target property and map it to a float64 between [0,1]
|
|
10
|
+
bucket(input) {
|
|
11
|
+
const { high, low } = this.murmur128(input);
|
|
12
|
+
return this.toFloat64(high, low);
|
|
13
|
+
}
|
|
14
|
+
// Computes MurmurHash3 (128-bit) hash and returns the high and low parts.
|
|
15
|
+
// The high and low parts of the hash are returned in big-endian format,
|
|
16
|
+
// which is crucial for consistency with the Go implementation that also uses big-endian.
|
|
17
|
+
murmur128(input) {
|
|
18
|
+
const hash = murmurhash3js_1.default.x64.hash128(input);
|
|
19
|
+
// Convert the hash from hexadecimal to BigInt.
|
|
20
|
+
// The first 16 characters represent the high part (most significant bits),
|
|
21
|
+
// and the last 16 characters represent the low part (least significant bits).
|
|
22
|
+
const high = BigInt('0x' + hash.slice(0, 16)); // High part
|
|
23
|
+
const low = BigInt('0x' + hash.slice(16, 32)); // Low part
|
|
24
|
+
return { high, low };
|
|
25
|
+
}
|
|
26
|
+
// Convert a 128-bit hash (two uint64 values) to a float64 in the range [0,1].
|
|
27
|
+
// Because we bucket millions of users, we use the full 128-bit hash to avoid collisions.
|
|
28
|
+
toFloat64(high, low) {
|
|
29
|
+
// Combine the high and low parts into a single floating-point number.
|
|
30
|
+
// This maintains the full 128-bit range, ensuring a normalized value between [0,1].
|
|
31
|
+
const full = Number(high) * Math.pow(2, 64) + Number(low);
|
|
32
|
+
// Calculate the maximum value for a 128-bit number.
|
|
33
|
+
const maxValue = Math.pow(2, 128) - 1;
|
|
34
|
+
// Normalize the combined value to the range [0,1].
|
|
35
|
+
return full / maxValue;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.Bucketeer = Bucketeer;
|
package/lib/clauseEvaluator.js
CHANGED
|
@@ -31,13 +31,23 @@ var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create
|
|
|
31
31
|
} : function (o, v) {
|
|
32
32
|
o["default"] = v;
|
|
33
33
|
});
|
|
34
|
-
var __importStar = void 0 && (void 0).__importStar || function (
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
};
|
|
34
|
+
var __importStar = void 0 && (void 0).__importStar || function () {
|
|
35
|
+
var _ownKeys = function ownKeys(o) {
|
|
36
|
+
_ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
37
|
+
var ar = [];
|
|
38
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
39
|
+
return ar;
|
|
40
|
+
};
|
|
41
|
+
return _ownKeys(o);
|
|
42
|
+
};
|
|
43
|
+
return function (mod) {
|
|
44
|
+
if (mod && mod.__esModule) return mod;
|
|
45
|
+
var result = {};
|
|
46
|
+
if (mod != null) for (var k = _ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
47
|
+
__setModuleDefault(result, mod);
|
|
48
|
+
return result;
|
|
49
|
+
};
|
|
50
|
+
}();
|
|
41
51
|
Object.defineProperty(exports, "__esModule", {
|
|
42
52
|
value: true
|
|
43
53
|
});
|
|
@@ -86,6 +96,8 @@ var ClauseEvaluator = /*#__PURE__*/function () {
|
|
|
86
96
|
return this.dependencyEvaluator.evaluate(clause.getAttribute(), clause.getValuesList(), flagVariations);
|
|
87
97
|
case clause_pb_1.Clause.Operator.PARTIALLY_MATCH:
|
|
88
98
|
return this.partiallyMatches(targetValue, clause.getValuesList());
|
|
99
|
+
case clause_pb_1.Clause.Operator.NOT_EQUALS:
|
|
100
|
+
return !this.equals(targetValue, clause.getValuesList());
|
|
89
101
|
default:
|
|
90
102
|
return false;
|
|
91
103
|
}
|
|
@@ -97,6 +109,21 @@ var ClauseEvaluator = /*#__PURE__*/function () {
|
|
|
97
109
|
}, {
|
|
98
110
|
key: "equals",
|
|
99
111
|
value: function equals(targetValue, values) {
|
|
112
|
+
// First try semver comparison (with v-prefix normalization via semver.valid)
|
|
113
|
+
var semverTarget = semver.valid(targetValue);
|
|
114
|
+
if (semverTarget) {
|
|
115
|
+
var semverValues = values.map(function (v) {
|
|
116
|
+
return semver.valid(v);
|
|
117
|
+
}).filter(function (v) {
|
|
118
|
+
return v !== null;
|
|
119
|
+
});
|
|
120
|
+
// Target parsed as semver; if no values parsed or none matched, return false
|
|
121
|
+
// (consistent with greaterOrEqual, greater, less, lessOrEqual behavior)
|
|
122
|
+
return semverValues.some(function (value) {
|
|
123
|
+
return semver.eq(semverTarget, value);
|
|
124
|
+
});
|
|
125
|
+
}
|
|
126
|
+
// Fall back to exact string comparison only when target fails to parse as semver
|
|
100
127
|
return values.includes(targetValue);
|
|
101
128
|
}
|
|
102
129
|
}, {
|
|
@@ -109,6 +136,21 @@ var ClauseEvaluator = /*#__PURE__*/function () {
|
|
|
109
136
|
}, {
|
|
110
137
|
key: "in",
|
|
111
138
|
value: function _in(targetValue, values) {
|
|
139
|
+
// First try semver comparison (with v-prefix normalization via semver.valid)
|
|
140
|
+
var semverTarget = semver.valid(targetValue);
|
|
141
|
+
if (semverTarget) {
|
|
142
|
+
var semverValues = values.map(function (v) {
|
|
143
|
+
return semver.valid(v);
|
|
144
|
+
}).filter(function (v) {
|
|
145
|
+
return v !== null;
|
|
146
|
+
});
|
|
147
|
+
// Target parsed as semver; if no values parsed or none matched, return false
|
|
148
|
+
// (consistent with greaterOrEqual, greater, less, lessOrEqual behavior)
|
|
149
|
+
return semverValues.some(function (value) {
|
|
150
|
+
return semver.eq(semverTarget, value);
|
|
151
|
+
});
|
|
152
|
+
}
|
|
153
|
+
// Fall back to exact string comparison only when target fails to parse as semver
|
|
112
154
|
return values.includes(targetValue);
|
|
113
155
|
}
|
|
114
156
|
}, {
|
package/lib/clauseEvaluator.mjs
CHANGED
|
@@ -15,13 +15,23 @@ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (
|
|
|
15
15
|
}) : function(o, v) {
|
|
16
16
|
o["default"] = v;
|
|
17
17
|
});
|
|
18
|
-
var __importStar = (this && this.__importStar) || function (
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
};
|
|
18
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
19
|
+
var ownKeys = function(o) {
|
|
20
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
21
|
+
var ar = [];
|
|
22
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
23
|
+
return ar;
|
|
24
|
+
};
|
|
25
|
+
return ownKeys(o);
|
|
26
|
+
};
|
|
27
|
+
return function (mod) {
|
|
28
|
+
if (mod && mod.__esModule) return mod;
|
|
29
|
+
var result = {};
|
|
30
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
31
|
+
__setModuleDefault(result, mod);
|
|
32
|
+
return result;
|
|
33
|
+
};
|
|
34
|
+
})();
|
|
25
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
26
36
|
exports.ClauseEvaluator = void 0;
|
|
27
37
|
const clause_pb_1 = require("./proto/feature/clause_pb");
|
|
@@ -65,6 +75,8 @@ class ClauseEvaluator {
|
|
|
65
75
|
return this.dependencyEvaluator.evaluate(clause.getAttribute(), clause.getValuesList(), flagVariations);
|
|
66
76
|
case clause_pb_1.Clause.Operator.PARTIALLY_MATCH:
|
|
67
77
|
return this.partiallyMatches(targetValue, clause.getValuesList());
|
|
78
|
+
case clause_pb_1.Clause.Operator.NOT_EQUALS:
|
|
79
|
+
return !this.equals(targetValue, clause.getValuesList());
|
|
68
80
|
default:
|
|
69
81
|
return false;
|
|
70
82
|
}
|
|
@@ -75,12 +87,34 @@ class ClauseEvaluator {
|
|
|
75
87
|
}
|
|
76
88
|
}
|
|
77
89
|
equals(targetValue, values) {
|
|
90
|
+
// First try semver comparison (with v-prefix normalization via semver.valid)
|
|
91
|
+
const semverTarget = semver.valid(targetValue);
|
|
92
|
+
if (semverTarget) {
|
|
93
|
+
const semverValues = values
|
|
94
|
+
.map((v) => semver.valid(v))
|
|
95
|
+
.filter((v) => v !== null);
|
|
96
|
+
// Target parsed as semver; if no values parsed or none matched, return false
|
|
97
|
+
// (consistent with greaterOrEqual, greater, less, lessOrEqual behavior)
|
|
98
|
+
return semverValues.some((value) => semver.eq(semverTarget, value));
|
|
99
|
+
}
|
|
100
|
+
// Fall back to exact string comparison only when target fails to parse as semver
|
|
78
101
|
return values.includes(targetValue);
|
|
79
102
|
}
|
|
80
103
|
partiallyMatches(targetValue, values) {
|
|
81
104
|
return values.some((value) => targetValue.includes(value));
|
|
82
105
|
}
|
|
83
106
|
in(targetValue, values) {
|
|
107
|
+
// First try semver comparison (with v-prefix normalization via semver.valid)
|
|
108
|
+
const semverTarget = semver.valid(targetValue);
|
|
109
|
+
if (semverTarget) {
|
|
110
|
+
const semverValues = values
|
|
111
|
+
.map((v) => semver.valid(v))
|
|
112
|
+
.filter((v) => v !== null);
|
|
113
|
+
// Target parsed as semver; if no values parsed or none matched, return false
|
|
114
|
+
// (consistent with greaterOrEqual, greater, less, lessOrEqual behavior)
|
|
115
|
+
return semverValues.some((value) => semver.eq(semverTarget, value));
|
|
116
|
+
}
|
|
117
|
+
// Fall back to exact string comparison only when target fails to parse as semver
|
|
84
118
|
return values.includes(targetValue);
|
|
85
119
|
}
|
|
86
120
|
startsWith(targetValue, values) {
|
package/lib/evaluation.d.ts
CHANGED
|
@@ -8,6 +8,7 @@ export declare function EvaluationID(featureID: string, featureVersion: number,
|
|
|
8
8
|
declare class Evaluator {
|
|
9
9
|
private ruleEvaluator;
|
|
10
10
|
private strategyEvaluator;
|
|
11
|
+
private variationCache;
|
|
11
12
|
constructor();
|
|
12
13
|
evaluateFeatures(features: Feature[], user: User, mapSegmentUsers: Map<string, SegmentUser[]>, targetTag: string): Promise<UserEvaluations>;
|
|
13
14
|
getPrerequisiteDownwards(targetFeatures: Feature[], allFeatures: Feature[]): Feature[];
|
|
@@ -21,5 +22,13 @@ declare class Evaluator {
|
|
|
21
22
|
}): [Reason, Variation];
|
|
22
23
|
getEvalFeatures(targetFeatures: Feature[], allFeatures: Feature[]): Feature[];
|
|
23
24
|
private findVariation;
|
|
25
|
+
/**
|
|
26
|
+
* Converts YAML to JSON if needed, with in-memory caching.
|
|
27
|
+
* This ensures client SDKs can retrieve variation values using the object variation interface.
|
|
28
|
+
* Only performs conversion when the variation type is YAML.
|
|
29
|
+
* Cache key uses feature.updatedAt + variation.id to ensure cache invalidation when variations are updated.
|
|
30
|
+
*/
|
|
31
|
+
private convertVariationValue;
|
|
24
32
|
}
|
|
25
|
-
|
|
33
|
+
declare function getFeatureIDsDependsOn(feature: Feature): Array<string>;
|
|
34
|
+
export { Evaluator, getFeatureIDsDependsOn };
|