@kenji71089/evaluation 0.0.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.
Files changed (209) hide show
  1. package/.release-please-manifest.json +3 -0
  2. package/README.md +9 -0
  3. package/eslint.config.mjs +27 -0
  4. package/lib/clauseEvaluator.d.ts +22 -0
  5. package/lib/clauseEvaluator.js +299 -0
  6. package/lib/clauseEvaluator.mjs +214 -0
  7. package/lib/dependencyEvaluator.d.ts +6 -0
  8. package/lib/dependencyEvaluator.js +46 -0
  9. package/lib/dependencyEvaluator.mjs +19 -0
  10. package/lib/errors.d.ts +9 -0
  11. package/lib/errors.js +15 -0
  12. package/lib/errors.mjs +12 -0
  13. package/lib/evaluation.d.ts +25 -0
  14. package/lib/evaluation.js +503 -0
  15. package/lib/evaluation.mjs +328 -0
  16. package/lib/google/api/annotations_pb.d.ts +8 -0
  17. package/lib/google/api/annotations_pb.js +40 -0
  18. package/lib/google/api/annotations_pb.mjs +54 -0
  19. package/lib/google/api/annotations_pb_service.d.ts +3 -0
  20. package/lib/google/api/annotations_pb_service.js +3 -0
  21. package/lib/google/api/annotations_pb_service.mjs +3 -0
  22. package/lib/google/api/http_pb.d.ts +132 -0
  23. package/lib/google/api/http_pb.js +860 -0
  24. package/lib/google/api/http_pb.mjs +982 -0
  25. package/lib/google/api/http_pb_service.d.ts +3 -0
  26. package/lib/google/api/http_pb_service.js +3 -0
  27. package/lib/google/api/http_pb_service.mjs +3 -0
  28. package/lib/google/rpc/code_pb.d.ts +26 -0
  29. package/lib/google/rpc/code_pb.js +44 -0
  30. package/lib/google/rpc/code_pb.mjs +48 -0
  31. package/lib/google/rpc/code_pb_service.d.ts +3 -0
  32. package/lib/google/rpc/code_pb_service.js +3 -0
  33. package/lib/google/rpc/code_pb_service.mjs +3 -0
  34. package/lib/google/rpc/error_details_pb.d.ts +322 -0
  35. package/lib/google/rpc/error_details_pb.js +2220 -0
  36. package/lib/google/rpc/error_details_pb.mjs +2499 -0
  37. package/lib/google/rpc/error_details_pb_service.d.ts +3 -0
  38. package/lib/google/rpc/error_details_pb_service.js +3 -0
  39. package/lib/google/rpc/error_details_pb_service.mjs +3 -0
  40. package/lib/google/rpc/status_pb.d.ts +36 -0
  41. package/lib/google/rpc/status_pb.js +235 -0
  42. package/lib/google/rpc/status_pb.mjs +268 -0
  43. package/lib/google/rpc/status_pb_service.d.ts +3 -0
  44. package/lib/google/rpc/status_pb_service.js +3 -0
  45. package/lib/google/rpc/status_pb_service.mjs +3 -0
  46. package/lib/index.d.ts +20 -0
  47. package/lib/index.js +199 -0
  48. package/lib/index.mjs +46 -0
  49. package/lib/modelFactory.d.ts +64 -0
  50. package/lib/modelFactory.js +206 -0
  51. package/lib/modelFactory.mjs +176 -0
  52. package/lib/proto/event/client/event_pb.d.ts +761 -0
  53. package/lib/proto/event/client/event_pb.js +5195 -0
  54. package/lib/proto/event/client/event_pb.mjs +5865 -0
  55. package/lib/proto/event/client/event_pb_service.d.ts +3 -0
  56. package/lib/proto/event/client/event_pb_service.js +3 -0
  57. package/lib/proto/event/client/event_pb_service.mjs +3 -0
  58. package/lib/proto/event/domain/event_pb.d.ts +4518 -0
  59. package/lib/proto/event/domain/event_pb.js +10834 -0
  60. package/lib/proto/event/domain/event_pb.mjs +33315 -0
  61. package/lib/proto/event/domain/event_pb_service.d.ts +3 -0
  62. package/lib/proto/event/domain/event_pb_service.js +3 -0
  63. package/lib/proto/event/domain/event_pb_service.mjs +3 -0
  64. package/lib/proto/event/domain/localized_message_pb.d.ts +29 -0
  65. package/lib/proto/event/domain/localized_message_pb.js +183 -0
  66. package/lib/proto/event/domain/localized_message_pb.mjs +206 -0
  67. package/lib/proto/event/domain/localized_message_pb_service.d.ts +3 -0
  68. package/lib/proto/event/domain/localized_message_pb_service.js +3 -0
  69. package/lib/proto/event/domain/localized_message_pb_service.mjs +3 -0
  70. package/lib/proto/event/service/feature_pb.d.ts +44 -0
  71. package/lib/proto/event/service/feature_pb.js +277 -0
  72. package/lib/proto/event/service/feature_pb.mjs +319 -0
  73. package/lib/proto/event/service/feature_pb_service.d.ts +3 -0
  74. package/lib/proto/event/service/feature_pb_service.js +3 -0
  75. package/lib/proto/event/service/feature_pb_service.mjs +3 -0
  76. package/lib/proto/event/service/segment_pb.d.ts +51 -0
  77. package/lib/proto/event/service/segment_pb.js +324 -0
  78. package/lib/proto/event/service/segment_pb.mjs +375 -0
  79. package/lib/proto/event/service/segment_pb_service.d.ts +3 -0
  80. package/lib/proto/event/service/segment_pb_service.js +3 -0
  81. package/lib/proto/event/service/segment_pb_service.mjs +3 -0
  82. package/lib/proto/event/service/user_pb.d.ts +49 -0
  83. package/lib/proto/event/service/user_pb.js +315 -0
  84. package/lib/proto/event/service/user_pb.mjs +362 -0
  85. package/lib/proto/event/service/user_pb_service.d.ts +3 -0
  86. package/lib/proto/event/service/user_pb_service.js +3 -0
  87. package/lib/proto/event/service/user_pb_service.mjs +3 -0
  88. package/lib/proto/feature/clause_pb.d.ts +57 -0
  89. package/lib/proto/feature/clause_pb.js +277 -0
  90. package/lib/proto/feature/clause_pb.mjs +312 -0
  91. package/lib/proto/feature/clause_pb_service.d.ts +3 -0
  92. package/lib/proto/feature/clause_pb_service.js +3 -0
  93. package/lib/proto/feature/clause_pb_service.mjs +3 -0
  94. package/lib/proto/feature/command_pb.d.ts +1213 -0
  95. package/lib/proto/feature/command_pb.js +8260 -0
  96. package/lib/proto/feature/command_pb.mjs +9275 -0
  97. package/lib/proto/feature/command_pb_service.d.ts +3 -0
  98. package/lib/proto/feature/command_pb_service.js +3 -0
  99. package/lib/proto/feature/command_pb_service.mjs +3 -0
  100. package/lib/proto/feature/evaluation_pb.d.ts +111 -0
  101. package/lib/proto/feature/evaluation_pb.js +685 -0
  102. package/lib/proto/feature/evaluation_pb.mjs +793 -0
  103. package/lib/proto/feature/evaluation_pb_service.d.ts +3 -0
  104. package/lib/proto/feature/evaluation_pb_service.js +3 -0
  105. package/lib/proto/feature/evaluation_pb_service.mjs +3 -0
  106. package/lib/proto/feature/feature_last_used_info_pb.d.ts +45 -0
  107. package/lib/proto/feature/feature_last_used_info_pb.js +283 -0
  108. package/lib/proto/feature/feature_last_used_info_pb.mjs +326 -0
  109. package/lib/proto/feature/feature_last_used_info_pb_service.d.ts +3 -0
  110. package/lib/proto/feature/feature_last_used_info_pb_service.js +3 -0
  111. package/lib/proto/feature/feature_last_used_info_pb_service.mjs +3 -0
  112. package/lib/proto/feature/feature_pb.d.ts +192 -0
  113. package/lib/proto/feature/feature_pb.js +1210 -0
  114. package/lib/proto/feature/feature_pb.mjs +1413 -0
  115. package/lib/proto/feature/feature_pb_service.d.ts +3 -0
  116. package/lib/proto/feature/feature_pb_service.js +3 -0
  117. package/lib/proto/feature/feature_pb_service.mjs +3 -0
  118. package/lib/proto/feature/flag_trigger_pb.d.ts +84 -0
  119. package/lib/proto/feature/flag_trigger_pb.js +452 -0
  120. package/lib/proto/feature/flag_trigger_pb.mjs +525 -0
  121. package/lib/proto/feature/flag_trigger_pb_service.d.ts +3 -0
  122. package/lib/proto/feature/flag_trigger_pb_service.js +3 -0
  123. package/lib/proto/feature/flag_trigger_pb_service.mjs +3 -0
  124. package/lib/proto/feature/prerequisite_pb.d.ts +29 -0
  125. package/lib/proto/feature/prerequisite_pb.js +183 -0
  126. package/lib/proto/feature/prerequisite_pb.mjs +206 -0
  127. package/lib/proto/feature/prerequisite_pb_service.d.ts +3 -0
  128. package/lib/proto/feature/prerequisite_pb_service.js +3 -0
  129. package/lib/proto/feature/prerequisite_pb_service.mjs +3 -0
  130. package/lib/proto/feature/reason_pb.d.ts +40 -0
  131. package/lib/proto/feature/reason_pb.js +196 -0
  132. package/lib/proto/feature/reason_pb.mjs +219 -0
  133. package/lib/proto/feature/reason_pb_service.d.ts +3 -0
  134. package/lib/proto/feature/reason_pb_service.js +3 -0
  135. package/lib/proto/feature/reason_pb_service.mjs +3 -0
  136. package/lib/proto/feature/rule_pb.d.ts +39 -0
  137. package/lib/proto/feature/rule_pb.js +254 -0
  138. package/lib/proto/feature/rule_pb.mjs +291 -0
  139. package/lib/proto/feature/rule_pb_service.d.ts +3 -0
  140. package/lib/proto/feature/rule_pb_service.js +3 -0
  141. package/lib/proto/feature/rule_pb_service.mjs +3 -0
  142. package/lib/proto/feature/segment_pb.d.ts +161 -0
  143. package/lib/proto/feature/segment_pb.js +974 -0
  144. package/lib/proto/feature/segment_pb.mjs +1127 -0
  145. package/lib/proto/feature/segment_pb_service.d.ts +3 -0
  146. package/lib/proto/feature/segment_pb_service.js +3 -0
  147. package/lib/proto/feature/segment_pb_service.mjs +3 -0
  148. package/lib/proto/feature/service_pb.d.ts +2158 -0
  149. package/lib/proto/feature/service_pb.js +5363 -0
  150. package/lib/proto/feature/service_pb.mjs +16348 -0
  151. package/lib/proto/feature/service_pb_service.d.ts +747 -0
  152. package/lib/proto/feature/service_pb_service.js +1424 -0
  153. package/lib/proto/feature/service_pb_service.mjs +1501 -0
  154. package/lib/proto/feature/strategy_pb.d.ts +110 -0
  155. package/lib/proto/feature/strategy_pb.js +712 -0
  156. package/lib/proto/feature/strategy_pb.mjs +803 -0
  157. package/lib/proto/feature/strategy_pb_service.d.ts +3 -0
  158. package/lib/proto/feature/strategy_pb_service.js +3 -0
  159. package/lib/proto/feature/strategy_pb_service.mjs +3 -0
  160. package/lib/proto/feature/target_pb.d.ts +31 -0
  161. package/lib/proto/feature/target_pb.js +207 -0
  162. package/lib/proto/feature/target_pb.mjs +232 -0
  163. package/lib/proto/feature/target_pb_service.d.ts +3 -0
  164. package/lib/proto/feature/target_pb_service.js +3 -0
  165. package/lib/proto/feature/target_pb_service.mjs +3 -0
  166. package/lib/proto/feature/variation_pb.d.ts +37 -0
  167. package/lib/proto/feature/variation_pb.js +233 -0
  168. package/lib/proto/feature/variation_pb.mjs +266 -0
  169. package/lib/proto/feature/variation_pb_service.d.ts +3 -0
  170. package/lib/proto/feature/variation_pb_service.js +3 -0
  171. package/lib/proto/feature/variation_pb_service.mjs +3 -0
  172. package/lib/proto/gateway/service_pb.d.ts +772 -0
  173. package/lib/proto/gateway/service_pb.js +5249 -0
  174. package/lib/proto/gateway/service_pb.mjs +6001 -0
  175. package/lib/proto/gateway/service_pb_service.d.ts +253 -0
  176. package/lib/proto/gateway/service_pb_service.js +436 -0
  177. package/lib/proto/gateway/service_pb_service.mjs +461 -0
  178. package/lib/proto/user/user_pb.d.ts +58 -0
  179. package/lib/proto/user/user_pb.js +410 -0
  180. package/lib/proto/user/user_pb.mjs +460 -0
  181. package/lib/proto/user/user_pb_service.d.ts +3 -0
  182. package/lib/proto/user/user_pb_service.js +3 -0
  183. package/lib/proto/user/user_pb_service.mjs +3 -0
  184. package/lib/protoc-gen-openapiv2/options/annotations_pb.d.ts +16 -0
  185. package/lib/protoc-gen-openapiv2/options/annotations_pb.js +100 -0
  186. package/lib/protoc-gen-openapiv2/options/annotations_pb.mjs +158 -0
  187. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.d.ts +3 -0
  188. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.js +3 -0
  189. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.mjs +3 -0
  190. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.d.ts +834 -0
  191. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.js +5456 -0
  192. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.mjs +6256 -0
  193. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.d.ts +3 -0
  194. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.js +3 -0
  195. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.mjs +3 -0
  196. package/lib/ruleEvaluator.d.ts +13 -0
  197. package/lib/ruleEvaluator.js +80 -0
  198. package/lib/ruleEvaluator.mjs +41 -0
  199. package/lib/segmentEvaluator.d.ts +7 -0
  200. package/lib/segmentEvaluator.js +74 -0
  201. package/lib/segmentEvaluator.mjs +34 -0
  202. package/lib/strategyEvaluator.d.ts +10 -0
  203. package/lib/strategyEvaluator.js +135 -0
  204. package/lib/strategyEvaluator.mjs +83 -0
  205. package/lib/userEvaluation.d.ts +8 -0
  206. package/lib/userEvaluation.js +70 -0
  207. package/lib/userEvaluation.mjs +60 -0
  208. package/package.json +46 -0
  209. package/release-please-config.json +22 -0
