@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.
Files changed (196) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/README.md +36 -6
  3. package/lib/bucketeer.d.ts +6 -0
  4. package/lib/bucketeer.js +65 -0
  5. package/lib/bucketeer.mjs +38 -0
  6. package/lib/clauseEvaluator.js +49 -7
  7. package/lib/clauseEvaluator.mjs +41 -7
  8. package/lib/evaluation.d.ts +10 -1
  9. package/lib/evaluation.js +184 -27
  10. package/lib/evaluation.mjs +141 -10
  11. package/lib/index.d.ts +12 -10
  12. package/lib/index.js +61 -40
  13. package/lib/index.mjs +16 -10
  14. package/lib/modelFactory.d.ts +1 -0
  15. package/lib/modelFactory.js +2 -0
  16. package/lib/modelFactory.mjs +2 -0
  17. package/lib/proto/event/client/event_pb.d.ts +19 -9
  18. package/lib/proto/event/client/event_pb.js +22 -12
  19. package/lib/proto/event/client/event_pb.mjs +100 -90
  20. package/lib/proto/feature/clause_pb.d.ts +2 -1
  21. package/lib/proto/feature/clause_pb.js +3 -2
  22. package/lib/proto/feature/clause_pb.mjs +7 -6
  23. package/lib/proto/feature/evaluation_pb.d.ts +3 -3
  24. package/lib/proto/feature/evaluation_pb.js +1 -1
  25. package/lib/proto/feature/evaluation_pb.mjs +15 -15
  26. package/lib/proto/feature/feature_last_used_info_pb.d.ts +10 -1
  27. package/lib/proto/feature/feature_last_used_info_pb.js +12 -1
  28. package/lib/proto/feature/feature_last_used_info_pb.mjs +18 -7
  29. package/lib/proto/feature/feature_pb.d.ts +72 -7
  30. package/lib/proto/feature/feature_pb.js +446 -4
  31. package/lib/proto/feature/feature_pb.mjs +535 -29
  32. package/lib/proto/feature/prerequisite_pb.d.ts +1 -1
  33. package/lib/proto/feature/prerequisite_pb.js +1 -1
  34. package/lib/proto/feature/prerequisite_pb.mjs +3 -3
  35. package/lib/proto/feature/reason_pb.d.ts +8 -1
  36. package/lib/proto/feature/reason_pb.js +9 -2
  37. package/lib/proto/feature/reason_pb.mjs +11 -4
  38. package/lib/proto/feature/rule_pb.d.ts +3 -3
  39. package/lib/proto/feature/rule_pb.js +1 -1
  40. package/lib/proto/feature/rule_pb.mjs +4 -4
  41. package/lib/proto/feature/segment_pb.d.ts +3 -3
  42. package/lib/proto/feature/segment_pb.js +1 -1
  43. package/lib/proto/feature/segment_pb.mjs +22 -22
  44. package/lib/proto/feature/strategy_pb.d.ts +31 -1
  45. package/lib/proto/feature/strategy_pb.js +206 -2
  46. package/lib/proto/feature/strategy_pb.mjs +242 -9
  47. package/lib/proto/feature/target_pb.d.ts +1 -1
  48. package/lib/proto/feature/target_pb.js +1 -1
  49. package/lib/proto/feature/target_pb.mjs +3 -3
  50. package/lib/proto/feature/variation_pb.d.ts +1 -1
  51. package/lib/proto/feature/variation_pb.js +1 -1
  52. package/lib/proto/feature/variation_pb.mjs +5 -5
  53. package/lib/proto/user/user_pb.d.ts +53 -1
  54. package/lib/proto/user/user_pb.js +374 -1
  55. package/lib/proto/user/user_pb.mjs +427 -7
  56. package/lib/strategyEvaluator.d.ts +0 -2
  57. package/lib/strategyEvaluator.js +23 -57
  58. package/lib/strategyEvaluator.mjs +23 -46
  59. package/lib/userEvaluation.js +13 -3
  60. package/lib/userEvaluation.mjs +13 -3
  61. package/package.json +15 -8
  62. package/lib/google/api/annotations_pb.d.ts +0 -8
  63. package/lib/google/api/annotations_pb.js +0 -40
  64. package/lib/google/api/annotations_pb.mjs +0 -54
  65. package/lib/google/api/annotations_pb_service.d.ts +0 -3
  66. package/lib/google/api/annotations_pb_service.js +0 -3
  67. package/lib/google/api/annotations_pb_service.mjs +0 -3
  68. package/lib/google/api/http_pb.d.ts +0 -132
  69. package/lib/google/api/http_pb.js +0 -860
  70. package/lib/google/api/http_pb.mjs +0 -982
  71. package/lib/google/api/http_pb_service.d.ts +0 -3
  72. package/lib/google/api/http_pb_service.js +0 -3
  73. package/lib/google/api/http_pb_service.mjs +0 -3
  74. package/lib/google/rpc/code_pb.d.ts +0 -26
  75. package/lib/google/rpc/code_pb.js +0 -44
  76. package/lib/google/rpc/code_pb.mjs +0 -48
  77. package/lib/google/rpc/code_pb_service.d.ts +0 -3
  78. package/lib/google/rpc/code_pb_service.js +0 -3
  79. package/lib/google/rpc/code_pb_service.mjs +0 -3
  80. package/lib/google/rpc/error_details_pb.d.ts +0 -322
  81. package/lib/google/rpc/error_details_pb.js +0 -2220
  82. package/lib/google/rpc/error_details_pb.mjs +0 -2499
  83. package/lib/google/rpc/error_details_pb_service.d.ts +0 -3
  84. package/lib/google/rpc/error_details_pb_service.js +0 -3
  85. package/lib/google/rpc/error_details_pb_service.mjs +0 -3
  86. package/lib/google/rpc/status_pb.d.ts +0 -36
  87. package/lib/google/rpc/status_pb.js +0 -235
  88. package/lib/google/rpc/status_pb.mjs +0 -268
  89. package/lib/google/rpc/status_pb_service.d.ts +0 -3
  90. package/lib/google/rpc/status_pb_service.js +0 -3
  91. package/lib/google/rpc/status_pb_service.mjs +0 -3
  92. package/lib/proto/event/client/event_pb_service.d.ts +0 -3
  93. package/lib/proto/event/client/event_pb_service.js +0 -3
  94. package/lib/proto/event/client/event_pb_service.mjs +0 -3
  95. package/lib/proto/event/domain/event_pb.d.ts +0 -4518
  96. package/lib/proto/event/domain/event_pb.js +0 -10834
  97. package/lib/proto/event/domain/event_pb.mjs +0 -33315
  98. package/lib/proto/event/domain/event_pb_service.d.ts +0 -3
  99. package/lib/proto/event/domain/event_pb_service.js +0 -3
  100. package/lib/proto/event/domain/event_pb_service.mjs +0 -3
  101. package/lib/proto/event/domain/localized_message_pb.d.ts +0 -29
  102. package/lib/proto/event/domain/localized_message_pb.js +0 -183
  103. package/lib/proto/event/domain/localized_message_pb.mjs +0 -206
  104. package/lib/proto/event/domain/localized_message_pb_service.d.ts +0 -3
  105. package/lib/proto/event/domain/localized_message_pb_service.js +0 -3
  106. package/lib/proto/event/domain/localized_message_pb_service.mjs +0 -3
  107. package/lib/proto/event/service/feature_pb.d.ts +0 -44
  108. package/lib/proto/event/service/feature_pb.js +0 -277
  109. package/lib/proto/event/service/feature_pb.mjs +0 -319
  110. package/lib/proto/event/service/feature_pb_service.d.ts +0 -3
  111. package/lib/proto/event/service/feature_pb_service.js +0 -3
  112. package/lib/proto/event/service/feature_pb_service.mjs +0 -3
  113. package/lib/proto/event/service/segment_pb.d.ts +0 -51
  114. package/lib/proto/event/service/segment_pb.js +0 -324
  115. package/lib/proto/event/service/segment_pb.mjs +0 -375
  116. package/lib/proto/event/service/segment_pb_service.d.ts +0 -3
  117. package/lib/proto/event/service/segment_pb_service.js +0 -3
  118. package/lib/proto/event/service/segment_pb_service.mjs +0 -3
  119. package/lib/proto/event/service/user_pb.d.ts +0 -49
  120. package/lib/proto/event/service/user_pb.js +0 -315
  121. package/lib/proto/event/service/user_pb.mjs +0 -362
  122. package/lib/proto/event/service/user_pb_service.d.ts +0 -3
  123. package/lib/proto/event/service/user_pb_service.js +0 -3
  124. package/lib/proto/event/service/user_pb_service.mjs +0 -3
  125. package/lib/proto/feature/clause_pb_service.d.ts +0 -3
  126. package/lib/proto/feature/clause_pb_service.js +0 -3
  127. package/lib/proto/feature/clause_pb_service.mjs +0 -3
  128. package/lib/proto/feature/command_pb.d.ts +0 -1213
  129. package/lib/proto/feature/command_pb.js +0 -8260
  130. package/lib/proto/feature/command_pb.mjs +0 -9275
  131. package/lib/proto/feature/command_pb_service.d.ts +0 -3
  132. package/lib/proto/feature/command_pb_service.js +0 -3
  133. package/lib/proto/feature/command_pb_service.mjs +0 -3
  134. package/lib/proto/feature/evaluation_pb_service.d.ts +0 -3
  135. package/lib/proto/feature/evaluation_pb_service.js +0 -3
  136. package/lib/proto/feature/evaluation_pb_service.mjs +0 -3
  137. package/lib/proto/feature/feature_last_used_info_pb_service.d.ts +0 -3
  138. package/lib/proto/feature/feature_last_used_info_pb_service.js +0 -3
  139. package/lib/proto/feature/feature_last_used_info_pb_service.mjs +0 -3
  140. package/lib/proto/feature/feature_pb_service.d.ts +0 -3
  141. package/lib/proto/feature/feature_pb_service.js +0 -3
  142. package/lib/proto/feature/feature_pb_service.mjs +0 -3
  143. package/lib/proto/feature/flag_trigger_pb.d.ts +0 -84
  144. package/lib/proto/feature/flag_trigger_pb.js +0 -452
  145. package/lib/proto/feature/flag_trigger_pb.mjs +0 -525
  146. package/lib/proto/feature/flag_trigger_pb_service.d.ts +0 -3
  147. package/lib/proto/feature/flag_trigger_pb_service.js +0 -3
  148. package/lib/proto/feature/flag_trigger_pb_service.mjs +0 -3
  149. package/lib/proto/feature/prerequisite_pb_service.d.ts +0 -3
  150. package/lib/proto/feature/prerequisite_pb_service.js +0 -3
  151. package/lib/proto/feature/prerequisite_pb_service.mjs +0 -3
  152. package/lib/proto/feature/reason_pb_service.d.ts +0 -3
  153. package/lib/proto/feature/reason_pb_service.js +0 -3
  154. package/lib/proto/feature/reason_pb_service.mjs +0 -3
  155. package/lib/proto/feature/rule_pb_service.d.ts +0 -3
  156. package/lib/proto/feature/rule_pb_service.js +0 -3
  157. package/lib/proto/feature/rule_pb_service.mjs +0 -3
  158. package/lib/proto/feature/segment_pb_service.d.ts +0 -3
  159. package/lib/proto/feature/segment_pb_service.js +0 -3
  160. package/lib/proto/feature/segment_pb_service.mjs +0 -3
  161. package/lib/proto/feature/service_pb.d.ts +0 -2158
  162. package/lib/proto/feature/service_pb.js +0 -5363
  163. package/lib/proto/feature/service_pb.mjs +0 -16348
  164. package/lib/proto/feature/service_pb_service.d.ts +0 -747
  165. package/lib/proto/feature/service_pb_service.js +0 -1424
  166. package/lib/proto/feature/service_pb_service.mjs +0 -1501
  167. package/lib/proto/feature/strategy_pb_service.d.ts +0 -3
  168. package/lib/proto/feature/strategy_pb_service.js +0 -3
  169. package/lib/proto/feature/strategy_pb_service.mjs +0 -3
  170. package/lib/proto/feature/target_pb_service.d.ts +0 -3
  171. package/lib/proto/feature/target_pb_service.js +0 -3
  172. package/lib/proto/feature/target_pb_service.mjs +0 -3
  173. package/lib/proto/feature/variation_pb_service.d.ts +0 -3
  174. package/lib/proto/feature/variation_pb_service.js +0 -3
  175. package/lib/proto/feature/variation_pb_service.mjs +0 -3
  176. package/lib/proto/gateway/service_pb.d.ts +0 -772
  177. package/lib/proto/gateway/service_pb.js +0 -5249
  178. package/lib/proto/gateway/service_pb.mjs +0 -6001
  179. package/lib/proto/gateway/service_pb_service.d.ts +0 -253
  180. package/lib/proto/gateway/service_pb_service.js +0 -436
  181. package/lib/proto/gateway/service_pb_service.mjs +0 -461
  182. package/lib/proto/user/user_pb_service.d.ts +0 -3
  183. package/lib/proto/user/user_pb_service.js +0 -3
  184. package/lib/proto/user/user_pb_service.mjs +0 -3
  185. package/lib/protoc-gen-openapiv2/options/annotations_pb.d.ts +0 -16
  186. package/lib/protoc-gen-openapiv2/options/annotations_pb.js +0 -100
  187. package/lib/protoc-gen-openapiv2/options/annotations_pb.mjs +0 -158
  188. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.d.ts +0 -3
  189. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.js +0 -3
  190. package/lib/protoc-gen-openapiv2/options/annotations_pb_service.mjs +0 -3
  191. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.d.ts +0 -834
  192. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.js +0 -5456
  193. package/lib/protoc-gen-openapiv2/options/openapiv2_pb.mjs +0 -6256
  194. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.d.ts +0 -3
  195. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.js +0 -3
  196. package/lib/protoc-gen-openapiv2/options/openapiv2_pb_service.mjs +0 -3
