@featurevisor/sdk
Version:
Featurevisor SDK for Node.js and the browser
2 lines • 24.1 kB
JavaScript
var e={d:(t,r)=>{for(var a in r)e.o(r,a)&&!e.o(t,a)&&Object.defineProperty(t,a,{enumerable:!0,get:r[a]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{Il:()=>m,f6:()=>x,ps:()=>S,Jr:()=>D,Vy:()=>k,lb:()=>h,mx:()=>u,Q_:()=>L,h:()=>V,K_:()=>O,_3:()=>j,EM:()=>E,eG:()=>v,dg:()=>b,f:()=>c,xE:()=>p});const r=/^[v^~<>=]*?(\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+)(?:\.([x*]|\d+))?(?:-([\da-z\-]+(?:\.[\da-z\-]+)*))?(?:\+[\da-z\-]+(?:\.[\da-z\-]+)*)?)?)?$/i,a=e=>{if("string"!=typeof e)throw new TypeError("Invalid argument expected string");const t=e.match(r);if(!t)throw new Error(`Invalid argument not valid semver ('${e}' received)`);return t.shift(),t},i=e=>"*"===e||"x"===e||"X"===e,n=e=>{const t=parseInt(e,10);return isNaN(t)?e:t},s=(e,t)=>{if(i(e)||i(t))return 0;const[r,a]=((e,t)=>typeof e!=typeof t?[String(e),String(t)]:[e,t])(n(e),n(t));return r>a?1:r<a?-1:0},o=(e,t)=>{for(let r=0;r<Math.max(e.length,t.length);r++){const a=s(e[r]||"0",t[r]||"0");if(0!==a)return a}return 0},l=(e,t)=>{const r=a(e),i=a(t),n=r.pop(),s=i.pop(),l=o(r,i);return 0!==l?l:n&&s?o(n.split("."),s.split(".")):n||s?n?-1:1:0};function c(e,t){return-1===t.indexOf(".")?e[t]:t.split(".").reduce(((e,t)=>e?e[t]:void 0),e)}function u(e,t,r){const{attribute:a,operator:i,value:n,regexFlags:s}=e,o=c(t,a);if("equals"===i)return o===n;if("notEquals"===i)return o!==n;if("before"===i||"after"===i){const e=o instanceof Date?o:new Date(o),t=n instanceof Date?n:new Date(n);return"before"===i?e<t:e>t}if(!Array.isArray(n)||-1===["string","number"].indexOf(typeof o)&&null!==o)if("string"==typeof o&&"string"==typeof n){const e=o;if("contains"===i)return-1!==e.indexOf(n);if("notContains"===i)return-1===e.indexOf(n);if("startsWith"===i)return e.startsWith(n);if("endsWith"===i)return e.endsWith(n);if("semverEquals"===i)return 0===l(e,n);if("semverNotEquals"===i)return 0!==l(e,n);if("semverGreaterThan"===i)return 1===l(e,n);if("semverGreaterThanOrEquals"===i)return l(e,n)>=0;if("semverLessThan"===i)return-1===l(e,n);if("semverLessThanOrEquals"===i)return l(e,n)<=0;if("matches"===i)return r(n,s||"").test(e);if("notMatches"===i)return!r(n,s||"").test(e)}else if("number"==typeof o&&"number"==typeof n){if("greaterThan"===i)return o>n;if("greaterThanOrEquals"===i)return o>=n;if("lessThan"===i)return o<n;if("lessThanOrEquals"===i)return o<=n}else{if("exists"===i)return void 0!==o;if("notExists"===i)return void 0===o;if(Array.isArray(o)&&"string"==typeof n){const e=o;if("includes"===i)return e.indexOf(n)>-1;if("notIncludes"===i)return-1===e.indexOf(n)}}else{const e=o;if("in"===i)return-1!==n.indexOf(e);if("notIn"===i)return-1===n.indexOf(e)}return!1}const f=e=>(new TextEncoder).encode(e),g=1,d=Math.pow(2,32),h=1e5;function b(e){const t=function(e,t){let r,a,i,n,s,o,l,c;for("string"==typeof e&&(e=f(e)),r=3&e.length,a=e.length-r,i=t,s=3432918353,o=461845907,c=0;c<a;)l=255&e[c]|(255&e[++c])<<8|(255&e[++c])<<16|(255&e[++c])<<24,++c,l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*o+(((l>>>16)*o&65535)<<16)&4294967295,i^=l,i=i<<13|i>>>19,n=5*(65535&i)+((5*(i>>>16)&65535)<<16)&4294967295,i=27492+(65535&n)+((58964+(n>>>16)&65535)<<16);switch(l=0,r){case 3:l^=(255&e[c+2])<<16;case 2:l^=(255&e[c+1])<<8;case 1:l^=255&e[c],l=(65535&l)*s+(((l>>>16)*s&65535)<<16)&4294967295,l=l<<15|l>>>17,l=(65535&l)*o+(((l>>>16)*o&65535)<<16)&4294967295,i^=l}return i^=e.length,i^=i>>>16,i=2246822507*(65535&i)+((2246822507*(i>>>16)&65535)<<16)&4294967295,i^=i>>>13,i=3266489909*(65535&i)+((3266489909*(i>>>16)&65535)<<16)&4294967295,i^=i>>>16,i>>>0}(e,g)/d;return Math.floor(t*h)}const y=".";function v(e){const{featureKey:t,bucketBy:r,context:a,logger:i}=e;let n,s;if("string"==typeof r)n="plain",s=[r];else if(Array.isArray(r))n="and",s=r;else{if("object"!=typeof r||!Array.isArray(r.or))throw i.error("invalid bucketBy",{featureKey:t,bucketBy:r}),new Error("invalid bucketBy");n="or",s=r.or}const o=[];return s.forEach((e=>{const t=c(a,e);void 0!==t&&("plain"===n||"and"===n||0===o.length)&&o.push(t)})),o.push(t),o.join(y)}const p="[Featurevisor]",O=function(e,t,r={}){let a="log";"info"===e?a="info":"warn"===e?a="warn":"error"===e&&(a="error"),console[a](p,t,r)};class k{constructor(e){this.level=e.level||k.defaultLevel,this.handle=e.handler||O}setLevel(e){this.level=e}log(e,t,r){k.allLevels.indexOf(this.level)>=k.allLevels.indexOf(e)&&this.handle(e,t,r)}debug(e,t){this.log("debug",e,t)}info(e,t){this.log("info",e,t)}warn(e,t){this.log("warn",e,t)}error(e,t){this.log("error",e,t)}}function V(e={}){return new k(e)}k.allLevels=["fatal","error","warn","info","debug"],k.defaultLevel="info";class A{constructor(e){this.hooks=[],this.logger=e.logger,e.hooks&&e.hooks.forEach((e=>{this.add(e)}))}add(e){if(!this.hooks.some((t=>t.name===e.name)))return this.hooks.push(e),()=>{this.remove(e.name)};this.logger.error(`Hook with name "${e.name}" already exists.`,{name:e.name,hook:e})}remove(e){this.hooks=this.hooks.filter((t=>t.name!==e))}getAll(){return this.hooks}}class K{constructor(){this.listeners={}}on(e,t){this.listeners[e]||(this.listeners[e]=[]);const r=this.listeners[e];r.push(t);let a=!0;return function(){if(!a)return;a=!1;const e=r.indexOf(t);-1!==e&&r.splice(e,1)}}trigger(e,t={}){const r=this.listeners[e];r&&r.forEach((function(e){try{e(t)}catch(e){console.error(e)}}))}clearAll(){this.listeners={}}}class m{constructor(e){const{datafile:t,logger:r}=e;this.logger=r,this.schemaVersion=t.schemaVersion,this.revision=t.revision,this.segments=t.segments,this.features=t.features,this.regexCache={}}getRevision(){return this.revision}getSchemaVersion(){return this.schemaVersion}getSegment(e){const t=this.segments[e];if(t)return t.conditions=this.parseConditionsIfStringified(t.conditions),t}getFeatureKeys(){return Object.keys(this.features)}getFeature(e){return this.features[e]}getVariableKeys(e){const t=this.getFeature(e);return t?Object.keys(t.variablesSchema||{}):[]}hasVariations(e){const t=this.getFeature(e);return!!t&&Array.isArray(t.variations)&&t.variations.length>0}getRegex(e,t){const r=t||"",a=`${e}-${r}`;if(this.regexCache[a])return this.regexCache[a];const i=new RegExp(e,r);return this.regexCache[a]=i,i}allConditionsAreMatched(e,t){if("string"==typeof e)return"*"===e;const r=(e,t)=>this.getRegex(e,t);if("attribute"in e)try{return u(e,t,r)}catch(r){return this.logger.warn(r.message,{error:r,details:{condition:e,context:t}}),!1}return"and"in e&&Array.isArray(e.and)?e.and.every((e=>this.allConditionsAreMatched(e,t))):"or"in e&&Array.isArray(e.or)?e.or.some((e=>this.allConditionsAreMatched(e,t))):"not"in e&&Array.isArray(e.not)?e.not.every((()=>!1===this.allConditionsAreMatched({and:e.not},t))):!!Array.isArray(e)&&e.every((e=>this.allConditionsAreMatched(e,t)))}segmentIsMatched(e,t){return this.allConditionsAreMatched(e.conditions,t)}allSegmentsAreMatched(e,t){if("*"===e)return!0;if("string"==typeof e){const r=this.getSegment(e);return!!r&&this.segmentIsMatched(r,t)}if("object"==typeof e){if("and"in e&&Array.isArray(e.and))return e.and.every((e=>this.allSegmentsAreMatched(e,t)));if("or"in e&&Array.isArray(e.or))return e.or.some((e=>this.allSegmentsAreMatched(e,t)));if("not"in e&&Array.isArray(e.not))return e.not.every((e=>!1===this.allSegmentsAreMatched(e,t)))}return!!Array.isArray(e)&&e.every((e=>this.allSegmentsAreMatched(e,t)))}getMatchedTraffic(e,t){return e.find((e=>!!this.allSegmentsAreMatched(this.parseSegmentsIfStringified(e.segments),t)))}getMatchedAllocation(e,t){if(e.allocation)for(const r of e.allocation){const[e,a]=r.range;if(r.range&&e<=t&&a>=t)return r}}getMatchedForce(e,t){const r={force:void 0,forceIndex:void 0},a="string"==typeof e?this.getFeature(e):e;if(!a||!a.force)return r;for(let e=0;e<a.force.length;e++){const i=a.force[e];if(i.conditions&&this.allConditionsAreMatched(this.parseConditionsIfStringified(i.conditions),t)){r.force=i,r.forceIndex=e;break}if(i.segments&&this.allSegmentsAreMatched(this.parseSegmentsIfStringified(i.segments),t)){r.force=i,r.forceIndex=e;break}}return r}parseConditionsIfStringified(e){if("string"!=typeof e)return e;if("*"===e)return e;try{return JSON.parse(e)}catch(t){return this.logger.error("Error parsing conditions",{error:t,details:{conditions:e}}),e}}parseSegmentsIfStringified(e){return"string"==typeof e&&(e.startsWith("{")||e.startsWith("["))?JSON.parse(e):e}}var x;function E(e){try{const{hooksManager:t}=e,r=t.getAll();let a=e;for(const e of t.getAll())e.before&&(a=e.before(a));let i=j(a);void 0!==a.defaultVariationValue&&"variation"===i.type&&void 0===i.variationValue&&(i.variationValue=a.defaultVariationValue),void 0!==a.defaultVariableValue&&"variable"===i.type&&void 0===i.variableValue&&(i.variableValue=a.defaultVariableValue);for(const e of r)e.after&&(i=e.after(i,a));return i}catch(t){const{type:r,featureKey:a,variableKey:i,logger:n}=e,s={type:r,featureKey:a,variableKey:i,reason:x.ERROR,error:t};return n.error("error during evaluation",s),s}}function j(e){const{type:t,featureKey:r,variableKey:a,context:i,logger:n,datafileReader:s,sticky:o,hooksManager:l}=e,c=l.getAll();let u;try{let l;if("flag"!==t&&(l=j(Object.assign(Object.assign({},e),{type:"flag"})),!1===l.enabled)){u={type:t,featureKey:r,reason:x.DISABLED};const e=s.getFeature(r);if("variable"===t&&e&&a&&e.variablesSchema&&e.variablesSchema[a]){const i=e.variablesSchema[a];void 0!==i.disabledValue?u={type:t,featureKey:r,reason:x.VARIABLE_DISABLED,variableKey:a,variableValue:i.disabledValue,variableSchema:i,enabled:!1}:i.useDefaultWhenDisabled&&(u={type:t,featureKey:r,reason:x.VARIABLE_DEFAULT,variableKey:a,variableValue:i.defaultValue,variableSchema:i,enabled:!1})}return"variation"===t&&e&&e.disabledVariationValue&&(u={type:t,featureKey:r,reason:x.VARIATION_DISABLED,variationValue:e.disabledVariationValue,enabled:!1}),n.debug("feature is disabled",u),u}if(o&&o[r]){if("flag"===t&&void 0!==o[r].enabled)return u={type:t,featureKey:r,reason:x.STICKY,sticky:o[r],enabled:o[r].enabled},n.debug("using sticky enabled",u),u;if("variation"===t){const e=o[r].variation;if(void 0!==e)return u={type:t,featureKey:r,reason:x.STICKY,variationValue:e},n.debug("using sticky variation",u),u}if(a){const e=o[r].variables;if(e){const i=e[a];if(void 0!==i)return u={type:t,featureKey:r,reason:x.STICKY,variableKey:a,variableValue:i},n.debug("using sticky variable",u),u}}}const f="string"==typeof r?s.getFeature(r):r;if(!f)return u={type:t,featureKey:r,reason:x.FEATURE_NOT_FOUND},n.warn("feature not found",u),u;let g;if("flag"===t&&f.deprecated&&n.warn("feature is deprecated",{featureKey:r}),a){if(f.variablesSchema&&f.variablesSchema[a]&&(g=f.variablesSchema[a]),!g)return u={type:t,featureKey:r,reason:x.VARIABLE_NOT_FOUND,variableKey:a},n.warn("variable schema not found",u),u;g.deprecated&&n.warn("variable is deprecated",{featureKey:r,variableKey:a})}if("variation"===t&&(!f.variations||0===f.variations.length))return u={type:t,featureKey:r,reason:x.NO_VARIATIONS},n.warn("no variations",u),u;const{force:d,forceIndex:h}=s.getMatchedForce(f,i);if(d){if("flag"===t&&void 0!==d.enabled)return u={type:t,featureKey:r,reason:x.FORCED,forceIndex:h,force:d,enabled:d.enabled},n.debug("forced enabled found",u),u;if("variation"===t&&d.variation&&f.variations){const e=f.variations.find((e=>e.value===d.variation));if(e)return u={type:t,featureKey:r,reason:x.FORCED,forceIndex:h,force:d,variation:e},n.debug("forced variation found",u),u}if(a&&d.variables&&void 0!==d.variables[a])return u={type:t,featureKey:r,reason:x.FORCED,forceIndex:h,force:d,variableKey:a,variableSchema:g,variableValue:d.variables[a]},n.debug("forced variable",u),u}if("flag"===t&&f.required&&f.required.length>0){const a=f.required.every((t=>{let r,a;if("string"==typeof t?r=t:(r=t.key,a=t.variation),!j(Object.assign(Object.assign({},e),{type:"flag",featureKey:r})).enabled)return!1;if(void 0!==a){const t=j(Object.assign(Object.assign({},e),{type:"variation",featureKey:r}));let i;return t.variationValue?i=t.variationValue:t.variation&&(i=t.variation.value),i===a}return!0}));if(!a)return u={type:t,featureKey:r,reason:x.REQUIRED,required:f.required,enabled:a},n.debug("required features not enabled",u),u}let y=v({featureKey:r,bucketBy:f.bucketBy,context:i,logger:n});for(const e of c)e.bucketKey&&(y=e.bucketKey({featureKey:r,context:i,bucketBy:f.bucketBy,bucketKey:y}));let p,O,k=b(y);for(const e of c)e.bucketValue&&(k=e.bucketValue({featureKey:r,bucketKey:y,context:i,bucketValue:k}));if("flag"!==t?(p=s.getMatchedTraffic(f.traffic,i),p&&(O=s.getMatchedAllocation(p,k))):p=s.getMatchedTraffic(f.traffic,i),p){if(0===p.percentage)return u={type:t,featureKey:r,reason:x.RULE,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,enabled:!1},n.debug("matched rule with 0 percentage",u),u;if("flag"===t){if(f.ranges&&f.ranges.length>0)return f.ranges.find((e=>k>=e[0]&&k<e[1]))?(u={type:t,featureKey:r,reason:x.ALLOCATED,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,enabled:void 0===p.enabled||p.enabled},n.debug("matched",u),u):(u={type:t,featureKey:r,reason:x.OUT_OF_RANGE,bucketKey:y,bucketValue:k,enabled:!1},n.debug("not matched",u),u);if(void 0!==p.enabled)return u={type:t,featureKey:r,reason:x.RULE,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,enabled:p.enabled},n.debug("override from rule",u),u;if(k<=p.percentage)return u={type:t,featureKey:r,reason:x.RULE,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,enabled:!0},n.debug("matched traffic",u),u}if("variation"===t&&f.variations){if(p.variation){const e=f.variations.find((e=>e.value===p.variation));if(e)return u={type:t,featureKey:r,reason:x.RULE,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,variation:e},n.debug("override from rule",u),u}if(O&&O.variation){const e=f.variations.find((e=>e.value===O.variation));if(e)return u={type:t,featureKey:r,reason:x.ALLOCATED,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,variation:e},n.debug("allocated variation",u),u}}}if("variable"===t&&a){if(p&&p.variables&&void 0!==p.variables[a])return u={type:t,featureKey:r,reason:x.RULE,bucketKey:y,bucketValue:k,ruleKey:p.key,traffic:p,variableKey:a,variableSchema:g,variableValue:p.variables[a]},n.debug("override from rule",u),u;let e;if(d&&d.variation?e=d.variation:p&&p.variation?e=p.variation:O&&O.variation&&(e=O.variation),e&&Array.isArray(f.variations)){const o=f.variations.find((t=>t.value===e));if(o&&o.variableOverrides&&o.variableOverrides[a]){const e=o.variableOverrides[a].find((e=>e.conditions?s.allConditionsAreMatched("string"==typeof e.conditions&&"*"!==e.conditions?JSON.parse(e.conditions):e.conditions,i):!!e.segments&&s.allSegmentsAreMatched(s.parseSegmentsIfStringified(e.segments),i)));if(e)return u={type:t,featureKey:r,reason:x.VARIABLE_OVERRIDE,bucketKey:y,bucketValue:k,ruleKey:null==p?void 0:p.key,traffic:p,variableKey:a,variableSchema:g,variableValue:e.value},n.debug("variable override",u),u}if(o&&o.variables&&void 0!==o.variables[a])return u={type:t,featureKey:r,reason:x.ALLOCATED,bucketKey:y,bucketValue:k,ruleKey:null==p?void 0:p.key,traffic:p,variableKey:a,variableSchema:g,variableValue:o.variables[a]},n.debug("allocated variable",u),u}}return"variation"===t?(u={type:t,featureKey:r,reason:x.NO_MATCH,bucketKey:y,bucketValue:k},n.debug("no matched variation",u),u):"variable"===t?g?(u={type:t,featureKey:r,reason:x.VARIABLE_DEFAULT,bucketKey:y,bucketValue:k,variableKey:a,variableSchema:g,variableValue:g.defaultValue},n.debug("using default value",u),u):(u={type:t,featureKey:r,reason:x.VARIABLE_NOT_FOUND,variableKey:a,bucketKey:y,bucketValue:k},n.debug("variable not found",u),u):(u={type:t,featureKey:r,reason:x.NO_MATCH,bucketKey:y,bucketValue:k,enabled:!1},n.debug("nothing matched",u),u)}catch(e){return u={type:t,featureKey:r,variableKey:a,reason:x.ERROR,error:e},n.error("error",u),u}}function R(e={},t={},r){const a=[...Object.keys(e),...Object.keys(t)];return{features:a.filter(((e,t)=>a.indexOf(e)===t)),replaced:r}}!function(e){e.FEATURE_NOT_FOUND="feature_not_found",e.DISABLED="disabled",e.REQUIRED="required",e.OUT_OF_RANGE="out_of_range",e.NO_VARIATIONS="no_variations",e.VARIATION_DISABLED="variation_disabled",e.VARIABLE_NOT_FOUND="variable_not_found",e.VARIABLE_DEFAULT="variable_default",e.VARIABLE_DISABLED="variable_disabled",e.VARIABLE_OVERRIDE="variable_override",e.NO_MATCH="no_match",e.FORCED="forced",e.STICKY="sticky",e.RULE="rule",e.ALLOCATED="allocated",e.ERROR="error"}(x||(x={}));class S{constructor(e){this.parent=e.parent,this.context=e.context,this.sticky=e.sticky||{},this.emitter=new K}on(e,t){return"context_set"===e||"sticky_set"===e?this.emitter.on(e,t):this.parent.on(e,t)}close(){this.emitter.clearAll()}setContext(e,t=!1){this.context=t?e:Object.assign(Object.assign({},this.context),e),this.emitter.trigger("context_set",{context:this.context,replaced:t})}getContext(e){return this.parent.getContext(Object.assign(Object.assign({},this.context),e))}setSticky(e,t=!1){const r=this.sticky||{};this.sticky=t?Object.assign({},e):Object.assign(Object.assign({},this.sticky),e);const a=R(r,this.sticky,t);this.emitter.trigger("sticky_set",a)}isEnabled(e,t={},r={}){return this.parent.isEnabled(e,Object.assign(Object.assign({},this.context),t),Object.assign({sticky:this.sticky},r))}getVariation(e,t={},r={}){return this.parent.getVariation(e,Object.assign(Object.assign({},this.context),t),Object.assign({sticky:this.sticky},r))}getVariable(e,t,r={},a={}){return this.parent.getVariable(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableBoolean(e,t,r={},a={}){return this.parent.getVariableBoolean(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableString(e,t,r={},a={}){return this.parent.getVariableString(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableInteger(e,t,r={},a={}){return this.parent.getVariableInteger(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableDouble(e,t,r={},a={}){return this.parent.getVariableDouble(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableArray(e,t,r={},a={}){return this.parent.getVariableArray(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableObject(e,t,r={},a={}){return this.parent.getVariableObject(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getVariableJSON(e,t,r={},a={}){return this.parent.getVariableJSON(e,t,Object.assign(Object.assign({},this.context),r),Object.assign({sticky:this.sticky},a))}getAllEvaluations(e={},t=[],r={}){return this.parent.getAllEvaluations(Object.assign(Object.assign({},this.context),e),t,Object.assign({sticky:this.sticky},r))}}function I(e,t){try{if(void 0===e)return null;switch(t){case"string":return"string"==typeof e?e:null;case"integer":return parseInt(e,10);case"double":return parseFloat(e);case"boolean":return!0===e;case"array":return Array.isArray(e)?e:null;case"object":return"object"==typeof e?e:null;default:return e}}catch(e){return null}}const _={schemaVersion:"2",revision:"unknown",segments:{},features:{}};class D{constructor(e){this.context={},this.context=e.context||{},this.logger=e.logger||V({level:e.logLevel||k.defaultLevel}),this.hooksManager=new A({hooks:e.hooks||[],logger:this.logger}),this.emitter=new K,this.sticky=e.sticky,this.datafileReader=new m({datafile:_,logger:this.logger}),e.datafile&&(this.datafileReader=new m({datafile:"string"==typeof e.datafile?JSON.parse(e.datafile):e.datafile,logger:this.logger})),this.logger.info("Featurevisor SDK initialized")}setLogLevel(e){this.logger.setLevel(e)}setDatafile(e){try{const t=new m({datafile:"string"==typeof e?JSON.parse(e):e,logger:this.logger}),r=function(e,t){const r=e.getRevision(),a=e.getFeatureKeys(),i=t.getRevision(),n=t.getFeatureKeys(),s=[],o=[],l=[];for(const r of a){if(-1===n.indexOf(r)){s.push(r);continue}const a=e.getFeature(r),i=t.getFeature(r);(null==a?void 0:a.hash)!==(null==i?void 0:i.hash)&&o.push(r)}for(const e of n)-1===a.indexOf(e)&&l.push(e);return{revision:i,previousRevision:r,revisionChanged:r!==i,features:[...s,...o,...l].filter(((e,t,r)=>r.indexOf(e)===t))}}(this.datafileReader,t);this.datafileReader=t,this.logger.info("datafile set",r),this.emitter.trigger("datafile_set",r)}catch(e){this.logger.error("could not parse datafile",{error:e})}}setSticky(e,t=!1){const r=this.sticky||{};this.sticky=t?Object.assign({},e):Object.assign(Object.assign({},this.sticky),e);const a=R(r,this.sticky,t);this.logger.info("sticky features set",a),this.emitter.trigger("sticky_set",a)}getRevision(){return this.datafileReader.getRevision()}getFeature(e){return this.datafileReader.getFeature(e)}addHook(e){return this.hooksManager.add(e)}on(e,t){return this.emitter.on(e,t)}close(){this.emitter.clearAll()}setContext(e,t=!1){this.context=t?e:Object.assign(Object.assign({},this.context),e),this.emitter.trigger("context_set",{context:this.context,replaced:t}),this.logger.debug(t?"context replaced":"context updated",{context:this.context,replaced:t})}getContext(e){return e?Object.assign(Object.assign({},this.context),e):this.context}spawn(e={},t={}){return new S({parent:this,context:this.getContext(e),sticky:t.sticky})}getEvaluationDependencies(e,t={}){return{context:this.getContext(e),logger:this.logger,hooksManager:this.hooksManager,datafileReader:this.datafileReader,sticky:t.sticky?Object.assign(Object.assign({},this.sticky),t.sticky):this.sticky,defaultVariationValue:t.defaultVariationValue,defaultVariableValue:t.defaultVariableValue}}evaluateFlag(e,t={},r={}){return E(Object.assign(Object.assign({},this.getEvaluationDependencies(t,r)),{type:"flag",featureKey:e}))}isEnabled(e,t={},r={}){try{return!0===this.evaluateFlag(e,t,r).enabled}catch(t){return this.logger.error("isEnabled",{featureKey:e,error:t}),!1}}evaluateVariation(e,t={},r={}){return E(Object.assign(Object.assign({},this.getEvaluationDependencies(t,r)),{type:"variation",featureKey:e}))}getVariation(e,t={},r={}){try{const a=this.evaluateVariation(e,t,r);return void 0!==a.variationValue?a.variationValue:a.variation?a.variation.value:null}catch(t){return this.logger.error("getVariation",{featureKey:e,error:t}),null}}evaluateVariable(e,t,r={},a={}){return E(Object.assign(Object.assign({},this.getEvaluationDependencies(r,a)),{type:"variable",featureKey:e,variableKey:t}))}getVariable(e,t,r={},a={}){try{const i=this.evaluateVariable(e,t,r,a);return void 0!==i.variableValue?i.variableSchema&&"json"===i.variableSchema.type&&"string"==typeof i.variableValue?JSON.parse(i.variableValue):i.variableValue:null}catch(r){return this.logger.error("getVariable",{featureKey:e,variableKey:t,error:r}),null}}getVariableBoolean(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"boolean")}getVariableString(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"string")}getVariableInteger(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"integer")}getVariableDouble(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"double")}getVariableArray(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"array")}getVariableObject(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"object")}getVariableJSON(e,t,r={},a={}){return I(this.getVariable(e,t,r,a),"json")}getAllEvaluations(e={},t=[],r={}){const a={},i=t.length>0?t:this.datafileReader.getFeatureKeys();for(const t of i){const i={enabled:this.isEnabled(t,e,r)};if(this.datafileReader.hasVariations(t)){const a=this.getVariation(t,e,r);a&&(i.variation=a)}const n=this.datafileReader.getVariableKeys(t);if(n.length>0){i.variables={};for(const a of n)i.variables[a]=this.getVariable(t,a,e,r)}a[t]=i}return a}}function L(e={}){return new D(e)}var M=t.Il,C=t.f6,F=t.ps,T=t.Jr,w=t.Vy,N=t.lb,B=t.mx,U=t.Q_,q=t.h,J=t.K_,W=t._3,H=t.EM,G=t.eG,z=t.dg,$=t.f,Q=t.xE;export{M as DatafileReader,C as EvaluationReason,F as FeaturevisorChildInstance,T as FeaturevisorInstance,w as Logger,N as MAX_BUCKETED_NUMBER,B as conditionIsMatched,U as createInstance,q as createLogger,J as defaultLogHandler,W as evaluate,H as evaluateWithHooks,G as getBucketKey,z as getBucketedNumber,$ as getValueFromContext,Q as loggerPrefix};
//# sourceMappingURL=index.mjs.map