@@ -0,0 +1,3 @@
1
+ // package: grpc.gateway.protoc_gen_openapiv2.options
2
+ // file: protoc-gen-openapiv2/options/openapiv2.proto
3
+
@@ -0,0 +1,3 @@
1
+ // package: grpc.gateway.protoc_gen_openapiv2.options
2
+ // file: protoc-gen-openapiv2/options/openapiv2.proto
3
+ "use strict";
@@ -0,0 +1,3 @@
1
+ // package: grpc.gateway.protoc_gen_openapiv2.options
2
+ // file: protoc-gen-openapiv2/options/openapiv2.proto
3
+
@@ -0,0 +1,13 @@
1
+ import { Rule } from './proto/feature/rule_pb';
2
+ import { User } from './proto/user/user_pb';
3
+ import { SegmentUser } from './proto/feature/segment_pb';
4
+ declare class RuleEvaluator {
5
+ private clauseEvaluator;
6
+ constructor();
7
+ evaluate(rules: Rule[], user: User, segmentUsers: SegmentUser[], flagVariations: {
8
+ [key: string]: string;
9
+ }): Rule | null;
10
+ private evaluateRule;
11
+ private evaluateClause;
12
+ }
13
+ export { RuleEvaluator };
@@ -0,0 +1,80 @@
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 _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
5
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
8
+ 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); } }
9
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
10
+ function _defineProperty(e, r, t) { return (r = _toPropertyKey(r)) in e ? Object.defineProperty(e, r, { value: t, enumerable: !0, configurable: !0, writable: !0 }) : e[r] = t, e; }
11
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
12
+ 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); }
13
+ Object.defineProperty(exports, "__esModule", {
14
+ value: true
15
+ });
16
+ exports.RuleEvaluator = void 0;
17
+ var clauseEvaluator_1 = require("./clauseEvaluator");
18
+ //
19
+ var RuleEvaluator = /*#__PURE__*/function () {
20
+ function RuleEvaluator() {
21
+ _classCallCheck(this, RuleEvaluator);
22
+ _defineProperty(this, "clauseEvaluator", void 0);
23
+ this.clauseEvaluator = new clauseEvaluator_1.ClauseEvaluator();
24
+ }
25
+ return _createClass(RuleEvaluator, [{
26
+ key: "evaluate",
27
+ value: function evaluate(rules, user, segmentUsers, flagVariations) {
28
+ var _iterator = _createForOfIteratorHelper(rules),
29
+ _step;
30
+ try {
31
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
32
+ var rule = _step.value;
33
+ var matched = this.evaluateRule(rule, user, segmentUsers, flagVariations);
34
+ if (matched) {
35
+ return rule;
36
+ }
37
+ }
38
+ } catch (err) {
39
+ _iterator.e(err);
40
+ } finally {
41
+ _iterator.f();
42
+ }
43
+ return null;
44
+ }
45
+ }, {
46
+ key: "evaluateRule",
47
+ value: function evaluateRule(rule, user, segmentUsers, flagVariations) {
48
+ var _iterator2 = _createForOfIteratorHelper(rule.getClausesList()),
49
+ _step2;
50
+ try {
51
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
52
+ var clause = _step2.value;
53
+ var matched = this.evaluateClause(clause, user, segmentUsers, flagVariations);
54
+ if (!matched) {
55
+ return false;
56
+ }
57
+ }
58
+ } catch (err) {
59
+ _iterator2.e(err);
60
+ } finally {
61
+ _iterator2.f();
62
+ }
63
+ return true;
64
+ }
65
+ }, {
66
+ key: "evaluateClause",
67
+ value: function evaluateClause(clause, user, segmentUsers, flagVariations) {
68
+ var targetAttr;
69
+ if (clause.getAttribute() === 'id') {
70
+ targetAttr = user.getId();
71
+ } else {
72
+ targetAttr = user.getDataMap().get(clause.getAttribute());
73
+ }
74
+ return this.clauseEvaluator.evaluate(targetAttr || '',
75
+ // Handling the case where targetAttr is undefined
76
+ clause, user.getId(), segmentUsers, flagVariations);
77
+ }
78
+ }]);
79
+ }();
80
+ exports.RuleEvaluator = RuleEvaluator;
@@ -0,0 +1,41 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RuleEvaluator = void 0;
4
+ const clauseEvaluator_1 = require("./clauseEvaluator");
5
+ //
6
+ class RuleEvaluator {
7
+ clauseEvaluator;
8
+ constructor() {
9
+ this.clauseEvaluator = new clauseEvaluator_1.ClauseEvaluator();
10
+ }
11
+ evaluate(rules, user, segmentUsers, flagVariations) {
12
+ for (const rule of rules) {
13
+ const matched = this.evaluateRule(rule, user, segmentUsers, flagVariations);
14
+ if (matched) {
15
+ return rule;
16
+ }
17
+ }
18
+ return null;
19
+ }
20
+ evaluateRule(rule, user, segmentUsers, flagVariations) {
21
+ for (const clause of rule.getClausesList()) {
22
+ const matched = this.evaluateClause(clause, user, segmentUsers, flagVariations);
23
+ if (!matched) {
24
+ return false;
25
+ }
26
+ }
27
+ return true;
28
+ }
29
+ evaluateClause(clause, user, segmentUsers, flagVariations) {
30
+ let targetAttr;
31
+ if (clause.getAttribute() === 'id') {
32
+ targetAttr = user.getId();
33
+ }
34
+ else {
35
+ targetAttr = user.getDataMap().get(clause.getAttribute());
36
+ }
37
+ return this.clauseEvaluator.evaluate(targetAttr || '', // Handling the case where targetAttr is undefined
38
+ clause, user.getId(), segmentUsers, flagVariations);
39
+ }
40
+ }
41
+ exports.RuleEvaluator = RuleEvaluator;
@@ -0,0 +1,7 @@
1
+ import { SegmentUser } from './proto/feature/segment_pb';
2
+ declare class SegmentEvaluator {
3
+ evaluate(segmentIDs: string[], userID: string, segmentUsers: SegmentUser[]): boolean;
4
+ private findSegmentUser;
5
+ private containsSegmentUser;
6
+ }
7
+ export { SegmentEvaluator };
@@ -0,0 +1,74 @@
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 _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
5
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
8
+ 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); } }
9
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
10
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
11
+ 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); }
12
+ Object.defineProperty(exports, "__esModule", {
13
+ value: true
14
+ });
15
+ exports.SegmentEvaluator = void 0;
16
+ var segment_pb_1 = require("./proto/feature/segment_pb");
17
+ //
18
+ var SegmentEvaluator = /*#__PURE__*/function () {
19
+ function SegmentEvaluator() {
20
+ _classCallCheck(this, SegmentEvaluator);
21
+ }
22
+ return _createClass(SegmentEvaluator, [{
23
+ key: "evaluate",
24
+ value: function evaluate(segmentIDs, userID, segmentUsers) {
25
+ return this.findSegmentUser(segmentIDs, userID, segment_pb_1.SegmentUser.State.INCLUDED, segmentUsers);
26
+ }
27
+ }, {
28
+ key: "findSegmentUser",
29
+ value: function findSegmentUser(segmentIDs, userID, state, segmentUsers) {
30
+ var _iterator = _createForOfIteratorHelper(segmentIDs),
31
+ _step;
32
+ try {
33
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
34
+ var segmentID = _step.value;
35
+ if (!this.containsSegmentUser(segmentID, userID, state, segmentUsers)) {
36
+ return false;
37
+ }
38
+ }
39
+ } catch (err) {
40
+ _iterator.e(err);
41
+ } finally {
42
+ _iterator.f();
43
+ }
44
+ return true;
45
+ }
46
+ }, {
47
+ key: "containsSegmentUser",
48
+ value: function containsSegmentUser(segmentID, userID, state, segmentUsers) {
49
+ var _iterator2 = _createForOfIteratorHelper(segmentUsers),
50
+ _step2;
51
+ try {
52
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
53
+ var user = _step2.value;
54
+ if (user.getSegmentId() !== segmentID) {
55
+ continue;
56
+ }
57
+ if (user.getUserId() !== userID) {
58
+ continue;
59
+ }
60
+ if (user.getState() !== state) {
61
+ continue;
62
+ }
63
+ return true;
64
+ }
65
+ } catch (err) {
66
+ _iterator2.e(err);
67
+ } finally {
68
+ _iterator2.f();
69
+ }
70
+ return false;
71
+ }
72
+ }]);
73
+ }();
74
+ exports.SegmentEvaluator = SegmentEvaluator;
@@ -0,0 +1,34 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.SegmentEvaluator = void 0;
4
+ const segment_pb_1 = require("./proto/feature/segment_pb");
5
+ //
6
+ class SegmentEvaluator {
7
+ evaluate(segmentIDs, userID, segmentUsers) {
8
+ return this.findSegmentUser(segmentIDs, userID, segment_pb_1.SegmentUser.State.INCLUDED, segmentUsers);
9
+ }
10
+ findSegmentUser(segmentIDs, userID, state, segmentUsers) {
11
+ for (const segmentID of segmentIDs) {
12
+ if (!this.containsSegmentUser(segmentID, userID, state, segmentUsers)) {
13
+ return false;
14
+ }
15
+ }
16
+ return true;
17
+ }
18
+ containsSegmentUser(segmentID, userID, state, segmentUsers) {
19
+ for (const user of segmentUsers) {
20
+ if (user.getSegmentId() !== segmentID) {
21
+ continue;
22
+ }
23
+ if (user.getUserId() !== userID) {
24
+ continue;
25
+ }
26
+ if (user.getState() !== state) {
27
+ continue;
28
+ }
29
+ return true;
30
+ }
31
+ return false;
32
+ }
33
+ }
34
+ exports.SegmentEvaluator = SegmentEvaluator;
@@ -0,0 +1,10 @@
1
+ import { Strategy } from './proto/feature/strategy_pb';
2
+ import { Variation } from './proto/feature/variation_pb';
3
+ declare class StrategyEvaluator {
4
+ evaluate(strategy: Strategy, userID: string, variations: Variation[], featureID: string, samplingSeed: string): Variation;
5
+ private rollout;
6
+ private bucket;
7
+ private hash;
8
+ private findVariation;
9
+ }
10
+ export { StrategyEvaluator };
@@ -0,0 +1,135 @@
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 _createForOfIteratorHelper(r, e) { var t = "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (!t) { if (Array.isArray(r) || (t = _unsupportedIterableToArray(r)) || e && r && "number" == typeof r.length) { t && (r = t); var _n = 0, F = function F() {}; return { s: F, n: function n() { return _n >= r.length ? { done: !0 } : { done: !1, value: r[_n++] }; }, e: function e(r) { throw r; }, f: F }; } throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); } var o, a = !0, u = !1; return { s: function s() { t = t.call(r); }, n: function n() { var r = t.next(); return a = r.done, r; }, e: function e(r) { u = !0, o = r; }, f: function f() { try { a || null == t["return"] || t["return"](); } finally { if (u) throw o; } } }; }
5
+ function _unsupportedIterableToArray(r, a) { if (r) { if ("string" == typeof r) return _arrayLikeToArray(r, a); var t = {}.toString.call(r).slice(8, -1); return "Object" === t && r.constructor && (t = r.constructor.name), "Map" === t || "Set" === t ? Array.from(r) : "Arguments" === t || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(t) ? _arrayLikeToArray(r, a) : void 0; } }
6
+ function _arrayLikeToArray(r, a) { (null == a || a > r.length) && (a = r.length); for (var e = 0, n = Array(a); e < a; e++) n[e] = r[e]; return n; }
7
+ function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
8
+ 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); } }
9
+ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r), t && _defineProperties(e, t), Object.defineProperty(e, "prototype", { writable: !1 }), e; }
10
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
11
+ 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); }
12
+ var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
13
+ if (k2 === undefined) k2 = k;
14
+ var desc = Object.getOwnPropertyDescriptor(m, k);
15
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
16
+ desc = {
17
+ enumerable: true,
18
+ get: function get() {
19
+ return m[k];
20
+ }
21
+ };
22
+ }
23
+ Object.defineProperty(o, k2, desc);
24
+ } : function (o, m, k, k2) {
25
+ if (k2 === undefined) k2 = k;
26
+ o[k2] = m[k];
27
+ });
28
+ var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) {
29
+ Object.defineProperty(o, "default", {
30
+ enumerable: true,
31
+ value: v
32
+ });
33
+ } : function (o, v) {
34
+ o["default"] = v;
35
+ });
36
+ var __importStar = void 0 && (void 0).__importStar || function (mod) {
37
+ if (mod && mod.__esModule) return mod;
38
+ var result = {};
39
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
40
+ __setModuleDefault(result, mod);
41
+ return result;
42
+ };
43
+ Object.defineProperty(exports, "__esModule", {
44
+ value: true
45
+ });
46
+ exports.StrategyEvaluator = void 0;
47
+ var crypto = __importStar(require("crypto"));
48
+ var strategy_pb_1 = require("./proto/feature/strategy_pb");
49
+ //
50
+ var MAX = 0xffffffffffffffffn;
51
+ var StrategyEvaluator = /*#__PURE__*/function () {
52
+ function StrategyEvaluator() {
53
+ _classCallCheck(this, StrategyEvaluator);
54
+ }
55
+ return _createClass(StrategyEvaluator, [{
56
+ key: "evaluate",
57
+ value: function evaluate(strategy, userID, variations, featureID, samplingSeed) {
58
+ var _strategy$getFixedStr;
59
+ switch (strategy.getType()) {
60
+ case strategy_pb_1.Strategy.Type.FIXED:
61
+ return this.findVariation(((_strategy$getFixedStr = strategy.getFixedStrategy()) === null || _strategy$getFixedStr === void 0 ? void 0 : _strategy$getFixedStr.getVariation()) || '', variations);
62
+ case strategy_pb_1.Strategy.Type.ROLLOUT:
63
+ var rolloutStrategy = strategy.getRolloutStrategy();
64
+ if (rolloutStrategy !== undefined) {
65
+ var variationID = this.rollout(rolloutStrategy, userID, featureID, samplingSeed);
66
+ return this.findVariation(variationID, variations);
67
+ }
68
+ throw new Error('Missing rollout strategy');
69
+ default:
70
+ throw new Error('Unsupported strategy');
71
+ }
72
+ }
73
+ }, {
74
+ key: "rollout",
75
+ value: function rollout(strategy, userID, featureID, samplingSeed) {
76
+ var bucket = this.bucket(userID, featureID, samplingSeed);
77
+ var sum = 0.0;
78
+ var _iterator = _createForOfIteratorHelper(strategy.getVariationsList()),
79
+ _step;
80
+ try {
81
+ for (_iterator.s(); !(_step = _iterator.n()).done;) {
82
+ var variation = _step.value;
83
+ sum += variation.getWeight() / 100000.0;
84
+ if (bucket < sum) {
85
+ return variation.getVariation();
86
+ }
87
+ }
88
+ } catch (err) {
89
+ _iterator.e(err);
90
+ } finally {
91
+ _iterator.f();
92
+ }
93
+ throw new Error('Variation not found');
94
+ }
95
+ }, {
96
+ key: "bucket",
97
+ value: function bucket(userID, featureID, samplingSeed) {
98
+ try {
99
+ var hash = this.hash(userID, featureID, samplingSeed);
100
+ var intVal = BigInt('0x' + hash.slice(0, 16)); // Convert the first 16 hex characters to BigInt
101
+ // Divide the BigInt value by `max` and convert it to a number. Use Number() since we need a float.
102
+ return Number(intVal) / Number(MAX);
103
+ } catch (error) {
104
+ console.error('Failed to calculate bucket value:', error);
105
+ throw error;
106
+ }
107
+ }
108
+ }, {
109
+ key: "hash",
110
+ value: function hash(userID, featureID, samplingSeed) {
111
+ var concat = "".concat(featureID, "-").concat(userID).concat(samplingSeed);
112
+ return crypto.createHash('md5').update(concat).digest('hex');
113
+ }
114
+ }, {
115
+ key: "findVariation",
116
+ value: function findVariation(variationID, variations) {
117
+ var _iterator2 = _createForOfIteratorHelper(variations),
118
+ _step2;
119
+ try {
120
+ for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
121
+ var variation = _step2.value;
122
+ if (variation.getId() === variationID) {
123
+ return variation;
124
+ }
125
+ }
126
+ } catch (err) {
127
+ _iterator2.e(err);
128
+ } finally {
129
+ _iterator2.f();
130
+ }
131
+ throw new Error('Variation not found');
132
+ }
133
+ }]);
134
+ }();
135
+ exports.StrategyEvaluator = StrategyEvaluator;
@@ -0,0 +1,83 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || function (mod) {
19
+ if (mod && mod.__esModule) return mod;
20
+ var result = {};
21
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
22
+ __setModuleDefault(result, mod);
23
+ return result;
24
+ };
25
+ Object.defineProperty(exports, "__esModule", { value: true });
26
+ exports.StrategyEvaluator = void 0;
27
+ const crypto = __importStar(require("crypto"));
28
+ const strategy_pb_1 = require("./proto/feature/strategy_pb");
29
+ //
30
+ const MAX = 0xffffffffffffffffn;
31
+ class StrategyEvaluator {
32
+ evaluate(strategy, userID, variations, featureID, samplingSeed) {
33
+ switch (strategy.getType()) {
34
+ case strategy_pb_1.Strategy.Type.FIXED:
35
+ return this.findVariation(strategy.getFixedStrategy()?.getVariation() || '', variations);
36
+ case strategy_pb_1.Strategy.Type.ROLLOUT:
37
+ const rolloutStrategy = strategy.getRolloutStrategy();
38
+ if (rolloutStrategy !== undefined) {
39
+ const variationID = this.rollout(rolloutStrategy, userID, featureID, samplingSeed);
40
+ return this.findVariation(variationID, variations);
41
+ }
42
+ throw new Error('Missing rollout strategy');
43
+ default:
44
+ throw new Error('Unsupported strategy');
45
+ }
46
+ }
47
+ rollout(strategy, userID, featureID, samplingSeed) {
48
+ const bucket = this.bucket(userID, featureID, samplingSeed);
49
+ let sum = 0.0;
50
+ for (const variation of strategy.getVariationsList()) {
51
+ sum += variation.getWeight() / 100000.0;
52
+ if (bucket < sum) {
53
+ return variation.getVariation();
54
+ }
55
+ }
56
+ throw new Error('Variation not found');
57
+ }
58
+ bucket(userID, featureID, samplingSeed) {
59
+ try {
60
+ const hash = this.hash(userID, featureID, samplingSeed);
61
+ const intVal = BigInt('0x' + hash.slice(0, 16)); // Convert the first 16 hex characters to BigInt
62
+ // Divide the BigInt value by `max` and convert it to a number. Use Number() since we need a float.
63
+ return Number(intVal) / Number(MAX);
64
+ }
65
+ catch (error) {
66
+ console.error('Failed to calculate bucket value:', error);
67
+ throw error;
68
+ }
69
+ }
70
+ hash(userID, featureID, samplingSeed) {
71
+ const concat = `${featureID}-${userID}${samplingSeed}`;
72
+ return crypto.createHash('md5').update(concat).digest('hex');
73
+ }
74
+ findVariation(variationID, variations) {
75
+ for (const variation of variations) {
76
+ if (variation.getId() === variationID) {
77
+ return variation;
78
+ }
79
+ }
80
+ throw new Error('Variation not found');
81
+ }
82
+ }
83
+ exports.StrategyEvaluator = StrategyEvaluator;
@@ -0,0 +1,8 @@
1
+ import { Evaluation, UserEvaluations } from './proto/feature/evaluation_pb';
2
+ import { Feature } from './proto/feature/feature_pb';
3
+ declare function NewUserEvaluations(id: string, evaluations: Evaluation[], archivedFeaturesIds: string[], forceUpdate: boolean): UserEvaluations;
4
+ declare function sortMapKeys(data: Record<string, string>): string[];
5
+ declare function GenerateFeaturesID(features: Feature[]): string;
6
+ declare function UserEvaluationsID(userID: string, userMetadata: Record<string, string>, // equivalent to map[string]string in Go
7
+ features: Feature[]): string;
8
+ export { UserEvaluationsID, GenerateFeaturesID, sortMapKeys, NewUserEvaluations };
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+
3
+ var __importDefault = void 0 && (void 0).__importDefault || function (mod) {
4
+ return mod && mod.__esModule ? mod : {
5
+ "default": mod
6
+ };
7
+ };
8
+ Object.defineProperty(exports, "__esModule", {
9
+ value: true
10
+ });
11
+ exports.UserEvaluationsID = UserEvaluationsID;
12
+ exports.GenerateFeaturesID = GenerateFeaturesID;
13
+ exports.sortMapKeys = sortMapKeys;
14
+ exports.NewUserEvaluations = NewUserEvaluations;
15
+ var evaluation_pb_1 = require("./proto/feature/evaluation_pb");
16
+ var fnv_plus_1 = __importDefault(require("fnv-plus"));
17
+ //
18
+ function NewUserEvaluations(id, evaluations, archivedFeaturesIds, forceUpdate) {
19
+ var now = Math.floor(Date.now() / 1000); // Equivalent to Unix time
20
+ var userEvaluations = new evaluation_pb_1.UserEvaluations();
21
+ userEvaluations.setId(id);
22
+ userEvaluations.setEvaluationsList(evaluations);
23
+ userEvaluations.setCreatedAt(now);
24
+ userEvaluations.setArchivedFeatureIdsList(archivedFeaturesIds);
25
+ userEvaluations.setForceUpdate(forceUpdate);
26
+ return userEvaluations;
27
+ }
28
+ function sortMapKeys(data) {
29
+ var keys = Object.keys(data);
30
+ keys.sort(); // Sort keys alphabetically
31
+ return keys;
32
+ }
33
+ function GenerateFeaturesID(features) {
34
+ // Sort features based on the 'id'
35
+ features.sort(function (a, b) {
36
+ return a.getId() < b.getId() ? -1 : 1;
37
+ });
38
+ // Initialize FNV-1a 64-bit hash string
39
+ var hashInput = '';
40
+ // Concatenate each feature's 'id' and 'version' into the hash input
41
+ features.forEach(function (feature) {
42
+ hashInput += "".concat(feature.getId(), ":").concat(feature.getVersion());
43
+ });
44
+ // Generate the FNV-1a 64-bit hash and return it as a decimal string
45
+ var hash = fnv_plus_1["default"].hash(hashInput, 64);
46
+ return hash.dec();
47
+ }
48
+ function UserEvaluationsID(userID, userMetadata,
49
+ // equivalent to map[string]string in Go
50
+ features) {
51
+ // Sort features by ID
52
+ features.sort(function (a, b) {
53
+ return a.getId() < b.getId() ? -1 : 1;
54
+ });
55
+ // Initialize FNV-1a 64-bit hash input
56
+ var hashInput = userID;
57
+ // Sort and append userMetadata to the hash input
58
+ var keys = sortMapKeys(userMetadata);
59
+ keys.forEach(function (key) {
60
+ hashInput += "".concat(key, ":").concat(userMetadata[key]);
61
+ });
62
+ // Append feature details to the hash input
63
+ features.forEach(function (feature) {
64
+ hashInput += "".concat(feature.getId(), ":").concat(feature.getVersion());
65
+ });
66
+ // Generate the FNV-1a 64-bit hash
67
+ var hash = fnv_plus_1["default"].hash(hashInput, 64);
68
+ // Return the hashed value as a decimal string
69
+ return hash.dec();
70
+ }
@@ -0,0 +1,60 @@
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.UserEvaluationsID = UserEvaluationsID;
7
+ exports.GenerateFeaturesID = GenerateFeaturesID;
8
+ exports.sortMapKeys = sortMapKeys;
9
+ exports.NewUserEvaluations = NewUserEvaluations;
10
+ const evaluation_pb_1 = require("./proto/feature/evaluation_pb");
11
+ const fnv_plus_1 = __importDefault(require("fnv-plus"));
12
+ //
13
+ function NewUserEvaluations(id, evaluations, archivedFeaturesIds, forceUpdate) {
14
+ const now = Math.floor(Date.now() / 1000); // Equivalent to Unix time
15
+ const userEvaluations = new evaluation_pb_1.UserEvaluations();
16
+ userEvaluations.setId(id);
17
+ userEvaluations.setEvaluationsList(evaluations);
18
+ userEvaluations.setCreatedAt(now);
19
+ userEvaluations.setArchivedFeatureIdsList(archivedFeaturesIds);
20
+ userEvaluations.setForceUpdate(forceUpdate);
21
+ return userEvaluations;
22
+ }
23
+ function sortMapKeys(data) {
24
+ const keys = Object.keys(data);
25
+ keys.sort(); // Sort keys alphabetically
26
+ return keys;
27
+ }
28
+ function GenerateFeaturesID(features) {
29
+ // Sort features based on the 'id'
30
+ features.sort((a, b) => (a.getId() < b.getId() ? -1 : 1));
31
+ // Initialize FNV-1a 64-bit hash string
32
+ let hashInput = '';
33
+ // Concatenate each feature's 'id' and 'version' into the hash input
34
+ features.forEach((feature) => {
35
+ hashInput += `${feature.getId()}:${feature.getVersion()}`;
36
+ });
37
+ // Generate the FNV-1a 64-bit hash and return it as a decimal string
38
+ const hash = fnv_plus_1.default.hash(hashInput, 64);
39
+ return hash.dec();
40
+ }
41
+ function UserEvaluationsID(userID, userMetadata, // equivalent to map[string]string in Go
42
+ features) {
43
+ // Sort features by ID
44
+ features.sort((a, b) => (a.getId() < b.getId() ? -1 : 1));
45
+ // Initialize FNV-1a 64-bit hash input
46
+ let hashInput = userID;
47
+ // Sort and append userMetadata to the hash input
48
+ const keys = sortMapKeys(userMetadata);
49
+ keys.forEach((key) => {
50
+ hashInput += `${key}:${userMetadata[key]}`;
51
+ });
52
+ // Append feature details to the hash input
53
+ features.forEach((feature) => {
54
+ hashInput += `${feature.getId()}:${feature.getVersion()}`;
55
+ });
56
+ // Generate the FNV-1a 64-bit hash
57
+ const hash = fnv_plus_1.default.hash(hashInput, 64);
58
+ // Return the hashed value as a decimal string
59
+ return hash.dec();
60
+ }