package/lib/evaluation.js CHANGED
@@ -20,7 +20,8 @@ function _arrayWithHoles(r) { if (Array.isArray(r)) return r; }
20
20
  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; } } }; }
21
21
  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; } }
22
22
  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; }
23
- function _regeneratorRuntime() { "use strict"; /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/facebook/regenerator/blob/main/LICENSE */ _regeneratorRuntime = function _regeneratorRuntime() { return e; }; var t, e = {}, r = Object.prototype, n = r.hasOwnProperty, o = Object.defineProperty || function (t, e, r) { t[e] = r.value; }, i = "function" == typeof Symbol ? Symbol : {}, a = i.iterator || "@@iterator", c = i.asyncIterator || "@@asyncIterator", u = i.toStringTag || "@@toStringTag"; function define(t, e, r) { return Object.defineProperty(t, e, { value: r, enumerable: !0, configurable: !0, writable: !0 }), t[e]; } try { define({}, ""); } catch (t) { define = function define(t, e, r) { return t[e] = r; }; } function wrap(t, e, r, n) { var i = e && e.prototype instanceof Generator ? e : Generator, a = Object.create(i.prototype), c = new Context(n || []); return o(a, "_invoke", { value: makeInvokeMethod(t, r, c) }), a; } function tryCatch(t, e, r) { try { return { type: "normal", arg: t.call(e, r) }; } catch (t) { return { type: "throw", arg: t }; } } e.wrap = wrap; var h = "suspendedStart", l = "suspendedYield", f = "executing", s = "completed", y = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} var p = {}; define(p, a, function () { return this; }); var d = Object.getPrototypeOf, v = d && d(d(values([]))); v && v !== r && n.call(v, a) && (p = v); var g = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(p); function defineIteratorMethods(t) { ["next", "throw", "return"].forEach(function (e) { define(t, e, function (t) { return this._invoke(e, t); }); }); } function AsyncIterator(t, e) { function invoke(r, o, i, a) { var c = tryCatch(t[r], t, o); if ("throw" !== c.type) { var u = c.arg, h = u.value; return h && "object" == _typeof(h) && n.call(h, "__await") ? e.resolve(h.__await).then(function (t) { invoke("next", t, i, a); }, function (t) { invoke("throw", t, i, a); }) : e.resolve(h).then(function (t) { u.value = t, i(u); }, function (t) { return invoke("throw", t, i, a); }); } a(c.arg); } var r; o(this, "_invoke", { value: function value(t, n) { function callInvokeWithMethodAndArg() { return new e(function (e, r) { invoke(t, n, e, r); }); } return r = r ? r.then(callInvokeWithMethodAndArg, callInvokeWithMethodAndArg) : callInvokeWithMethodAndArg(); } }); } function makeInvokeMethod(e, r, n) { var o = h; return function (i, a) { if (o === f) throw Error("Generator is already running"); if (o === s) { if ("throw" === i) throw a; return { value: t, done: !0 }; } for (n.method = i, n.arg = a;;) { var c = n.delegate; if (c) { var u = maybeInvokeDelegate(c, n); if (u) { if (u === y) continue; return u; } } if ("next" === n.method) n.sent = n._sent = n.arg;else if ("throw" === n.method) { if (o === h) throw o = s, n.arg; n.dispatchException(n.arg); } else "return" === n.method && n.abrupt("return", n.arg); o = f; var p = tryCatch(e, r, n); if ("normal" === p.type) { if (o = n.done ? s : l, p.arg === y) continue; return { value: p.arg, done: n.done }; } "throw" === p.type && (o = s, n.method = "throw", n.arg = p.arg); } }; } function maybeInvokeDelegate(e, r) { var n = r.method, o = e.iterator[n]; if (o === t) return r.delegate = null, "throw" === n && e.iterator["return"] && (r.method = "return", r.arg = t, maybeInvokeDelegate(e, r), "throw" === r.method) || "return" !== n && (r.method = "throw", r.arg = new TypeError("The iterator does not provide a '" + n + "' method")), y; var i = tryCatch(o, e.iterator, r.arg); if ("throw" === i.type) return r.method = "throw", r.arg = i.arg, r.delegate = null, y; var a = i.arg; return a ? a.done ? (r[e.resultName] = a.value, r.next = e.nextLoc, "return" !== r.method && (r.method = "next", r.arg = t), r.delegate = null, y) : a : (r.method = "throw", r.arg = new TypeError("iterator result is not an object"), r.delegate = null, y); } function pushTryEntry(t) { var e = { tryLoc: t[0] }; 1 in t && (e.catchLoc = t[1]), 2 in t && (e.finallyLoc = t[2], e.afterLoc = t[3]), this.tryEntries.push(e); } function resetTryEntry(t) { var e = t.completion || {}; e.type = "normal", delete e.arg, t.completion = e; } function Context(t) { this.tryEntries = [{ tryLoc: "root" }], t.forEach(pushTryEntry, this), this.reset(!0); } function values(e) { if (e || "" === e) { var r = e[a]; if (r) return r.call(e); if ("function" == typeof e.next) return e; if (!isNaN(e.length)) { var o = -1, i = function next() { for (; ++o < e.length;) if (n.call(e, o)) return next.value = e[o], next.done = !1, next; return next.value = t, next.done = !0, next; }; return i.next = i; } } throw new TypeError(_typeof(e) + " is not iterable"); } return GeneratorFunction.prototype = GeneratorFunctionPrototype, o(g, "constructor", { value: GeneratorFunctionPrototype, configurable: !0 }), o(GeneratorFunctionPrototype, "constructor", { value: GeneratorFunction, configurable: !0 }), GeneratorFunction.displayName = define(GeneratorFunctionPrototype, u, "GeneratorFunction"), e.isGeneratorFunction = function (t) { var e = "function" == typeof t && t.constructor; return !!e && (e === GeneratorFunction || "GeneratorFunction" === (e.displayName || e.name)); }, e.mark = function (t) { return Object.setPrototypeOf ? Object.setPrototypeOf(t, GeneratorFunctionPrototype) : (t.__proto__ = GeneratorFunctionPrototype, define(t, u, "GeneratorFunction")), t.prototype = Object.create(g), t; }, e.awrap = function (t) { return { __await: t }; }, defineIteratorMethods(AsyncIterator.prototype), define(AsyncIterator.prototype, c, function () { return this; }), e.AsyncIterator = AsyncIterator, e.async = function (t, r, n, o, i) { void 0 === i && (i = Promise); var a = new AsyncIterator(wrap(t, r, n, o), i); return e.isGeneratorFunction(r) ? a : a.next().then(function (t) { return t.done ? t.value : a.next(); }); }, defineIteratorMethods(g), define(g, u, "Generator"), define(g, a, function () { return this; }), define(g, "toString", function () { return "[object Generator]"; }), e.keys = function (t) { var e = Object(t), r = []; for (var n in e) r.push(n); return r.reverse(), function next() { for (; r.length;) { var t = r.pop(); if (t in e) return next.value = t, next.done = !1, next; } return next.done = !0, next; }; }, e.values = values, Context.prototype = { constructor: Context, reset: function reset(e) { if (this.prev = 0, this.next = 0, this.sent = this._sent = t, this.done = !1, this.delegate = null, this.method = "next", this.arg = t, this.tryEntries.forEach(resetTryEntry), !e) for (var r in this) "t" === r.charAt(0) && n.call(this, r) && !isNaN(+r.slice(1)) && (this[r] = t); }, stop: function stop() { this.done = !0; var t = this.tryEntries[0].completion; if ("throw" === t.type) throw t.arg; return this.rval; }, dispatchException: function dispatchException(e) { if (this.done) throw e; var r = this; function handle(n, o) { return a.type = "throw", a.arg = e, r.next = n, o && (r.method = "next", r.arg = t), !!o; } for (var o = this.tryEntries.length - 1; o >= 0; --o) { var i = this.tryEntries[o], a = i.completion; if ("root" === i.tryLoc) return handle("end"); if (i.tryLoc <= this.prev) { var c = n.call(i, "catchLoc"), u = n.call(i, "finallyLoc"); if (c && u) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } else if (c) { if (this.prev < i.catchLoc) return handle(i.catchLoc, !0); } else { if (!u) throw Error("try statement without catch or finally"); if (this.prev < i.finallyLoc) return handle(i.finallyLoc); } } } }, abrupt: function abrupt(t, e) { for (var r = this.tryEntries.length - 1; r >= 0; --r) { var o = this.tryEntries[r]; if (o.tryLoc <= this.prev && n.call(o, "finallyLoc") && this.prev < o.finallyLoc) { var i = o; break; } } i && ("break" === t || "continue" === t) && i.tryLoc <= e && e <= i.finallyLoc && (i = null); var a = i ? i.completion : {}; return a.type = t, a.arg = e, i ? (this.method = "next", this.next = i.finallyLoc, y) : this.complete(a); }, complete: function complete(t, e) { if ("throw" === t.type) throw t.arg; return "break" === t.type || "continue" === t.type ? this.next = t.arg : "return" === t.type ? (this.rval = this.arg = t.arg, this.method = "return", this.next = "end") : "normal" === t.type && e && (this.next = e), y; }, finish: function finish(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.finallyLoc === t) return this.complete(r.completion, r.afterLoc), resetTryEntry(r), y; } }, "catch": function _catch(t) { for (var e = this.tryEntries.length - 1; e >= 0; --e) { var r = this.tryEntries[e]; if (r.tryLoc === t) { var n = r.completion; if ("throw" === n.type) { var o = n.arg; resetTryEntry(r); } return o; } } throw Error("illegal catch attempt"); }, delegateYield: function delegateYield(e, r, n) { return this.delegate = { iterator: values(e), resultName: r, nextLoc: n }, "next" === this.method && (this.arg = t), y; } }, e; }
23
+ function _regenerator() { /*! regenerator-runtime -- Copyright (c) 2014-present, Facebook, Inc. -- license (MIT): https://github.com/babel/babel/blob/main/packages/babel-helpers/LICENSE */ var e, t, r = "function" == typeof Symbol ? Symbol : {}, n = r.iterator || "@@iterator", o = r.toStringTag || "@@toStringTag"; function i(r, n, o, i) { var c = n && n.prototype instanceof Generator ? n : Generator, u = Object.create(c.prototype); return _regeneratorDefine2(u, "_invoke", function (r, n, o) { var i, c, u, f = 0, p = o || [], y = !1, G = { p: 0, n: 0, v: e, a: d, f: d.bind(e, 4), d: function d(t, r) { return i = t, c = 0, u = e, G.n = r, a; } }; function d(r, n) { for (c = r, u = n, t = 0; !y && f && !o && t < p.length; t++) { var o, i = p[t], d = G.p, l = i[2]; r > 3 ? (o = l === n) && (u = i[(c = i[4]) ? 5 : (c = 3, 3)], i[4] = i[5] = e) : i[0] <= d && ((o = r < 2 && d < i[1]) ? (c = 0, G.v = n, G.n = i[1]) : d < l && (o = r < 3 || i[0] > n || n > l) && (i[4] = r, i[5] = n, G.n = l, c = 0)); } if (o || r > 1) return a; throw y = !0, n; } return function (o, p, l) { if (f > 1) throw TypeError("Generator is already running"); for (y && 1 === p && d(p, l), c = p, u = l; (t = c < 2 ? e : u) || !y;) { i || (c ? c < 3 ? (c > 1 && (G.n = -1), d(c, u)) : G.n = u : G.v = u); try { if (f = 2, i) { if (c || (o = "next"), t = i[o]) { if (!(t = t.call(i, u))) throw TypeError("iterator result is not an object"); if (!t.done) return t; u = t.value, c < 2 && (c = 0); } else 1 === c && (t = i["return"]) && t.call(i), c < 2 && (u = TypeError("The iterator does not provide a '" + o + "' method"), c = 1); i = e; } else if ((t = (y = G.n < 0) ? u : r.call(n, G)) !== a) break; } catch (t) { i = e, c = 1, u = t; } finally { f = 1; } } return { value: t, done: y }; }; }(r, o, i), !0), u; } var a = {}; function Generator() {} function GeneratorFunction() {} function GeneratorFunctionPrototype() {} t = Object.getPrototypeOf; var c = [][n] ? t(t([][n]())) : (_regeneratorDefine2(t = {}, n, function () { return this; }), t), u = GeneratorFunctionPrototype.prototype = Generator.prototype = Object.create(c); function f(e) { return Object.setPrototypeOf ? Object.setPrototypeOf(e, GeneratorFunctionPrototype) : (e.__proto__ = GeneratorFunctionPrototype, _regeneratorDefine2(e, o, "GeneratorFunction")), e.prototype = Object.create(u), e; } return GeneratorFunction.prototype = GeneratorFunctionPrototype, _regeneratorDefine2(u, "constructor", GeneratorFunctionPrototype), _regeneratorDefine2(GeneratorFunctionPrototype, "constructor", GeneratorFunction), GeneratorFunction.displayName = "GeneratorFunction", _regeneratorDefine2(GeneratorFunctionPrototype, o, "GeneratorFunction"), _regeneratorDefine2(u), _regeneratorDefine2(u, o, "Generator"), _regeneratorDefine2(u, n, function () { return this; }), _regeneratorDefine2(u, "toString", function () { return "[object Generator]"; }), (_regenerator = function _regenerator() { return { w: i, m: f }; })(); }
24
+ function _regeneratorDefine2(e, r, n, t) { var i = Object.defineProperty; try { i({}, "", {}); } catch (e) { i = 0; } _regeneratorDefine2 = function _regeneratorDefine(e, r, n, t) { function o(r, n) { _regeneratorDefine2(e, r, function (e) { return this._invoke(r, n, e); }); } r ? i ? i(e, r, { value: n, enumerable: !t, configurable: !t, writable: !t }) : e[r] = n : (o("next", 0), o("throw", 1), o("return", 2)); }, _regeneratorDefine2(e, r, n, t); }
24
25
  function asyncGeneratorStep(n, t, e, r, o, a, c) { try { var i = n[a](c), u = i.value; } catch (n) { return void e(n); } i.done ? t(u) : Promise.resolve(u).then(r, o); }
25
26
  function _asyncToGenerator(n) { return function () { var t = this, e = arguments; return new Promise(function (r, o) { var a = n.apply(t, e); function _next(n) { asyncGeneratorStep(a, r, o, _next, _throw, "next", n); } function _throw(n) { asyncGeneratorStep(a, r, o, _next, _throw, "throw", n); } _next(void 0); }); }; }
26
27
  function _classCallCheck(a, n) { if (!(a instanceof n)) throw new TypeError("Cannot call a class as a function"); }
@@ -29,20 +30,64 @@ function _createClass(e, r, t) { return r && _defineProperties(e.prototype, r),
29
30
  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; }
30
31
  function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : i + ""; }
31
32
  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); }
33
+ var __createBinding = void 0 && (void 0).__createBinding || (Object.create ? function (o, m, k, k2) {
34
+ if (k2 === undefined) k2 = k;
35
+ var desc = Object.getOwnPropertyDescriptor(m, k);
36
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
37
+ desc = {
38
+ enumerable: true,
39
+ get: function get() {
40
+ return m[k];
41
+ }
42
+ };
43
+ }
44
+ Object.defineProperty(o, k2, desc);
45
+ } : function (o, m, k, k2) {
46
+ if (k2 === undefined) k2 = k;
47
+ o[k2] = m[k];
48
+ });
49
+ var __setModuleDefault = void 0 && (void 0).__setModuleDefault || (Object.create ? function (o, v) {
50
+ Object.defineProperty(o, "default", {
51
+ enumerable: true,
52
+ value: v
53
+ });
54
+ } : function (o, v) {
55
+ o["default"] = v;
56
+ });
57
+ var __importStar = void 0 && (void 0).__importStar || function () {
58
+ var _ownKeys = function ownKeys(o) {
59
+ _ownKeys = Object.getOwnPropertyNames || function (o) {
60
+ var ar = [];
61
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
62
+ return ar;
63
+ };
64
+ return _ownKeys(o);
65
+ };
66
+ return function (mod) {
67
+ if (mod && mod.__esModule) return mod;
68
+ var result = {};
69
+ if (mod != null) for (var k = _ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
70
+ __setModuleDefault(result, mod);
71
+ return result;
72
+ };
73
+ }();
32
74
  Object.defineProperty(exports, "__esModule", {
33
75
  value: true
34
76
  });
35
77
  exports.Evaluator = void 0;
36
78
  exports.EvaluationID = EvaluationID;
79
+ exports.getFeatureIDsDependsOn = getFeatureIDsDependsOn;
37
80
  var errors_1 = require("./errors");
38
81
  var clause_pb_1 = require("./proto/feature/clause_pb");
39
82
  var evaluation_pb_1 = require("./proto/feature/evaluation_pb");
83
+ var feature_pb_1 = require("./proto/feature/feature_pb");
40
84
  var reason_pb_1 = require("./proto/feature/reason_pb");
41
85
  var variation_pb_1 = require("./proto/feature/variation_pb");
42
86
  var ruleEvaluator_1 = require("./ruleEvaluator");
43
87
  var strategyEvaluator_1 = require("./strategyEvaluator");
44
88
  var userEvaluation_1 = require("./userEvaluation");
45
89
  var modelFactory_1 = require("./modelFactory");
90
+ var yaml = __importStar(require("js-yaml"));
46
91
  var SECONDS_TO_RE_EVALUATE_ALL = 30 * 24 * 60 * 60; // 30 days
47
92
  var SECONDS_FOR_ADJUSTMENT = 10; // 10 seconds
48
93
  function EvaluationID(featureID, featureVersion, userID) {
@@ -53,20 +98,21 @@ var Evaluator = /*#__PURE__*/function () {
53
98
  _classCallCheck(this, Evaluator);
54
99
  _defineProperty(this, "ruleEvaluator", void 0);
55
100
  _defineProperty(this, "strategyEvaluator", void 0);
101
+ // variationCache caches YAML to JSON conversions using variation ID as the key.
102
+ // Since variation IDs are UUIDs, they are globally unique and safe to use as cache keys.
103
+ _defineProperty(this, "variationCache", void 0);
56
104
  this.ruleEvaluator = new ruleEvaluator_1.RuleEvaluator();
57
105
  this.strategyEvaluator = new strategyEvaluator_1.StrategyEvaluator();
106
+ this.variationCache = new Map();
58
107
  }
59
108
  return _createClass(Evaluator, [{
60
109
  key: "evaluateFeatures",
61
110
  value: function () {
62
- var _evaluateFeatures = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee(features, user, mapSegmentUsers, targetTag) {
63
- return _regeneratorRuntime().wrap(function _callee$(_context) {
64
- while (1) switch (_context.prev = _context.next) {
111
+ var _evaluateFeatures = _asyncToGenerator(/*#__PURE__*/_regenerator().m(function _callee(features, user, mapSegmentUsers, targetTag) {
112
+ return _regenerator().w(function (_context) {
113
+ while (1) switch (_context.n) {
65
114
  case 0:
66
- return _context.abrupt("return", this.evaluate(features, user, mapSegmentUsers, false, targetTag));
67
- case 1:
68
- case "end":
69
- return _context.stop();
115
+ return _context.a(2, this.evaluate(features, user, mapSegmentUsers, false, targetTag));
70
116
  }
71
117
  }, _callee, this);
72
118
  }));
@@ -129,13 +175,6 @@ var Evaluator = /*#__PURE__*/function () {
129
175
  try {
130
176
  for (_iterator2.s(); !(_step2 = _iterator2.n()).done;) {
131
177
  var feature = _step2.value;
132
- if (feature.getArchived()) {
133
- // To keep response size small, the feature flags archived long time ago are excluded.
134
- if (!this.isArchivedBeforeLastThirtyDays(feature)) {
135
- archivedIDs.push(feature.getId());
136
- }
137
- continue;
138
- }
139
178
  var segmentUsers = this.listSegmentIDs(feature).flatMap(function (id) {
140
179
  return mapSegmentUsers.get(id) || [];
141
180
  });
@@ -144,13 +183,23 @@ var Evaluator = /*#__PURE__*/function () {
144
183
  reason = _this$assignUser2[0],
145
184
  variation = _this$assignUser2[1];
146
185
  // VariationId is used to check if prerequisite flag's result is what user expects it to be.
186
+ // This must be set for ALL features (including archived) for dependency resolution to work
147
187
  flagVariations[feature.getId()] = variation.getId();
188
+ if (feature.getArchived()) {
189
+ // To keep response size small, the feature flags archived long time ago are excluded.
190
+ if (!this.isArchivedBeforeLastThirtyDays(feature)) {
191
+ archivedIDs.push(feature.getId());
192
+ }
193
+ continue;
194
+ }
148
195
  // When the tag is set in the request,
149
196
  // it will return only the evaluations of flags that match the tag configured on the dashboard.
150
197
  // When empty, it will return all the evaluations of the flags in the environment.
151
198
  if (targetTag !== '' && !this.tagExist(feature.getTagsList(), targetTag)) {
152
199
  continue;
153
200
  }
201
+ // Convert YAML to JSON for client SDKs if needed
202
+ var convertedValue = this.convertVariationValue(feature, variation);
154
203
  var evaluationID = EvaluationID(feature.getId(), feature.getVersion(), user.getId());
155
204
  var evaluation = new evaluation_pb_1.Evaluation();
156
205
  evaluation.setId(evaluationID);
@@ -159,7 +208,7 @@ var Evaluator = /*#__PURE__*/function () {
159
208
  evaluation.setUserId(user.getId());
160
209
  evaluation.setVariationId(variation.getId());
161
210
  evaluation.setVariationName(variation.getName());
162
- evaluation.setVariationValue(variation.getValue());
211
+ evaluation.setVariationValue(convertedValue);
163
212
  // Deprecated
164
213
  // FIXME: Remove the Variation when is no longer being used.
165
214
  // For security reasons, we should remove the variation description.
@@ -168,7 +217,7 @@ var Evaluator = /*#__PURE__*/function () {
168
217
  var copyVariation = new variation_pb_1.Variation();
169
218
  copyVariation.setId(variation.getId());
170
219
  copyVariation.setName(variation.getName());
171
- copyVariation.setValue(variation.getValue());
220
+ copyVariation.setValue(convertedValue);
172
221
  evaluation.setVariation(copyVariation);
173
222
  evaluation.setReason(reason);
174
223
  evaluations.push(evaluation);
@@ -334,6 +383,39 @@ var Evaluator = /*#__PURE__*/function () {
334
383
  }
335
384
  return variation;
336
385
  }
386
+ /**
387
+ * Converts YAML to JSON if needed, with in-memory caching.
388
+ * This ensures client SDKs can retrieve variation values using the object variation interface.
389
+ * Only performs conversion when the variation type is YAML.
390
+ * Cache key uses feature.updatedAt + variation.id to ensure cache invalidation when variations are updated.
391
+ */
392
+ }, {
393
+ key: "convertVariationValue",
394
+ value: function convertVariationValue(feature, variation) {
395
+ // Only convert if type is YAML
396
+ if (feature.getVariationType() !== feature_pb_1.Feature.VariationType.YAML) {
397
+ return variation.getValue();
398
+ }
399
+ // Cache key: {featureUpdatedAt}:{variationId}
400
+ // This ensures cache is invalidated when the feature (and its variations) are updated,
401
+ // including changes from auto operations that don't increment feature.version
402
+ var cacheKey = "".concat(feature.getUpdatedAt(), ":").concat(variation.getId());
403
+ // Check cache first
404
+ var cached = this.variationCache.get(cacheKey);
405
+ if (cached !== undefined) {
406
+ return cached;
407
+ }
408
+ // Convert YAML to JSON
409
+ try {
410
+ var jsonValue = yamlToJSON(variation.getValue());
411
+ // Cache the result for future requests
412
+ this.variationCache.set(cacheKey, jsonValue);
413
+ return jsonValue;
414
+ } catch (error) {
415
+ // Return original value as fallback on error
416
+ return variation.getValue();
417
+ }
418
+ }
337
419
  }]);
338
420
  }();
339
421
  exports.Evaluator = Evaluator;
@@ -344,7 +426,7 @@ var Mark;
344
426
  Mark[Mark["Permanently"] = 2] = "Permanently";
345
427
  })(Mark || (Mark = {}));
346
428
  // FeatureIDsDependsOn returns the ids of the features that this feature depends on.
347
- function featureIDsDependsOn(feature) {
429
+ function getFeatureIDsDependsOn(feature) {
348
430
  var ids = [];
349
431
  // Iterate over prerequisites and add their FeatureId
350
432
  feature.getPrerequisitesList().forEach(function (p) {
@@ -392,7 +474,7 @@ function topologicalSort(features) {
392
474
  throw new ErrCycleExists();
393
475
  }
394
476
  marks[fId] = Mark.Temporary;
395
- var dependentFeatureIds = featureIDsDependsOn(f);
477
+ var dependentFeatureIds = getFeatureIDsDependsOn(f);
396
478
  var _iterator8 = _createForOfIteratorHelper(dependentFeatureIds),
397
479
  _step8;
398
480
  try {
@@ -439,7 +521,7 @@ function getFeaturesDependedOnTargets(targets, all) {
439
521
  // Add feature to evals
440
522
  evals[f.getId()] = f;
441
523
  // Get dependent features recursively
442
- var featureDependencies = featureIDsDependsOn(f);
524
+ var featureDependencies = getFeatureIDsDependsOn(f);
443
525
  featureDependencies.forEach(function (fid) {
444
526
  var target = all.get(fid);
445
527
  if (target !== undefined) {
@@ -455,6 +537,24 @@ function getFeaturesDependedOnTargets(targets, all) {
455
537
  }
456
538
  // getFeaturesDependsOnTargets returns the features that depend on the target features.
457
539
  // targetFeatures are included in the result.
540
+ //
541
+ // This function ensures complete transitive closure for incremental evaluation.
542
+ //
543
+ // Example scenario:
544
+ // Feature Dependencies: A ← B ← C, A ← D, E ← D
545
+ // Target: [C] (recently updated)
546
+ //
547
+ // Step 1 - DFS finds direct/transitive dependents of targets:
548
+ // - A depends on B, B depends on C (target) → Add A, B
549
+ // - E depends on D, D doesn't depend on C → Skip E
550
+ // Result: {C, A, B}
551
+ //
552
+ // Step 2 - Find dependencies of discovered dependents:
553
+ // - A depends on D (new!) → Add D
554
+ // Result: {C, A, B, D}
555
+ //
556
+ // Without Step 2: Evaluating A would fail with "feature D not found"
557
+ // With Step 2: Complete closure ensures all dependencies are available
458
558
  function getFeaturesDependsOnTargets(targets, all) {
459
559
  var evals = {};
460
560
  // Mark target features in the evals map initially
@@ -466,12 +566,12 @@ function getFeaturesDependsOnTargets(targets, all) {
466
566
  if (evals[f.getId()]) {
467
567
  return true;
468
568
  }
469
- var featureDependencies = featureIDsDependsOn(f);
470
- var _iterator10 = _createForOfIteratorHelper(featureDependencies),
471
- _step10;
569
+ var featureDependencies = getFeatureIDsDependsOn(f);
570
+ var _iterator0 = _createForOfIteratorHelper(featureDependencies),
571
+ _step0;
472
572
  try {
473
- for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
474
- var fid = _step10.value;
573
+ for (_iterator0.s(); !(_step0 = _iterator0.n()).done;) {
574
+ var fid = _step0.value;
475
575
  var dependentFeature = all.get(fid);
476
576
  if (dependentFeature && _dfs2(dependentFeature)) {
477
577
  // If the feature depends on one of the target features, add it to evals
@@ -480,9 +580,9 @@ function getFeaturesDependsOnTargets(targets, all) {
480
580
  }
481
581
  }
482
582
  } catch (err) {
483
- _iterator10.e(err);
583
+ _iterator0.e(err);
484
584
  } finally {
485
- _iterator10.f();
585
+ _iterator0.f();
486
586
  }
487
587
  return false;
488
588
  };
@@ -490,6 +590,56 @@ function getFeaturesDependsOnTargets(targets, all) {
490
590
  all.forEach(function (f) {
491
591
  _dfs2(f);
492
592
  });
593
+ // Step 2: Ensure complete transitive closure
594
+ // The DFS above finds dependents (who depends on targets), but misses dependencies of those dependents.
595
+ // Example: If target C → dependent A → dependency D, we found A but missed D.
596
+ // Efficiently process only newly discovered features in each iteration.
597
+ var processed = new Set();
598
+ var queue = [];
599
+ for (var _i = 0, _Object$values = Object.values(evals); _i < _Object$values.length; _i++) {
600
+ var f = _Object$values[_i];
601
+ queue.push(f);
602
+ }
603
+ var maxIterations = 100; // Prevent infinite loops in case of circular dependencies
604
+ var iteration = 0;
605
+ while (queue.length > 0 && iteration < maxIterations) {
606
+ iteration++;
607
+ var nextQueue = [];
608
+ var _iterator1 = _createForOfIteratorHelper(queue),
609
+ _step1;
610
+ try {
611
+ for (_iterator1.s(); !(_step1 = _iterator1.n()).done;) {
612
+ var _f = _step1.value;
613
+ if (processed.has(_f.getId())) {
614
+ continue;
615
+ }
616
+ processed.add(_f.getId());
617
+ // Find dependencies of f
618
+ var featureDependencies = getFeatureIDsDependsOn(_f);
619
+ var _iterator10 = _createForOfIteratorHelper(featureDependencies),
620
+ _step10;
621
+ try {
622
+ for (_iterator10.s(); !(_step10 = _iterator10.n()).done;) {
623
+ var depID = _step10.value;
624
+ var dep = all.get(depID);
625
+ if (dep && !evals[depID]) {
626
+ evals[depID] = dep;
627
+ nextQueue.push(dep);
628
+ }
629
+ }
630
+ } catch (err) {
631
+ _iterator10.e(err);
632
+ } finally {
633
+ _iterator10.f();
634
+ }
635
+ }
636
+ } catch (err) {
637
+ _iterator1.e(err);
638
+ } finally {
639
+ _iterator1.f();
640
+ }
641
+ queue = nextQueue;
642
+ }
493
643
  return evals;
494
644
  }
495
645
  function arrayToRecord(arr) {
@@ -500,4 +650,11 @@ function arrayToRecord(arr) {
500
650
  acc[key] = value;
501
651
  return acc;
502
652
  }, {});
653
+ }
654
+ /**
655
+ * Converts a YAML string to a JSON string.
656
+ */
657
+ function yamlToJSON(yamlStr) {
658
+ var data = yaml.load(yamlStr);
659
+ return JSON.stringify(data);
503
660
  }
@@ -1,16 +1,52 @@
1
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 () {
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
+ })();
2
35
  Object.defineProperty(exports, "__esModule", { value: true });
3
36
  exports.Evaluator = void 0;
4
37
  exports.EvaluationID = EvaluationID;
38
+ exports.getFeatureIDsDependsOn = getFeatureIDsDependsOn;
5
39
  const errors_1 = require("./errors");
6
40
  const clause_pb_1 = require("./proto/feature/clause_pb");
7
41
  const evaluation_pb_1 = require("./proto/feature/evaluation_pb");
42
+ const feature_pb_1 = require("./proto/feature/feature_pb");
8
43
  const reason_pb_1 = require("./proto/feature/reason_pb");
9
44
  const variation_pb_1 = require("./proto/feature/variation_pb");
10
45
  const ruleEvaluator_1 = require("./ruleEvaluator");
11
46
  const strategyEvaluator_1 = require("./strategyEvaluator");
12
47
  const userEvaluation_1 = require("./userEvaluation");
13
48
  const modelFactory_1 = require("./modelFactory");
49
+ const yaml = __importStar(require("js-yaml"));
14
50
  const SECONDS_TO_RE_EVALUATE_ALL = 30 * 24 * 60 * 60; // 30 days
15
51
  const SECONDS_FOR_ADJUSTMENT = 10; // 10 seconds
16
52
  function EvaluationID(featureID, featureVersion, userID) {
@@ -19,9 +55,13 @@ function EvaluationID(featureID, featureVersion, userID) {
19
55
  class Evaluator {
20
56
  ruleEvaluator;
21
57
  strategyEvaluator;
58
+ // variationCache caches YAML to JSON conversions using variation ID as the key.
59
+ // Since variation IDs are UUIDs, they are globally unique and safe to use as cache keys.
60
+ variationCache;
22
61
  constructor() {
23
62
  this.ruleEvaluator = new ruleEvaluator_1.RuleEvaluator();
24
63
  this.strategyEvaluator = new strategyEvaluator_1.StrategyEvaluator();
64
+ this.variationCache = new Map();
25
65
  }
26
66
  async evaluateFeatures(features, user, mapSegmentUsers, targetTag) {
27
67
  return this.evaluate(features, user, mapSegmentUsers, false, targetTag);
@@ -61,6 +101,11 @@ class Evaluator {
61
101
  const evaluations = [];
62
102
  const archivedIDs = [];
63
103
  for (const feature of sortedFeatures) {
104
+ const segmentUsers = this.listSegmentIDs(feature).flatMap((id) => mapSegmentUsers.get(id) || []);
105
+ const [reason, variation] = this.assignUser(feature, user, segmentUsers, flagVariations);
106
+ // VariationId is used to check if prerequisite flag's result is what user expects it to be.
107
+ // This must be set for ALL features (including archived) for dependency resolution to work
108
+ flagVariations[feature.getId()] = variation.getId();
64
109
  if (feature.getArchived()) {
65
110
  // To keep response size small, the feature flags archived long time ago are excluded.
66
111
  if (!this.isArchivedBeforeLastThirtyDays(feature)) {
@@ -68,16 +113,14 @@ class Evaluator {
68
113
  }
69
114
  continue;
70
115
  }
71
- const segmentUsers = this.listSegmentIDs(feature).flatMap((id) => mapSegmentUsers.get(id) || []);
72
- const [reason, variation] = this.assignUser(feature, user, segmentUsers, flagVariations);
73
- // VariationId is used to check if prerequisite flag's result is what user expects it to be.
74
- flagVariations[feature.getId()] = variation.getId();
75
116
  // When the tag is set in the request,
76
117
  // it will return only the evaluations of flags that match the tag configured on the dashboard.
77
118
  // When empty, it will return all the evaluations of the flags in the environment.
78
119
  if (targetTag !== '' && !this.tagExist(feature.getTagsList(), targetTag)) {
79
120
  continue;
80
121
  }
122
+ // Convert YAML to JSON for client SDKs if needed
123
+ const convertedValue = this.convertVariationValue(feature, variation);
81
124
  const evaluationID = EvaluationID(feature.getId(), feature.getVersion(), user.getId());
82
125
  const evaluation = new evaluation_pb_1.Evaluation();
83
126
  evaluation.setId(evaluationID);
@@ -86,7 +129,7 @@ class Evaluator {
86
129
  evaluation.setUserId(user.getId());
87
130
  evaluation.setVariationId(variation.getId());
88
131
  evaluation.setVariationName(variation.getName());
89
- evaluation.setVariationValue(variation.getValue());
132
+ evaluation.setVariationValue(convertedValue);
90
133
  // Deprecated
91
134
  // FIXME: Remove the Variation when is no longer being used.
92
135
  // For security reasons, we should remove the variation description.
@@ -95,7 +138,7 @@ class Evaluator {
95
138
  const copyVariation = new variation_pb_1.Variation();
96
139
  copyVariation.setId(variation.getId());
97
140
  copyVariation.setName(variation.getName());
98
- copyVariation.setValue(variation.getValue());
141
+ copyVariation.setValue(convertedValue);
99
142
  evaluation.setVariation(copyVariation);
100
143
  evaluation.setReason(reason);
101
144
  evaluations.push(evaluation);
@@ -195,6 +238,38 @@ class Evaluator {
195
238
  }
196
239
  return variation;
197
240
  }
241
+ /**
242
+ * Converts YAML to JSON if needed, with in-memory caching.
243
+ * This ensures client SDKs can retrieve variation values using the object variation interface.
244
+ * Only performs conversion when the variation type is YAML.
245
+ * Cache key uses feature.updatedAt + variation.id to ensure cache invalidation when variations are updated.
246
+ */
247
+ convertVariationValue(feature, variation) {
248
+ // Only convert if type is YAML
249
+ if (feature.getVariationType() !== feature_pb_1.Feature.VariationType.YAML) {
250
+ return variation.getValue();
251
+ }
252
+ // Cache key: {featureUpdatedAt}:{variationId}
253
+ // This ensures cache is invalidated when the feature (and its variations) are updated,
254
+ // including changes from auto operations that don't increment feature.version
255
+ const cacheKey = `${feature.getUpdatedAt()}:${variation.getId()}`;
256
+ // Check cache first
257
+ const cached = this.variationCache.get(cacheKey);
258
+ if (cached !== undefined) {
259
+ return cached;
260
+ }
261
+ // Convert YAML to JSON
262
+ try {
263
+ const jsonValue = yamlToJSON(variation.getValue());
264
+ // Cache the result for future requests
265
+ this.variationCache.set(cacheKey, jsonValue);
266
+ return jsonValue;
267
+ }
268
+ catch (error) {
269
+ // Return original value as fallback on error
270
+ return variation.getValue();
271
+ }
272
+ }
198
273
  }
199
274
  exports.Evaluator = Evaluator;
200
275
  var Mark;
@@ -204,7 +279,7 @@ var Mark;
204
279
  Mark[Mark["Permanently"] = 2] = "Permanently";
205
280
  })(Mark || (Mark = {}));
206
281
  // FeatureIDsDependsOn returns the ids of the features that this feature depends on.
207
- function featureIDsDependsOn(feature) {
282
+ function getFeatureIDsDependsOn(feature) {
208
283
  const ids = [];
209
284
  // Iterate over prerequisites and add their FeatureId
210
285
  feature.getPrerequisitesList().forEach((p) => {
@@ -248,7 +323,7 @@ function topologicalSort(features) {
248
323
  throw new ErrCycleExists();
249
324
  }
250
325
  marks[fId] = Mark.Temporary;
251
- const dependentFeatureIds = featureIDsDependsOn(f);
326
+ const dependentFeatureIds = getFeatureIDsDependsOn(f);
252
327
  for (const fid of dependentFeatureIds) {
253
328
  const pf = mapFeatures[fid];
254
329
  if (!pf) {
@@ -278,7 +353,7 @@ function getFeaturesDependedOnTargets(targets, all) {
278
353
  // Add feature to evals
279
354
  evals[f.getId()] = f;
280
355
  // Get dependent features recursively
281
- const featureDependencies = featureIDsDependsOn(f);
356
+ const featureDependencies = getFeatureIDsDependsOn(f);
282
357
  featureDependencies.forEach((fid) => {
283
358
  const target = all.get(fid);
284
359
  if (target !== undefined) {
@@ -292,6 +367,24 @@ function getFeaturesDependedOnTargets(targets, all) {
292
367
  }
293
368
  // getFeaturesDependsOnTargets returns the features that depend on the target features.
294
369
  // targetFeatures are included in the result.
370
+ //
371
+ // This function ensures complete transitive closure for incremental evaluation.
372
+ //
373
+ // Example scenario:
374
+ // Feature Dependencies: A ← B ← C, A ← D, E ← D
375
+ // Target: [C] (recently updated)
376
+ //
377
+ // Step 1 - DFS finds direct/transitive dependents of targets:
378
+ // - A depends on B, B depends on C (target) → Add A, B
379
+ // - E depends on D, D doesn't depend on C → Skip E
380
+ // Result: {C, A, B}
381
+ //
382
+ // Step 2 - Find dependencies of discovered dependents:
383
+ // - A depends on D (new!) → Add D
384
+ // Result: {C, A, B, D}
385
+ //
386
+ // Without Step 2: Evaluating A would fail with "feature D not found"
387
+ // With Step 2: Complete closure ensures all dependencies are available
295
388
  function getFeaturesDependsOnTargets(targets, all) {
296
389
  const evals = {};
297
390
  // Mark target features in the evals map initially
@@ -303,7 +396,7 @@ function getFeaturesDependsOnTargets(targets, all) {
303
396
  if (evals[f.getId()]) {
304
397
  return true;
305
398
  }
306
- const featureDependencies = featureIDsDependsOn(f);
399
+ const featureDependencies = getFeatureIDsDependsOn(f);
307
400
  for (const fid of featureDependencies) {
308
401
  const dependentFeature = all.get(fid);
309
402
  if (dependentFeature && dfs(dependentFeature)) {
@@ -318,6 +411,37 @@ function getFeaturesDependsOnTargets(targets, all) {
318
411
  all.forEach((f) => {
319
412
  dfs(f);
320
413
  });
414
+ // Step 2: Ensure complete transitive closure
415
+ // The DFS above finds dependents (who depends on targets), but misses dependencies of those dependents.
416
+ // Example: If target C → dependent A → dependency D, we found A but missed D.
417
+ // Efficiently process only newly discovered features in each iteration.
418
+ const processed = new Set();
419
+ let queue = [];
420
+ for (const f of Object.values(evals)) {
421
+ queue.push(f);
422
+ }
423
+ const maxIterations = 100; // Prevent infinite loops in case of circular dependencies
424
+ let iteration = 0;
425
+ while (queue.length > 0 && iteration < maxIterations) {
426
+ iteration++;
427
+ const nextQueue = [];
428
+ for (const f of queue) {
429
+ if (processed.has(f.getId())) {
430
+ continue;
431
+ }
432
+ processed.add(f.getId());
433
+ // Find dependencies of f
434
+ const featureDependencies = getFeatureIDsDependsOn(f);
435
+ for (const depID of featureDependencies) {
436
+ const dep = all.get(depID);
437
+ if (dep && !evals[depID]) {
438
+ evals[depID] = dep;
439
+ nextQueue.push(dep);
440
+ }
441
+ }
442
+ }
443
+ queue = nextQueue;
444
+ }
321
445
  return evals;
322
446
  }
323
447
  function arrayToRecord(arr) {
@@ -326,3 +450,10 @@ function arrayToRecord(arr) {
326
450
  return acc;
327
451
  }, {});
328
452
  }
453
+ /**
454
+ * Converts a YAML string to a JSON string.
455
+ */
456
+ function yamlToJSON(yamlStr) {
457
+ const data = yaml.load(yamlStr);
458
+ return JSON.stringify(data);
459
+ }