New Research: Supply Chain Attack on Axios Pulls Malicious Dependency from npm.Details →
Socket
Book a DemoSign in
Socket

@reforge-com/javascript

Package Overview
Dependencies
Maintainers
2
Versions
10
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@reforge-com/javascript - npm Package Compare versions

Comparing version
0.0.1
to
0.0.2
+2
dist/reforge.bundle.js
"use strict";var window;(window||={}).reforgeNamespace=(()=>{var h=(e,r)=>()=>(r||e((r={exports:{}}).exports,r),r.exports);var Q=h(z=>{"use strict";Object.defineProperty(z,"__esModule",{value:!0});z.default=Ke;var C,ke=new Uint8Array(16);function Ke(){if(!C&&(C=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!C))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return C(ke)}});var oe=h(R=>{"use strict";Object.defineProperty(R,"__esModule",{value:!0});R.default=void 0;var He=/^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;R.default=He});var T=h(j=>{"use strict";Object.defineProperty(j,"__esModule",{value:!0});j.default=void 0;var Fe=Be(oe());function Be(e){return e&&e.__esModule?e:{default:e}}function We(e){return typeof e=="string"&&Fe.default.test(e)}var Je=We;j.default=Je});var S=h(A=>{"use strict";Object.defineProperty(A,"__esModule",{value:!0});A.default=void 0;A.unsafeStringify=ae;var Xe=ze(T());function ze(e){return e&&e.__esModule?e:{default:e}}var g=[];for(let e=0;e<256;++e)g.push((e+256).toString(16).slice(1));function ae(e,r=0){return g[e[r+0]]+g[e[r+1]]+g[e[r+2]]+g[e[r+3]]+"-"+g[e[r+4]]+g[e[r+5]]+"-"+g[e[r+6]]+g[e[r+7]]+"-"+g[e[r+8]]+g[e[r+9]]+"-"+g[e[r+10]]+g[e[r+11]]+g[e[r+12]]+g[e[r+13]]+g[e[r+14]]+g[e[r+15]]}function Qe(e,r=0){let t=ae(e,r);if(!(0,Xe.default)(t))throw TypeError("Stringified UUID is invalid");return t}var Ye=Qe;A.default=Ye});var ue=h(M=>{"use strict";Object.defineProperty(M,"__esModule",{value:!0});M.default=void 0;var Ge=et(Q()),Ze=S();function et(e){return e&&e.__esModule?e:{default:e}}var le,Y,G=0,Z=0;function tt(e,r,t){let n=r&&t||0,i=r||new Array(16);e=e||{};let s=e.node||le,o=e.clockseq!==void 0?e.clockseq:Y;if(s==null||o==null){let f=e.random||(e.rng||Ge.default)();s==null&&(s=le=[f[0]|1,f[1],f[2],f[3],f[4],f[5]]),o==null&&(o=Y=(f[6]<<8|f[7])&16383)}let l=e.msecs!==void 0?e.msecs:Date.now(),a=e.nsecs!==void 0?e.nsecs:Z+1,u=l-G+(a-Z)/1e4;if(u<0&&e.clockseq===void 0&&(o=o+1&16383),(u<0||l>G)&&e.nsecs===void 0&&(a=0),a>=1e4)throw new Error("uuid.v1(): Can't create more than 10M uuids/sec");G=l,Z=a,Y=o,l+=122192928e5;let c=((l&268435455)*1e4+a)%4294967296;i[n++]=c>>>24&255,i[n++]=c>>>16&255,i[n++]=c>>>8&255,i[n++]=c&255;let y=l/4294967296*1e4&268435455;i[n++]=y>>>8&255,i[n++]=y&255,i[n++]=y>>>24&15|16,i[n++]=y>>>16&255,i[n++]=o>>>8|128,i[n++]=o&255;for(let f=0;f<6;++f)i[n+f]=s[f];return r||(0,Ze.unsafeStringify)(i)}var rt=tt;M.default=rt});var ee=h(U=>{"use strict";Object.defineProperty(U,"__esModule",{value:!0});U.default=void 0;var nt=it(T());function it(e){return e&&e.__esModule?e:{default:e}}function st(e){if(!(0,nt.default)(e))throw TypeError("Invalid UUID");let r,t=new Uint8Array(16);return t[0]=(r=parseInt(e.slice(0,8),16))>>>24,t[1]=r>>>16&255,t[2]=r>>>8&255,t[3]=r&255,t[4]=(r=parseInt(e.slice(9,13),16))>>>8,t[5]=r&255,t[6]=(r=parseInt(e.slice(14,18),16))>>>8,t[7]=r&255,t[8]=(r=parseInt(e.slice(19,23),16))>>>8,t[9]=r&255,t[10]=(r=parseInt(e.slice(24,36),16))/1099511627776&255,t[11]=r/4294967296&255,t[12]=r>>>24&255,t[13]=r>>>16&255,t[14]=r>>>8&255,t[15]=r&255,t}var ot=st;U.default=ot});var te=h(O=>{"use strict";Object.defineProperty(O,"__esModule",{value:!0});O.URL=O.DNS=void 0;O.default=ft;var at=S(),lt=ut(ee());function ut(e){return e&&e.__esModule?e:{default:e}}function ct(e){e=unescape(encodeURIComponent(e));let r=[];for(let t=0;t<e.length;++t)r.push(e.charCodeAt(t));return r}var ce="6ba7b810-9dad-11d1-80b4-00c04fd430c8";O.DNS=ce;var fe="6ba7b811-9dad-11d1-80b4-00c04fd430c8";O.URL=fe;function ft(e,r,t){function n(i,s,o,l){var a;if(typeof i=="string"&&(i=ct(i)),typeof s=="string"&&(s=(0,lt.default)(s)),((a=s)===null||a===void 0?void 0:a.length)!==16)throw TypeError("Namespace must be array-like (16 iterable integer values, 0-255)");let u=new Uint8Array(16+i.length);if(u.set(s),u.set(i,s.length),u=t(u),u[6]=u[6]&15|r,u[8]=u[8]&63|128,o){l=l||0;for(let c=0;c<16;++c)o[l+c]=u[c];return o}return(0,at.unsafeStringify)(u)}try{n.name=e}catch{}return n.DNS=ce,n.URL=fe,n}});var he=h(q=>{"use strict";Object.defineProperty(q,"__esModule",{value:!0});q.default=void 0;function dt(e){if(typeof e=="string"){let r=unescape(encodeURIComponent(e));e=new Uint8Array(r.length);for(let t=0;t<r.length;++t)e[t]=r.charCodeAt(t)}return ht(gt(pt(e),e.length*8))}function ht(e){let r=[],t=e.length*32,n="0123456789abcdef";for(let i=0;i<t;i+=8){let s=e[i>>5]>>>i%32&255,o=parseInt(n.charAt(s>>>4&15)+n.charAt(s&15),16);r.push(o)}return r}function de(e){return(e+64>>>9<<4)+14+1}function gt(e,r){e[r>>5]|=128<<r%32,e[de(r)-1]=r;let t=1732584193,n=-271733879,i=-1732584194,s=271733878;for(let o=0;o<e.length;o+=16){let l=t,a=n,u=i,c=s;t=p(t,n,i,s,e[o],7,-680876936),s=p(s,t,n,i,e[o+1],12,-389564586),i=p(i,s,t,n,e[o+2],17,606105819),n=p(n,i,s,t,e[o+3],22,-1044525330),t=p(t,n,i,s,e[o+4],7,-176418897),s=p(s,t,n,i,e[o+5],12,1200080426),i=p(i,s,t,n,e[o+6],17,-1473231341),n=p(n,i,s,t,e[o+7],22,-45705983),t=p(t,n,i,s,e[o+8],7,1770035416),s=p(s,t,n,i,e[o+9],12,-1958414417),i=p(i,s,t,n,e[o+10],17,-42063),n=p(n,i,s,t,e[o+11],22,-1990404162),t=p(t,n,i,s,e[o+12],7,1804603682),s=p(s,t,n,i,e[o+13],12,-40341101),i=p(i,s,t,n,e[o+14],17,-1502002290),n=p(n,i,s,t,e[o+15],22,1236535329),t=v(t,n,i,s,e[o+1],5,-165796510),s=v(s,t,n,i,e[o+6],9,-1069501632),i=v(i,s,t,n,e[o+11],14,643717713),n=v(n,i,s,t,e[o],20,-373897302),t=v(t,n,i,s,e[o+5],5,-701558691),s=v(s,t,n,i,e[o+10],9,38016083),i=v(i,s,t,n,e[o+15],14,-660478335),n=v(n,i,s,t,e[o+4],20,-405537848),t=v(t,n,i,s,e[o+9],5,568446438),s=v(s,t,n,i,e[o+14],9,-1019803690),i=v(i,s,t,n,e[o+3],14,-187363961),n=v(n,i,s,t,e[o+8],20,1163531501),t=v(t,n,i,s,e[o+13],5,-1444681467),s=v(s,t,n,i,e[o+2],9,-51403784),i=v(i,s,t,n,e[o+7],14,1735328473),n=v(n,i,s,t,e[o+12],20,-1926607734),t=m(t,n,i,s,e[o+5],4,-378558),s=m(s,t,n,i,e[o+8],11,-2022574463),i=m(i,s,t,n,e[o+11],16,1839030562),n=m(n,i,s,t,e[o+14],23,-35309556),t=m(t,n,i,s,e[o+1],4,-1530992060),s=m(s,t,n,i,e[o+4],11,1272893353),i=m(i,s,t,n,e[o+7],16,-155497632),n=m(n,i,s,t,e[o+10],23,-1094730640),t=m(t,n,i,s,e[o+13],4,681279174),s=m(s,t,n,i,e[o],11,-358537222),i=m(i,s,t,n,e[o+3],16,-722521979),n=m(n,i,s,t,e[o+6],23,76029189),t=m(t,n,i,s,e[o+9],4,-640364487),s=m(s,t,n,i,e[o+12],11,-421815835),i=m(i,s,t,n,e[o+15],16,530742520),n=m(n,i,s,t,e[o+2],23,-995338651),t=_(t,n,i,s,e[o],6,-198630844),s=_(s,t,n,i,e[o+7],10,1126891415),i=_(i,s,t,n,e[o+14],15,-1416354905),n=_(n,i,s,t,e[o+5],21,-57434055),t=_(t,n,i,s,e[o+12],6,1700485571),s=_(s,t,n,i,e[o+3],10,-1894986606),i=_(i,s,t,n,e[o+10],15,-1051523),n=_(n,i,s,t,e[o+1],21,-2054922799),t=_(t,n,i,s,e[o+8],6,1873313359),s=_(s,t,n,i,e[o+15],10,-30611744),i=_(i,s,t,n,e[o+6],15,-1560198380),n=_(n,i,s,t,e[o+13],21,1309151649),t=_(t,n,i,s,e[o+4],6,-145523070),s=_(s,t,n,i,e[o+11],10,-1120210379),i=_(i,s,t,n,e[o+2],15,718787259),n=_(n,i,s,t,e[o+9],21,-343485551),t=x(t,l),n=x(n,a),i=x(i,u),s=x(s,c)}return[t,n,i,s]}function pt(e){if(e.length===0)return[];let r=e.length*8,t=new Uint32Array(de(r));for(let n=0;n<r;n+=8)t[n>>5]|=(e[n/8]&255)<<n%32;return t}function x(e,r){let t=(e&65535)+(r&65535);return(e>>16)+(r>>16)+(t>>16)<<16|t&65535}function vt(e,r){return e<<r|e>>>32-r}function D(e,r,t,n,i,s){return x(vt(x(x(r,e),x(n,s)),i),t)}function p(e,r,t,n,i,s,o){return D(r&t|~r&n,e,r,i,s,o)}function v(e,r,t,n,i,s,o){return D(r&n|t&~n,e,r,i,s,o)}function m(e,r,t,n,i,s,o){return D(r^t^n,e,r,i,s,o)}function _(e,r,t,n,i,s,o){return D(t^(r|~n),e,r,i,s,o)}var mt=dt;q.default=mt});var pe=h(N=>{"use strict";Object.defineProperty(N,"__esModule",{value:!0});N.default=void 0;var _t=ge(te()),yt=ge(he());function ge(e){return e&&e.__esModule?e:{default:e}}var wt=(0,_t.default)("v3",48,yt.default),bt=wt;N.default=bt});var ve=h(L=>{"use strict";Object.defineProperty(L,"__esModule",{value:!0});L.default=void 0;var xt=typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto),Ot={randomUUID:xt};L.default=Ot});var ye=h(V=>{"use strict";Object.defineProperty(V,"__esModule",{value:!0});V.default=void 0;var me=_e(ve()),Et=_e(Q()),Pt=S();function _e(e){return e&&e.__esModule?e:{default:e}}function Tt(e,r,t){if(me.default.randomUUID&&!r&&!e)return me.default.randomUUID();e=e||{};let n=e.random||(e.rng||Et.default)();if(n[6]=n[6]&15|64,n[8]=n[8]&63|128,r){t=t||0;for(let i=0;i<16;++i)r[t+i]=n[i];return r}return(0,Pt.unsafeStringify)(n)}var At=Tt;V.default=At});var we=h($=>{"use strict";Object.defineProperty($,"__esModule",{value:!0});$.default=void 0;function St(e,r,t,n){switch(e){case 0:return r&t^~r&n;case 1:return r^t^n;case 2:return r&t^r&n^t&n;case 3:return r^t^n}}function re(e,r){return e<<r|e>>>32-r}function It(e){let r=[1518500249,1859775393,2400959708,3395469782],t=[1732584193,4023233417,2562383102,271733878,3285377520];if(typeof e=="string"){let o=unescape(encodeURIComponent(e));e=[];for(let l=0;l<o.length;++l)e.push(o.charCodeAt(l))}else Array.isArray(e)||(e=Array.prototype.slice.call(e));e.push(128);let n=e.length/4+2,i=Math.ceil(n/16),s=new Array(i);for(let o=0;o<i;++o){let l=new Uint32Array(16);for(let a=0;a<16;++a)l[a]=e[o*64+a*4]<<24|e[o*64+a*4+1]<<16|e[o*64+a*4+2]<<8|e[o*64+a*4+3];s[o]=l}s[i-1][14]=(e.length-1)*8/Math.pow(2,32),s[i-1][14]=Math.floor(s[i-1][14]),s[i-1][15]=(e.length-1)*8&4294967295;for(let o=0;o<i;++o){let l=new Uint32Array(80);for(let d=0;d<16;++d)l[d]=s[o][d];for(let d=16;d<80;++d)l[d]=re(l[d-3]^l[d-8]^l[d-14]^l[d-16],1);let a=t[0],u=t[1],c=t[2],y=t[3],f=t[4];for(let d=0;d<80;++d){let P=Math.floor(d/20),I=re(a,5)+St(P,u,c,y)+f+r[P]+l[d]>>>0;f=y,y=c,c=re(u,30)>>>0,u=a,a=I}t[0]=t[0]+a>>>0,t[1]=t[1]+u>>>0,t[2]=t[2]+c>>>0,t[3]=t[3]+y>>>0,t[4]=t[4]+f>>>0}return[t[0]>>24&255,t[0]>>16&255,t[0]>>8&255,t[0]&255,t[1]>>24&255,t[1]>>16&255,t[1]>>8&255,t[1]&255,t[2]>>24&255,t[2]>>16&255,t[2]>>8&255,t[2]&255,t[3]>>24&255,t[3]>>16&255,t[3]>>8&255,t[3]&255,t[4]>>24&255,t[4]>>16&255,t[4]>>8&255,t[4]&255]}var Ct=It;$.default=Ct});var xe=h(k=>{"use strict";Object.defineProperty(k,"__esModule",{value:!0});k.default=void 0;var Rt=be(te()),jt=be(we());function be(e){return e&&e.__esModule?e:{default:e}}var Mt=(0,Rt.default)("v5",80,jt.default),Ut=Mt;k.default=Ut});var Oe=h(K=>{"use strict";Object.defineProperty(K,"__esModule",{value:!0});K.default=void 0;var Dt="00000000-0000-0000-0000-000000000000";K.default=Dt});var Ee=h(H=>{"use strict";Object.defineProperty(H,"__esModule",{value:!0});H.default=void 0;var qt=Nt(T());function Nt(e){return e&&e.__esModule?e:{default:e}}function Lt(e){if(!(0,qt.default)(e))throw TypeError("Invalid UUID");return parseInt(e.slice(14,15),16)}var Vt=Lt;H.default=Vt});var Pe=h(w=>{"use strict";Object.defineProperty(w,"__esModule",{value:!0});Object.defineProperty(w,"NIL",{enumerable:!0,get:function(){return Ft.default}});Object.defineProperty(w,"parse",{enumerable:!0,get:function(){return Xt.default}});Object.defineProperty(w,"stringify",{enumerable:!0,get:function(){return Jt.default}});Object.defineProperty(w,"v1",{enumerable:!0,get:function(){return $t.default}});Object.defineProperty(w,"v3",{enumerable:!0,get:function(){return kt.default}});Object.defineProperty(w,"v4",{enumerable:!0,get:function(){return Kt.default}});Object.defineProperty(w,"v5",{enumerable:!0,get:function(){return Ht.default}});Object.defineProperty(w,"validate",{enumerable:!0,get:function(){return Wt.default}});Object.defineProperty(w,"version",{enumerable:!0,get:function(){return Bt.default}});var $t=b(ue()),kt=b(pe()),Kt=b(ye()),Ht=b(xe()),Ft=b(Oe()),Bt=b(Ee()),Wt=b(T()),Jt=b(S()),Xt=b(ee());function b(e){return e&&e.__esModule?e:{default:e}}});var Pr=h((Hr,$e)=>{var J=Object.defineProperty,zt=Object.defineProperties,Qt=Object.getOwnPropertyDescriptor,Yt=Object.getOwnPropertyDescriptors,Ae=Object.getOwnPropertyNames,B=Object.getOwnPropertySymbols,se=Object.prototype.hasOwnProperty,Se=Object.prototype.propertyIsEnumerable,Te=(e,r,t)=>r in e?J(e,r,{enumerable:!0,configurable:!0,writable:!0,value:t}):e[r]=t,E=(e,r)=>{for(var t in r||(r={}))se.call(r,t)&&Te(e,t,r[t]);if(B)for(var t of B(r))Se.call(r,t)&&Te(e,t,r[t]);return e},W=(e,r)=>zt(e,Yt(r)),Gt=(e,r)=>{var t={};for(var n in e)se.call(e,n)&&r.indexOf(n)<0&&(t[n]=e[n]);if(e!=null&&B)for(var n of B(e))r.indexOf(n)<0&&Se.call(e,n)&&(t[n]=e[n]);return t},Zt=(e,r)=>function(){return r||(0,e[Ae(e)[0]])((r={exports:{}}).exports,r),r.exports},er=(e,r)=>{for(var t in r)J(e,t,{get:r[t],enumerable:!0})},tr=(e,r,t,n)=>{if(r&&typeof r=="object"||typeof r=="function")for(let i of Ae(r))!se.call(e,i)&&i!==t&&J(e,i,{get:()=>r[i],enumerable:!(n=Qt(r,i))||n.enumerable});return e},rr=e=>tr(J({},"__esModule",{value:!0}),e),F=(e,r,t)=>new Promise((n,i)=>{var s=a=>{try{l(t.next(a))}catch(u){i(u)}},o=a=>{try{l(t.throw(a))}catch(u){i(u)}},l=a=>a.done?n(a.value):Promise.resolve(a.value).then(s,o);l((t=t.apply(e,r)).next())}),Ie=Zt({"package.json"(e,r){r.exports={packageManager:"yarn@4.9.2",name:"@reforge-com/javascript",version:"0.0.2",description:"Feature Flags & Dynamic Configuration as a Service",main:"dist/index.cjs",module:"dist/index.mjs",types:"dist/index.d.ts",author:"Jeffrey Chupp",license:"ISC",devDependencies:{"@types/eslint-plugin-jsx-a11y":"^6","@types/express":"^4.17.13","@types/jest":"^28.1.6","@types/uuid":"^9.0.5","@typescript-eslint/eslint-plugin":"^5.33.0","@typescript-eslint/parser":"^5.33.0",esbuild:"^0.25.11",eslint:"^8.21.0","eslint-config-airbnb":"^19.0.4","eslint-config-airbnb-typescript":"^17.0.0","eslint-config-prettier":"^8.8.0","eslint-plugin-import":"^2.26.0","eslint-plugin-jest":"^26.8.0","eslint-plugin-jsx-a11y":"^6.10.2","eslint-plugin-react":"^7.37.5",jest:"^29.0.0","jest-fetch-mock":"^3.0.3",prettier:"^3.0.0","ts-jest":"^29.1.1","ts-node":"^10.9.1",tsup:"^8.0.2",typescript:"^5.1.6"},scripts:{build:"rm -rf dist/ && tsup",dev:"tsup --watch",bundle:"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js",lint:"eslint --ext .ts,.tsx src/","lint:fix":"eslint --fix --ext .ts,.tsx src/",prettier:"prettier . -l","prettier:fix":"prettier --write .",test:"jest --verbose"},repository:{type:"git",url:"https://github.com/ReforgeHQ/sdk-javascript.git"},keywords:["feature-flags","config"],bugs:{url:"https://github.com/ReforgeHQ/sdk-javascript/issues"},homepage:"https://github.com/ReforgeHQ/sdk-javascript#readme",dependencies:{uuid:"^9.0.1"},exports:{".":{types:"./dist/index.d.ts",import:"./dist/index.mjs",require:"./dist/index.cjs"}}}}}),Ce={};er(Ce,{Config:()=>X,Context:()=>ne,Reforge:()=>Ve,reforge:()=>Or,version:()=>Er});$e.exports=rr(Ce);var nr=Pe(),ir=e=>({configRowIndex:parseInt(e.configRowIndex,10),conditionalValueIndex:parseInt(e.conditionalValueIndex,10),type:e.type,configId:e.id}),Re=(e,r,t)=>{let n=e[r];switch(r){case"json":try{return JSON.parse(n)}catch(i){return console.error(`Error parsing JSON from Reforge config ${t}`,i,n),e[r]}case"duration":{let i=n;return{ms:i.millis,seconds:i.millis/1e3}}default:return n}},sr=e=>{let r={};return Object.keys(e.evaluations).forEach(t=>{let n=e.evaluations[t],i=Object.keys(n.value)[0];r[t]=new X(t,Re(n.value,i,t),i,n.value,n.configEvaluationMetadata?ir(n.configEvaluationMetadata):void 0)}),r},or=e=>{let r={};return Object.keys(e).forEach(t=>{let n=typeof e[t];r[t]=new X(t,Re({[n]:e[t]},n,t),n)}),r},X=class{constructor(e,r,t,n,i){this.key=e,this.value=r,this.type=t,this.rawValue=n,this.configEvaluationMetadata=i}static digest(e){return e===void 0&&console.trace("Config.digest called with undefined payload"),"evaluations"in e?sr(e):or(e)}},ar=e=>{if(typeof window<"u"){if(typeof TextEncoder>"u")return window.btoa(e);let r=new TextEncoder().encode(e),t=Array.from(r,n=>String.fromCodePoint(n)).join("");return btoa(t)}return Buffer.from(e).toString("base64")},je=ar,lr=(e,r)=>{let t=Object.keys(e),n=Object.keys(r);return t.length!==n.length?!1:t.every(i=>{let s=e[i],o=r[i],l=Object.keys(s),a=Object.keys(o);return l.length!==a.length?!1:l.every(u=>{let c=s[u],y=o[u];return c===y})})},ur=e=>typeof e=="string"?"string":typeof e=="number"?Number.isInteger(e)?"int":"double":"bool",ne=class{constructor(e){Object.values(e).every(r=>typeof r=="object")||console.error("Context must be an object where the value of each key is also an object"),Object.values(e).some(r=>Object.values(r).some(t=>typeof t=="object"&&t!==null))&&console.error("Nested objects are not supported in context values at this time"),this.contexts=e}equals(e){return lr(this.contexts,e.contexts)}encode(){let e=Object.keys(this.contexts).map(r=>{let t={};return Object.keys(this.contexts[r]).forEach(n=>{t[n]={[ur(this.contexts[r][n])]:this.contexts[r][n]}}),{type:r,values:t}});return encodeURIComponent(je(JSON.stringify({contexts:e})))}},cr=class{constructor(e,r=2,t=2){this.maxDelay=e,this.multiplier=t,this.delay=r}call(){let e=this.delay;return this.delay=Math.min(this.delay*this.multiplier,this.maxDelay),e*1e3}},ie="log-level",fr={TRACE:1,DEBUG:2,INFO:3,WARN:4,ERROR:5,FATAL:6},dr=({loggerName:e,desiredLevel:r,defaultLevel:t,get:n})=>{let i=`${ie}.${e}`;for(;i.length>0;){let s=n(i);if(s)return fr[s.toString().toUpperCase()]<=r;if(i.indexOf(".")===-1)break;i=i.slice(0,i.lastIndexOf("."))}return t<=r},Me=class Ue{constructor(r,t,n){this.data=new Map,this.client=r,this.name=t,this.startAt=new Date,this.startPeriodicSync(n)}stop(){clearTimeout(this.timeoutID)}sync(){if(this.data.size===0)return;this.logInternal(`${this.name} syncing ${this.data.size} items`);let r=this.startAt;this.startAt=new Date,this.flush(this.prepareData(),r)}prepareData(){let r=new Map(this.data);return this.data.clear(),r}startPeriodicSync(r){this.startAt=new Date,this.syncInterval=Ue.calculateSyncInterval(r),this.scheduleNextSync()}scheduleNextSync(){let r=this.syncInterval();this.timeoutID=setTimeout(()=>{this.sync(),this.scheduleNextSync()},r)}static calculateSyncInterval(r){if(r!==void 0)return()=>r;let t=new cr(300,8);return()=>t.call()}logInternal(r){let t=`${this.client.clientNameString}.reforge.${this.name}`;this.client.shouldLog({loggerName:t,desiredLevel:2,defaultLevel:5},!1)&&console.log(`${t}: ${r}`)}},hr=e=>e.rawValue&&(e.type==="duration"||e.type==="json")?e.type==="json"?{json:e.rawValue[e.type]}:e.rawValue[e.type]:e.type==="stringList"?{values:e.value}:e.value,gr=(e,r)=>W(E({},r),{selectedValue:{[e.type]:hr(e)},count:0}),pr=class De extends Me{constructor(r,t,n){super(r,"EvaluationSummaryAggregator",n??3e4),this.maxKeys=t}record(r){if(!(this.data.size>=this.maxKeys)&&r?.configEvaluationMetadata){let t=r.configEvaluationMetadata,{type:n}=t,i=Gt(t,["type"]),s=`${r.key},${n}`;this.data.has(s)||this.data.set(s,gr(r,i));let o=this.data.get(s);o&&(o.count+=1)}}flush(r,t){var n;let i={start:t.getTime(),end:new Date().getTime(),summaries:De.summaries(r)};(n=this.client.telemetryUploader)==null||n.post(this.events(i))}static summaries(r){return Array.from(r).map(t=>{let[n,i]=t[0].split(","),o=[t[1]];return{key:n,type:i,counters:o}})}events(r){let t={summaries:r};return{instanceHash:this.client.instanceHash,events:[t]}}},qe=(e,r)=>({Authorization:`Basic ${je(`u:${e}`)}`,"X-Reforge-SDK-Version":r}),Ne=1e4,vr=["https://primary.reforge.com/api/v2","https://secondary.reforge.com/api/v2"],mr=2e3,_r=class{constructor({sdkKey:e,context:r,endpoints:t=void 0,timeout:n,collectContextMode:i="PERIODIC_EXAMPLE",clientVersion:s=""}){this.collectContextMode="PERIODIC_EXAMPLE",this.isAborted=!1,this.sdkKey=e,this.context=r,this.endpoints=t||vr,this.timeout=n||Ne,this.collectContextMode=i,this.clientVersion=s}url(e){return`${e}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${this.collectContextMode}`}loadFromEndpoint(e,r,t,n){this.abortController=new AbortController;let{signal:i}=this.abortController;this.isAborted=!1;let s=this.endpoints[e],o=this.url(s);fetch(o,E({signal:i},r)).then(a=>{if(this.clearAbortTimeout(),a.ok)return a.json();throw new Error(`${a.status} ${a.statusText}`)}).then(a=>{if(!("evaluations"in a))throw new Error(`Invalid payload:${JSON.stringify(a)}`);t(a)}).catch(a=>{this.clearAbortTimeout(),e<this.endpoints.length-1?this.loadFromEndpoint(e+1,r,t,n):n(a)});let l=e<this.endpoints.length-1?Math.min(this.timeout,mr):this.timeout;this.abortTimeoutId=setTimeout(()=>{var a;this.isAborted||(this.isAborted=!0,(a=this.abortController)==null||a.abort())},l)}load(){var e;this.isAborted||(this.isAborted=!0,(e=this.abortController)==null||e.abort());let r={headers:qe(this.sdkKey,this.clientVersion)};return new Promise((n,i)=>{this.loadFromEndpoint(0,r,n,i)})}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}},yr=class Le{constructor({sdkKey:r,apiEndpoint:t=void 0,timeout:n,clientVersion:i}){this.sdkKey=r,this.apiEndpoint=t||"https://telemetry.prefab.cloud/api/v1",this.timeout=n||Ne,this.clientVersion=i}clearAbortTimeout(){clearTimeout(this.abortTimeoutId)}static postUrl(r){return`${r}/telemetry`}postToEndpoint(r,t,n){let i=new AbortController,s=i?.signal,o=!1,l=Le.postUrl(this.apiEndpoint);fetch(l,E({signal:s},r)).then(a=>(this.clearAbortTimeout(),a.ok?a.json():(console.warn(`Reforge warning: Error uploading telemetry ${a.status} ${a.statusText}`),a.status))).then(a=>{t(a)}).catch(a=>{if(this.clearAbortTimeout(),a.name==="AbortError"){try{console.debug("Reforge telemetry request aborted")}catch{}t({status:"aborted"});return}n(a)}),this.abortTimeoutId=setTimeout(()=>{o||(o=!0,i.abort())},this.timeout)}post(r){let t={method:"POST",headers:W(E({},qe(this.sdkKey,this.clientVersion)),{"Content-Type":"application/json",Accept:"application/json"}),body:JSON.stringify(r),keepalive:!0};return new Promise((i,s)=>{this.postToEndpoint(t,i,s)})}},wr={1:"traces",2:"debugs",3:"infos",4:"warns",5:"errors",6:"fatals"},br=class extends Me{constructor(e,r,t){super(e,"LoggerAggregator",t??3e4),this.maxLoggers=r}record(e,r){if(this.data.size>=this.maxLoggers)return;this.data.has(e)||this.data.set(e,{loggerName:e,traces:0,debugs:0,infos:0,warns:0,errors:0,fatals:0});let t=this.data.get(e);if(t){let n=wr[r];t[n]+=1}}flush(e,r){var t;let n={startAt:r.getTime(),endAt:new Date().getTime(),loggers:Array.from(e.values())};(t=this.client.telemetryUploader)==null||t.post(this.events(n))}events(e){let r={loggers:e};return{instanceHash:this.client.instanceHash,events:[r]}}},{version:xr}=Ie(),Ve=class{constructor(){this._configs={},this._pollCount=0,this._pollStatus={status:"not-started"},this._pollTimeoutId=void 0,this._instanceHash=(0,nr.v4)(),this.collectEvaluationSummaries=!0,this.collectLoggerNames=!1,this.clientNameString="sdk-javascript",this.loaded=!1,this.afterEvaluationCallback=(()=>{}),this._context=new ne({})}init(e){return F(this,arguments,function*({sdkKey:r,context:t,endpoints:n=void 0,apiEndpoint:i,timeout:s=void 0,afterEvaluationCallback:o=()=>{},collectEvaluationSummaries:l=!0,collectLoggerNames:a=!1,collectContextMode:u="PERIODIC_EXAMPLE",clientNameString:c="sdk-javascript",clientVersionString:y=xr}){let f=t??this.context;if(!f)throw new Error("Context must be provided");this._context=f,this.clientNameString=c;let d=`${c}-${y}`;return this.loader=new _r({sdkKey:r,context:f,endpoints:n,timeout:s,collectContextMode:u,clientVersion:d}),this._telemetryUploader=new yr({sdkKey:r,apiEndpoint:i,timeout:s,clientVersion:d}),this.collectEvaluationSummaries=l,l&&(this.evalutionSummaryAggregator=new pr(this,1e5)),this.collectLoggerNames=a,a&&(this.loggerAggregator=new br(this,1e5)),(l||a)&&typeof window<"u"&&typeof window.addEventListener=="function"&&window.addEventListener("beforeunload",()=>{var P,I;(P=this.evalutionSummaryAggregator)==null||P.sync(),(I=this.loggerAggregator)==null||I.sync()}),this.afterEvaluationCallback=o,this.load()})}extract(){return Object.entries(this._configs).reduce((e,[r,t])=>W(E({},e),{[r]:t.value}),{})}hydrate(e){this.setConfigPrivate(e)}get context(){return this._context}get instanceHash(){return this._instanceHash}get pollTimeoutId(){return this._pollTimeoutId}get pollCount(){return this._pollCount}get pollStatus(){return this._pollStatus}get telemetryUploader(){return this._telemetryUploader}load(){return F(this,null,function*(){if(!this.loader||!this.context)throw new Error("Reforge not initialized. Call init() first.");if(globalThis&&globalThis._reforgeBootstrap){let e=globalThis._reforgeBootstrap,r=new ne(e.context);if(this.context.equals(r))return this.setConfigPrivate({evaluations:e.evaluations}),Promise.resolve()}return this.loader.context=this.context,this.loader.load().then(e=>{this.setConfigPrivate(e)}).finally(()=>{this.pollStatus.status==="running"&&(this._pollCount+=1)})})}updateContext(e,r=!1){return F(this,null,function*(){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this._context=e,r?Promise.resolve():this.load()})}poll(e){return F(this,arguments,function*({frequencyInMs:r}){if(!this.loader)throw new Error("Reforge not initialized. Call init() first.");return this.stopPolling(),this._pollStatus={status:"pending"},this.loader.load().finally(()=>{this.doPolling({frequencyInMs:r})})})}doPolling({frequencyInMs:e}){this._pollTimeoutId=setTimeout(()=>{this.load().finally(()=>{this.pollStatus.status==="running"&&this.doPolling({frequencyInMs:e})})},e),this._pollStatus={status:"running",frequencyInMs:e}}stopPolling(){this.pollTimeoutId&&(clearTimeout(this.pollTimeoutId),this._pollTimeoutId=void 0),this._pollStatus={status:"stopped"}}stopTelemetry(){var e,r;this.telemetryUploader&&((e=this.evalutionSummaryAggregator)==null||e.stop(),(r=this.loggerAggregator)==null||r.stop())}setConfigPrivate(e){this._configs=X.digest(e),this.loaded=!0}isEnabled(e){return this.get(e)===!0}get(e){if(!this.loaded){e.startsWith(ie)||console.warn(`Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key "${e}".`);return}let r=this._configs[e],t=r?.value;return e.startsWith(ie)||(this.collectEvaluationSummaries&&setTimeout(()=>{var n;return(n=this.evalutionSummaryAggregator)==null?void 0:n.record(r)}),setTimeout(()=>this.afterEvaluationCallback(e,t,this.context))),t}getDuration(e){let r=this.get(e);if(r){if(!Object.prototype.hasOwnProperty.call(r,"seconds")||!Object.prototype.hasOwnProperty.call(r,"ms"))throw new Error(`Value for key "${e}" is not a duration`);return r}}shouldLog(e,r=!0){if(this.collectLoggerNames){let t=()=>{var n;return(n=this.loggerAggregator)==null?void 0:n.record(e.loggerName,e.desiredLevel)};r?setTimeout(t):t()}return dr(W(E({},e),{get:this.get.bind(this)}))}isCollectingEvaluationSummaries(){return this.collectEvaluationSummaries}isCollectingLoggerNames(){return this.collectLoggerNames}},Or=new Ve,{version:Er}=Ie()});return Pr();})();
window.reforge = window.reforgeNamespace.reforge
+4
-0
# Changelog
## 0.0.2 - 2025-10-30
- fix: include the dist/reforge.bundle.js in our published NPM package
## 0.0.1 - 2025-10-01

@@ -4,0 +8,0 @@

+2
-1

@@ -78,3 +78,3 @@ "use strict";

name: "@reforge-com/javascript",
version: "0.0.1",
version: "0.0.2",
description: "Feature Flags & Dynamic Configuration as a Service",

@@ -93,2 +93,3 @@ main: "dist/index.cjs",

"@typescript-eslint/parser": "^5.33.0",
esbuild: "^0.25.11",
eslint: "^8.21.0",

@@ -95,0 +96,0 @@ "eslint-config-airbnb": "^19.0.4",

@@ -1,1 +0,1 @@

{"version":3,"sources":["../package.json","../index.ts","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.1\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport { reforge, Reforge, ReforgeInitParams, Config, Context, version };\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n","import { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport { PREFIX as loggerPrefix, shouldLog, ShouldLogParams } from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n let loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n while (loggerNameWithPrefix.length > 0) {\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n if (loggerNameWithPrefix.indexOf(\".\") === -1) {\n break;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(0, loggerNameWithPrefix.lastIndexOf(\".\"));\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.prefab.cloud/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n"],"mappings":"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","names":["exports","module","version","uuid","version"]}
{"version":3,"sources":["../package.json","../index.ts","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.2\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport { reforge, Reforge, ReforgeInitParams, Config, Context, version };\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n","import { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport { PREFIX as loggerPrefix, shouldLog, ShouldLogParams } from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n let loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n while (loggerNameWithPrefix.length > 0) {\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n if (loggerNameWithPrefix.indexOf(\".\") === -1) {\n break;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(0, loggerNameWithPrefix.lastIndexOf(\".\"));\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.prefab.cloud/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n"],"mappings":"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","names":["exports","module","version","uuid","version"]}

@@ -63,3 +63,3 @@ var __defProp = Object.defineProperty;

name: "@reforge-com/javascript",
version: "0.0.1",
version: "0.0.2",
description: "Feature Flags & Dynamic Configuration as a Service",

@@ -78,2 +78,3 @@ main: "dist/index.cjs",

"@typescript-eslint/parser": "^5.33.0",
esbuild: "^0.25.11",
eslint: "^8.21.0",

@@ -80,0 +81,0 @@ "eslint-config-airbnb": "^19.0.4",

@@ -1,1 +0,1 @@

{"version":3,"sources":["../package.json","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts","../index.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.1\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport { PREFIX as loggerPrefix, shouldLog, ShouldLogParams } from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n let loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n while (loggerNameWithPrefix.length > 0) {\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n if (loggerNameWithPrefix.indexOf(\".\") === -1) {\n break;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(0, loggerNameWithPrefix.lastIndexOf(\".\"));\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.prefab.cloud/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport { reforge, Reforge, ReforgeInitParams, Config, Context, version };\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n"],"mappings":"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","names":["version"]}
{"version":3,"sources":["../package.json","../src/reforge.ts","../src/config.ts","../src/base64Encode.ts","../src/context.ts","../src/exponentialBackoff.ts","../src/logger.ts","../src/periodicSync.ts","../src/evaluationSummaryAggregator.ts","../src/apiHelpers.ts","../src/loader.ts","../src/telemetryUploader.ts","../src/loggerAggregator.ts","../index.ts"],"sourcesContent":["{\n \"packageManager\": \"yarn@4.9.2\",\n \"name\": \"@reforge-com/javascript\",\n \"version\": \"0.0.2\",\n \"description\": \"Feature Flags & Dynamic Configuration as a Service\",\n \"main\": \"dist/index.cjs\",\n \"module\": \"dist/index.mjs\",\n \"types\": \"dist/index.d.ts\",\n \"author\": \"Jeffrey Chupp\",\n \"license\": \"ISC\",\n \"devDependencies\": {\n \"@types/eslint-plugin-jsx-a11y\": \"^6\",\n \"@types/express\": \"^4.17.13\",\n \"@types/jest\": \"^28.1.6\",\n \"@types/uuid\": \"^9.0.5\",\n \"@typescript-eslint/eslint-plugin\": \"^5.33.0\",\n \"@typescript-eslint/parser\": \"^5.33.0\",\n \"esbuild\": \"^0.25.11\",\n \"eslint\": \"^8.21.0\",\n \"eslint-config-airbnb\": \"^19.0.4\",\n \"eslint-config-airbnb-typescript\": \"^17.0.0\",\n \"eslint-config-prettier\": \"^8.8.0\",\n \"eslint-plugin-import\": \"^2.26.0\",\n \"eslint-plugin-jest\": \"^26.8.0\",\n \"eslint-plugin-jsx-a11y\": \"^6.10.2\",\n \"eslint-plugin-react\": \"^7.37.5\",\n \"jest\": \"^29.0.0\",\n \"jest-fetch-mock\": \"^3.0.3\",\n \"prettier\": \"^3.0.0\",\n \"ts-jest\": \"^29.1.1\",\n \"ts-node\": \"^10.9.1\",\n \"tsup\": \"^8.0.2\",\n \"typescript\": \"^5.1.6\"\n },\n \"scripts\": {\n \"build\": \"rm -rf dist/ && tsup\",\n \"dev\": \"tsup --watch\",\n \"bundle\": \"esbuild --minify --target=esnext --bundle --outfile=dist/reforge.bundle.js --global-name=window.reforgeNamespace dist/index.cjs && echo 'window.reforge = window.reforgeNamespace.reforge' >> dist/reforge.bundle.js\",\n \"lint\": \"eslint --ext .ts,.tsx src/\",\n \"lint:fix\": \"eslint --fix --ext .ts,.tsx src/\",\n \"prettier\": \"prettier . -l\",\n \"prettier:fix\": \"prettier --write .\",\n \"test\": \"jest --verbose\"\n },\n \"repository\": {\n \"type\": \"git\",\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript.git\"\n },\n \"keywords\": [\n \"feature-flags\",\n \"config\"\n ],\n \"bugs\": {\n \"url\": \"https://github.com/ReforgeHQ/sdk-javascript/issues\"\n },\n \"homepage\": \"https://github.com/ReforgeHQ/sdk-javascript#readme\",\n \"dependencies\": {\n \"uuid\": \"^9.0.1\"\n },\n \"exports\": {\n \".\": {\n \"types\": \"./dist/index.d.ts\",\n \"import\": \"./dist/index.mjs\",\n \"require\": \"./dist/index.cjs\"\n }\n }\n}\n","import { v4 as uuid } from \"uuid\";\n\nimport { Config, EvaluationPayload, RawConfigWithoutTypes } from \"./config\";\nimport type {\n Duration,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n Contexts,\n} from \"./types\";\nimport Context from \"./context\";\nimport { EvaluationSummaryAggregator } from \"./evaluationSummaryAggregator\";\nimport Loader, { CollectContextModeType } from \"./loader\";\nimport { PREFIX as loggerPrefix, shouldLog, ShouldLogParams } from \"./logger\";\nimport TelemetryUploader from \"./telemetryUploader\";\nimport { LoggerAggregator } from \"./loggerAggregator\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"../package.json\");\n\ntype EvaluationCallback = <K extends keyof TypedFrontEndConfigurationRaw>(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n context: Context | undefined\n) => void;\n\nexport interface ReforgeBootstrap {\n evaluations: EvaluationPayload;\n context: Contexts;\n}\n\nexport type ReforgeInitParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n apiEndpoint?: string;\n timeout?: number;\n afterEvaluationCallback?: EvaluationCallback;\n collectEvaluationSummaries?: boolean;\n collectLoggerNames?: boolean;\n collectContextMode?: CollectContextModeType;\n clientNameString?: string;\n clientVersionString?: string;\n};\n\ntype PollStatus =\n | { status: \"not-started\" }\n | { status: \"pending\" }\n | { status: \"stopped\" }\n | { status: \"running\"; frequencyInMs: number };\n\ntype PublicShouldLogParams = Omit<ShouldLogParams, \"get\">;\n\nexport class Reforge {\n private _configs: { [key: string]: Config } = {};\n\n private _telemetryUploader: TelemetryUploader | undefined;\n\n private _pollCount = 0;\n\n private _pollStatus: PollStatus = { status: \"not-started\" };\n\n private _pollTimeoutId = undefined as ReturnType<typeof setTimeout> | undefined;\n\n private _instanceHash: string = uuid();\n\n private collectEvaluationSummaries = true;\n\n private collectLoggerNames = false;\n\n private evalutionSummaryAggregator: EvaluationSummaryAggregator | undefined;\n\n private loggerAggregator: LoggerAggregator | undefined;\n\n public clientNameString = \"sdk-javascript\";\n\n public loaded = false;\n\n public loader: Loader | undefined;\n\n public afterEvaluationCallback = (() => {}) as EvaluationCallback;\n\n private _context: Context = new Context({});\n\n async init({\n sdkKey,\n context: providedContext,\n endpoints = undefined,\n apiEndpoint,\n timeout = undefined,\n afterEvaluationCallback = () => {},\n collectEvaluationSummaries = true,\n collectLoggerNames = false,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientNameString = \"sdk-javascript\",\n clientVersionString = version,\n }: ReforgeInitParams) {\n const context = providedContext ?? this.context;\n\n if (!context) {\n throw new Error(\"Context must be provided\");\n }\n\n this._context = context;\n\n this.clientNameString = clientNameString;\n const clientNameAndVersionString = `${clientNameString}-${clientVersionString}`;\n\n this.loader = new Loader({\n sdkKey,\n context,\n endpoints,\n timeout,\n collectContextMode,\n clientVersion: clientNameAndVersionString,\n });\n\n this._telemetryUploader = new TelemetryUploader({\n sdkKey,\n apiEndpoint,\n timeout,\n clientVersion: clientNameAndVersionString,\n });\n\n this.collectEvaluationSummaries = collectEvaluationSummaries;\n if (collectEvaluationSummaries) {\n this.evalutionSummaryAggregator = new EvaluationSummaryAggregator(this, 100000);\n }\n\n this.collectLoggerNames = collectLoggerNames;\n if (collectLoggerNames) {\n this.loggerAggregator = new LoggerAggregator(this, 100000);\n }\n\n if (\n (collectEvaluationSummaries || collectLoggerNames) &&\n typeof window !== \"undefined\" &&\n typeof window.addEventListener === \"function\"\n ) {\n window.addEventListener(\"beforeunload\", () => {\n this.evalutionSummaryAggregator?.sync();\n this.loggerAggregator?.sync();\n });\n }\n\n this.afterEvaluationCallback = afterEvaluationCallback;\n\n return this.load();\n }\n\n public extract(): Record<string, Config[\"value\"]> {\n return Object.entries(this._configs).reduce(\n (agg, [key, value]) => ({\n ...agg,\n [key]: value.value,\n }),\n {} as Record<string, Config[\"value\"]>\n );\n }\n\n public hydrate(rawValues: RawConfigWithoutTypes | EvaluationPayload): void {\n this.setConfigPrivate(rawValues);\n }\n\n get context(): Context {\n return this._context;\n }\n\n get instanceHash(): string {\n return this._instanceHash;\n }\n\n get pollTimeoutId() {\n return this._pollTimeoutId;\n }\n\n get pollCount() {\n return this._pollCount;\n }\n\n get pollStatus() {\n return this._pollStatus;\n }\n\n get telemetryUploader(): TelemetryUploader | undefined {\n return this._telemetryUploader;\n }\n\n private async load() {\n if (!this.loader || !this.context) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n /* eslint-disable no-underscore-dangle */\n if (globalThis && (globalThis as any)._reforgeBootstrap) {\n /* eslint-disable no-underscore-dangle */\n const reforgeBootstrap = (globalThis as any)._reforgeBootstrap as ReforgeBootstrap;\n const bootstrapContext = new Context(reforgeBootstrap.context);\n\n if (this.context.equals(bootstrapContext)) {\n this.setConfigPrivate({ evaluations: reforgeBootstrap.evaluations });\n return Promise.resolve();\n }\n }\n\n // make sure we have the freshest context\n this.loader.context = this.context;\n\n return this.loader\n .load()\n .then((rawValues: any) => {\n this.setConfigPrivate(rawValues as EvaluationPayload);\n })\n .finally(() => {\n if (this.pollStatus.status === \"running\") {\n this._pollCount += 1;\n }\n });\n }\n\n async updateContext(context: Context, skipLoad = false) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this._context = context;\n\n if (skipLoad) {\n return Promise.resolve();\n }\n\n return this.load();\n }\n\n async poll({ frequencyInMs }: { frequencyInMs: number }) {\n if (!this.loader) {\n throw new Error(\"Reforge not initialized. Call init() first.\");\n }\n\n this.stopPolling();\n\n this._pollStatus = { status: \"pending\" };\n\n return this.loader.load().finally(() => {\n this.doPolling({ frequencyInMs });\n });\n }\n\n private doPolling({ frequencyInMs }: { frequencyInMs: number }) {\n this._pollTimeoutId = setTimeout(() => {\n this.load().finally(() => {\n if (this.pollStatus.status === \"running\") {\n this.doPolling({ frequencyInMs });\n }\n });\n }, frequencyInMs);\n\n this._pollStatus = {\n status: \"running\",\n frequencyInMs,\n };\n }\n\n stopPolling() {\n if (this.pollTimeoutId) {\n clearTimeout(this.pollTimeoutId);\n this._pollTimeoutId = undefined;\n }\n\n this._pollStatus = { status: \"stopped\" };\n }\n\n stopTelemetry() {\n if (this.telemetryUploader) {\n this.evalutionSummaryAggregator?.stop();\n this.loggerAggregator?.stop();\n }\n }\n\n private setConfigPrivate(rawValues: RawConfigWithoutTypes | EvaluationPayload) {\n this._configs = Config.digest(rawValues);\n this.loaded = true;\n }\n\n isEnabled<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends boolean\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): boolean {\n return this.get(key) === true;\n }\n\n get<K extends keyof TypedFrontEndConfigurationRaw>(key: K): TypedFrontEndConfigurationRaw[K] {\n if (!this.loaded) {\n if (!key.startsWith(loggerPrefix)) {\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: The client has not finished loading data yet. Unable to look up actual value for key \"${key}\".`\n );\n }\n\n return undefined;\n }\n\n const config = this._configs[key];\n\n const value = config?.value;\n\n if (!key.startsWith(loggerPrefix)) {\n if (this.collectEvaluationSummaries) {\n setTimeout(() => this.evalutionSummaryAggregator?.record(config));\n }\n\n setTimeout(() => this.afterEvaluationCallback(key, value, this.context));\n }\n\n return value;\n }\n\n getDuration<\n // We need to calcuate these live and not store in a type to ensure dynamic evaluation\n // in upstream libraries that override the FrontEndConfigurationRaw interface\n K extends keyof FrontEndConfigurationRaw extends never\n ? string\n : {\n [IK in keyof TypedFrontEndConfigurationRaw]: TypedFrontEndConfigurationRaw[IK] extends Duration\n ? IK\n : never;\n }[keyof TypedFrontEndConfigurationRaw],\n >(key: K): Duration | undefined {\n const value = this.get(key);\n\n if (!value) {\n return undefined;\n }\n\n if (\n !Object.prototype.hasOwnProperty.call(value, \"seconds\") ||\n !Object.prototype.hasOwnProperty.call(value, \"ms\")\n ) {\n throw new Error(`Value for key \"${key}\" is not a duration`);\n }\n\n return value as Duration;\n }\n\n shouldLog(args: PublicShouldLogParams, async = true): boolean {\n if (this.collectLoggerNames) {\n const record = () => this.loggerAggregator?.record(args.loggerName, args.desiredLevel);\n if (async) {\n setTimeout(record);\n } else {\n record();\n }\n }\n\n return shouldLog({ ...args, get: this.get.bind(this) });\n }\n\n isCollectingEvaluationSummaries(): boolean {\n return this.collectEvaluationSummaries;\n }\n\n isCollectingLoggerNames(): boolean {\n return this.collectLoggerNames;\n }\n}\n\nexport const reforge = new Reforge();\n","import { ReforgeLogLevel } from \"./logger\";\nimport { TypedFrontEndConfigurationRaw, ConfigEvaluationMetadata } from \"./types\";\n\nexport type RawConfigWithoutTypes = Record<string, any>;\n\ntype APIKeyMetadata = {\n id: string | number;\n};\n\n// TODO: Why is this definition different from the one in ./types.ts?\ntype Duration = {\n definition: string;\n millis: number;\n};\n\nexport interface IntRange {\n /** if empty treat as Number.MIN_VALUE. Inclusive */\n start?: bigint | undefined;\n /** if empty treat as Number.MAX_VALUE. Exclusive */\n end?: bigint | undefined;\n}\n\nexport enum ProvidedSource {\n EnvVar = \"ENV_VAR\",\n}\nexport interface Provided {\n source?: ProvidedSource | undefined;\n /** eg MY_ENV_VAR */\n lookup?: string | undefined;\n}\n\nexport enum SchemaType {\n UNKNOWN = 0,\n ZOD = 1,\n JSON_SCHEMA = 2,\n}\n\nexport interface Schema {\n schema: string;\n schemaType: SchemaType;\n}\n\nexport interface WeightedValue {\n /** out of 1000 */\n weight: number;\n // eslint-disable-next-line no-use-before-define\n value: ConfigValue | undefined;\n}\n\nexport enum LimitResponse_LimitPolicyNames {\n SecondlyRolling = 1,\n MinutelyRolling = 3,\n HourlyRolling = 5,\n DailyRolling = 7,\n MonthlyRolling = 8,\n Infinite = 9,\n YearlyRolling = 10,\n}\n\nexport enum LimitDefinition_SafetyLevel {\n L4_BEST_EFFORT = 4,\n L5_BOMBPROOF = 5,\n}\n\nexport interface LimitDefinition {\n policyName: LimitResponse_LimitPolicyNames;\n limit: number;\n burst: number;\n accountId: number;\n lastModified: number;\n returnable: boolean;\n /** [default = L4_BEST_EFFORT]; // Overridable by request */\n safetyLevel: LimitDefinition_SafetyLevel;\n}\nexport interface WeightedValues {\n weightedValues: WeightedValue[];\n hashByPropertyName?: string | undefined;\n}\n\nexport type ConfigValue =\n | {\n int: number | undefined;\n }\n | {\n string: string | undefined;\n }\n | {\n bytes: Buffer | undefined;\n }\n | {\n double: number | undefined;\n }\n | {\n bool: boolean | undefined;\n }\n | {\n weightedValues?: WeightedValues | undefined;\n }\n | {\n limitDefinition?: LimitDefinition | undefined;\n }\n | {\n logLevel: ReforgeLogLevel | undefined;\n }\n | {\n stringList: string[] | undefined;\n }\n | {\n intRange: IntRange | undefined;\n }\n | {\n provided: Provided | undefined;\n }\n | {\n duration: Duration | undefined;\n }\n | {\n json: string | undefined;\n }\n | {\n schema: Schema | undefined;\n }\n | {\n /** don't log or telemetry this value */\n confidential: boolean | undefined;\n }\n | {\n /** key name to decrypt with */\n decryptWith: string | undefined;\n };\n\ntype Evaluation = {\n value: ConfigValue;\n configEvaluationMetadata: {\n configRowIndex: string | number;\n conditionalValueIndex: string | number;\n weightedValueIndex?: string | number;\n type: string;\n valueType: string;\n id: string;\n };\n};\n\nexport type EvaluationPayload = {\n evaluations: { [key: string]: Evaluation };\n apikeyMetadata: APIKeyMetadata;\n};\n\nconst parseRawMetadata = (metadata: any) => ({\n configRowIndex: parseInt(metadata.configRowIndex, 10),\n conditionalValueIndex: parseInt(metadata.conditionalValueIndex, 10),\n type: metadata.type,\n configId: metadata.id,\n});\n\nconst valueFor = <K extends keyof TypedFrontEndConfigurationRaw>(\n value: ConfigValue,\n type: keyof ConfigValue,\n key: K\n): TypedFrontEndConfigurationRaw[K] => {\n const rawValue = value[type];\n\n switch (type) {\n case \"json\":\n try {\n return JSON.parse(rawValue as string);\n } catch (e) {\n // eslint-disable-next-line no-console\n console.error(`Error parsing JSON from Reforge config ${key}`, e, rawValue);\n return value[type];\n }\n case \"duration\": {\n const duration = rawValue as Duration;\n return {\n ms: duration.millis,\n seconds: duration.millis / 1000,\n };\n }\n default:\n return rawValue;\n }\n};\n\nexport const parseEvaluationPayload = (payload: EvaluationPayload) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload.evaluations).forEach((key) => {\n const evaluation = payload.evaluations[key];\n\n const type = Object.keys(evaluation.value)[0] as keyof ConfigValue;\n\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(\n key,\n valueFor(evaluation.value, type, key),\n type,\n evaluation.value,\n evaluation.configEvaluationMetadata\n ? parseRawMetadata(evaluation.configEvaluationMetadata)\n : undefined\n );\n });\n\n return configs;\n};\n\nconst parseRawConfigWithoutTypes = (payload: RawConfigWithoutTypes) => {\n // eslint-disable-next-line no-use-before-define\n const configs = {} as { [key: string]: Config };\n Object.keys(payload).forEach((key) => {\n const type = typeof payload[key] as keyof ConfigValue;\n // eslint-disable-next-line no-use-before-define\n configs[key] = new Config(key, valueFor({ [type]: payload[key] }, type, key), type);\n });\n\n return configs;\n};\n\nexport class Config<\n K extends keyof TypedFrontEndConfigurationRaw = keyof TypedFrontEndConfigurationRaw,\n> {\n key: K;\n\n value: TypedFrontEndConfigurationRaw[K];\n\n rawValue: ConfigValue | undefined;\n\n type: keyof ConfigValue;\n\n configEvaluationMetadata: ConfigEvaluationMetadata | undefined;\n\n constructor(\n key: K,\n value: TypedFrontEndConfigurationRaw[K],\n type: keyof ConfigValue,\n rawValue?: ConfigValue,\n metadata?: ConfigEvaluationMetadata\n ) {\n this.key = key;\n this.value = value;\n this.type = type;\n this.rawValue = rawValue;\n this.configEvaluationMetadata = metadata;\n }\n\n static digest(payload: EvaluationPayload | RawConfigWithoutTypes) {\n if (payload === undefined) {\n // eslint-disable-next-line no-console\n console.trace(\"Config.digest called with undefined payload\");\n }\n\n if (\"evaluations\" in payload) {\n return parseEvaluationPayload(payload as EvaluationPayload);\n }\n\n return parseRawConfigWithoutTypes(payload as RawConfigWithoutTypes);\n }\n}\n","const base64Encode = (obj: string) => {\n if (typeof window !== \"undefined\") {\n if (typeof TextEncoder === \"undefined\") {\n return window.btoa(obj);\n }\n\n const bytes = new TextEncoder().encode(obj);\n const binString = Array.from(bytes, (byte) => String.fromCodePoint(byte)).join(\"\");\n return btoa(binString);\n }\n\n return Buffer.from(obj).toString(\"base64\");\n};\n\nexport default base64Encode;\n","import { Contexts, ContextValue } from \"./types\";\nimport base64Encode from \"./base64Encode\";\n\nconst isEqual = (a: Contexts, b: Contexts) => {\n const aKeys = Object.keys(a);\n const bKeys = Object.keys(b);\n\n if (aKeys.length !== bKeys.length) {\n return false;\n }\n\n return aKeys.every((key) => {\n const aValues = a[key];\n const bValues = b[key];\n\n const aValuesKeys = Object.keys(aValues);\n const bValuesKeys = Object.keys(bValues);\n\n if (aValuesKeys.length !== bValuesKeys.length) {\n return false;\n }\n\n return aValuesKeys.every((ckey) => {\n const aValue = aValues[ckey];\n const bValue = bValues[ckey];\n\n return aValue === bValue;\n });\n });\n};\n\nconst getType = (value: ContextValue) => {\n if (typeof value === \"string\") {\n return \"string\";\n }\n\n if (typeof value === \"number\") {\n if (Number.isInteger(value)) {\n return \"int\";\n }\n\n return \"double\";\n }\n\n return \"bool\";\n};\n\nexport default class Context {\n contexts: Contexts;\n\n constructor(contexts: Contexts) {\n if (!Object.values(contexts).every((item: any) => typeof item === \"object\")) {\n // eslint-disable-next-line no-console\n console.error(\"Context must be an object where the value of each key is also an object\");\n }\n\n if (\n Object.values(contexts).some((item: any) =>\n Object.values(item).some((value: any) => typeof value === \"object\" && value !== null)\n )\n ) {\n // we decided to allow null values, which requres an extra check since typeof null is object\n // eslint-disable-next-line no-console\n console.error(\"Nested objects are not supported in context values at this time\");\n }\n\n this.contexts = contexts;\n }\n\n equals(other: Context) {\n return isEqual(this.contexts, other.contexts);\n }\n\n encode() {\n const formatted = Object.keys(this.contexts).map((key) => {\n const values: Record<string, Record<string, ContextValue>> = {};\n\n Object.keys(this.contexts[key]).forEach((ckey) => {\n values[ckey] = {\n [getType(this.contexts[key][ckey])]: this.contexts[key][ckey],\n };\n });\n\n return {\n type: key,\n values,\n };\n });\n\n return encodeURIComponent(base64Encode(JSON.stringify({ contexts: formatted })));\n }\n}\n","export class ExponentialBackoff {\n private maxDelay: number;\n\n private multiplier: number;\n\n private delay: number;\n\n // arguments are in seconds\n constructor(maxDelay: number, initialDelay = 2, multiplier = 2) {\n this.maxDelay = maxDelay;\n this.multiplier = multiplier;\n this.delay = initialDelay;\n }\n\n call(): number {\n const delayValue = this.delay;\n this.delay = Math.min(this.delay * this.multiplier, this.maxDelay);\n return delayValue * 1000;\n }\n}\n","import { TypedFrontEndConfigurationRaw } from \"./types\";\n\nexport const PREFIX = \"log-level\";\nexport enum ReforgeLogLevel {\n Trace = 1,\n Debug = 2,\n Info = 3,\n Warn = 4,\n Error = 5,\n Fatal = 6,\n}\n\nexport type LogLevelWord = Uppercase<keyof typeof ReforgeLogLevel>;\n\nconst WORD_LEVEL_LOOKUP: Readonly<Record<LogLevelWord, ReforgeLogLevel>> = {\n TRACE: ReforgeLogLevel.Trace,\n DEBUG: ReforgeLogLevel.Debug,\n INFO: ReforgeLogLevel.Info,\n WARN: ReforgeLogLevel.Warn,\n ERROR: ReforgeLogLevel.Error,\n FATAL: ReforgeLogLevel.Fatal,\n};\n\nexport const isValidLogLevel = (possibleLogLevel: string) =>\n Object.keys(WORD_LEVEL_LOOKUP).includes(possibleLogLevel.toUpperCase());\n\nexport interface ShouldLogParams {\n loggerName: string;\n desiredLevel: ReforgeLogLevel;\n defaultLevel: ReforgeLogLevel;\n get: <K extends keyof TypedFrontEndConfigurationRaw>(key: K) => TypedFrontEndConfigurationRaw[K];\n}\n\nexport const shouldLog = ({\n loggerName,\n desiredLevel,\n defaultLevel,\n get,\n}: ShouldLogParams): boolean => {\n let loggerNameWithPrefix = `${PREFIX}.${loggerName}`;\n\n while (loggerNameWithPrefix.length > 0) {\n const resolvedLevel = get(loggerNameWithPrefix);\n\n if (resolvedLevel) {\n return (\n WORD_LEVEL_LOOKUP[resolvedLevel.toString().toUpperCase() as LogLevelWord] <= desiredLevel\n );\n }\n\n if (loggerNameWithPrefix.indexOf(\".\") === -1) {\n break;\n }\n\n loggerNameWithPrefix = loggerNameWithPrefix.slice(0, loggerNameWithPrefix.lastIndexOf(\".\"));\n }\n\n return defaultLevel <= desiredLevel;\n};\n","import { ExponentialBackoff } from \"./exponentialBackoff\";\nimport { ReforgeLogLevel } from \"./logger\";\nimport { type reforge } from \"./reforge\";\n\nabstract class PeriodicSync<T> {\n protected data: Map<string, T> = new Map();\n\n private startAt: Date;\n\n private syncInterval: any;\n\n protected client: typeof reforge;\n\n private name: string;\n\n private timeoutID: ReturnType<typeof setTimeout> | undefined;\n\n constructor(client: typeof reforge, name: string, syncInterval?: number) {\n this.client = client;\n this.name = name;\n\n this.startAt = new Date();\n\n this.startPeriodicSync(syncInterval);\n }\n\n stop(): void {\n clearTimeout(this.timeoutID);\n }\n\n sync(): void {\n if (this.data.size === 0) return;\n\n this.logInternal(`${this.name} syncing ${this.data.size} items`);\n\n const startAtWas = this.startAt;\n this.startAt = new Date();\n\n this.flush(this.prepareData(), startAtWas);\n }\n\n protected abstract flush(toShip: Map<string, T>, startAtWas: Date): void;\n\n private prepareData(): Map<string, T> {\n const toShip = new Map(this.data);\n this.data.clear();\n\n return toShip;\n }\n\n private startPeriodicSync(syncInterval?: number): void {\n this.startAt = new Date();\n this.syncInterval = PeriodicSync.calculateSyncInterval(syncInterval);\n\n this.scheduleNextSync();\n }\n\n private scheduleNextSync() {\n const interval = this.syncInterval();\n this.timeoutID = setTimeout(() => {\n this.sync();\n this.scheduleNextSync(); // Schedule the next sync after the current one completes\n }, interval);\n }\n\n private static calculateSyncInterval(syncInterval?: number): any {\n if (syncInterval !== undefined) {\n return () => syncInterval;\n }\n\n const backoff = new ExponentialBackoff(60 * 5, 8);\n return () => backoff.call();\n }\n\n protected logInternal(message: string): void {\n const loggerName = `${this.client.clientNameString}.reforge.${this.name}`;\n\n if (\n this.client.shouldLog(\n {\n loggerName,\n desiredLevel: ReforgeLogLevel.Debug,\n defaultLevel: ReforgeLogLevel.Error,\n },\n false // synchronous so that this log ends up in the current batch\n )\n ) {\n // eslint-disable-next-line no-console\n console.log(`${loggerName}: ${message}`);\n }\n }\n}\n\nexport { PeriodicSync };\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\n// TODO: flush when we receive a config update (or as a result of a context update...but that should trigger a config update anyway)\n\nimport { PeriodicSync } from \"./periodicSync\";\nimport { Config } from \"./config\";\nimport { type reforge } from \"./reforge\";\nimport {\n ConfigEvaluationCounter,\n ConfigEvaluationSummaries,\n ConfigEvaluationSummary,\n TelemetryEvents,\n ConfigEvaluationMetadata,\n} from \"./types\";\n\nexport const massageSelectedValue = (config: Config): any => {\n if (config.rawValue && (config.type === \"duration\" || config.type === \"json\")) {\n if (config.type === \"json\") {\n return { json: config.rawValue[config.type] };\n }\n\n return config.rawValue[config.type];\n }\n\n return config.type === \"stringList\" ? { values: config.value } : config.value;\n};\n\nexport const massageConfigForTelemetry = (\n config: Config,\n metadata: Omit<ConfigEvaluationMetadata, \"type\">\n) => ({\n ...metadata,\n selectedValue: {\n [config.type]: massageSelectedValue(config),\n },\n count: 0,\n});\n\nclass EvaluationSummaryAggregator extends PeriodicSync<ConfigEvaluationCounter> {\n private maxKeys: number;\n\n constructor(client: typeof reforge, maxKeys: number, syncInterval?: number) {\n super(client, \"EvaluationSummaryAggregator\", syncInterval ?? 30000);\n\n this.maxKeys = maxKeys;\n }\n\n record(config: Config): void {\n if (this.data.size >= this.maxKeys) return;\n\n if (config?.configEvaluationMetadata) {\n const { type, ...metadata } = config.configEvaluationMetadata;\n const key = `${config.key},${type}`;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(key)) {\n this.data.set(key, massageConfigForTelemetry(config, metadata));\n }\n\n // increment count\n const counter = this.data.get(key);\n if (counter) {\n counter.count += 1;\n }\n }\n }\n\n protected flush(toShip: Map<string, ConfigEvaluationCounter>, startAtWas: Date): void {\n const summaries = {\n start: startAtWas.getTime(),\n end: new Date().getTime(),\n summaries: EvaluationSummaryAggregator.summaries(toShip),\n };\n\n this.client.telemetryUploader?.post(this.events(summaries));\n }\n\n private static summaries(data: Map<string, ConfigEvaluationCounter>): ConfigEvaluationSummary[] {\n return Array.from(data).map((entry: [string, ConfigEvaluationCounter]) => {\n const [configKey, configType] = entry[0].split(\",\");\n const counter = entry[1];\n const counters = [counter]; // this client only ever has one set of counter info per key\n\n return {\n key: configKey,\n type: configType,\n counters,\n };\n });\n }\n\n private events(summaries: ConfigEvaluationSummaries): TelemetryEvents {\n const event = { summaries };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { EvaluationSummaryAggregator };\n","import base64Encode from \"./base64Encode\";\n\nexport const headers = (sdkKey: string, clientVersion: string) => ({\n Authorization: `Basic ${base64Encode(`u:${sdkKey}`)}`,\n \"X-Reforge-SDK-Version\": clientVersion,\n});\n\nexport const DEFAULT_TIMEOUT = 10000;\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { EvaluationPayload } from \"./config\";\nimport Context from \"./context\";\n\nexport type CollectContextModeType = \"NONE\" | \"SHAPE_ONLY\" | \"PERIODIC_EXAMPLE\";\n\nexport type LoaderParams = {\n sdkKey: string;\n context: Context;\n endpoints?: string[] | undefined;\n timeout?: number;\n collectContextMode?: CollectContextModeType;\n clientVersion?: string;\n};\n\nexport type Headers = {\n [key: string]: string;\n};\n\nexport type FetchOptions = {\n headers: Headers;\n};\n\nconst defaultEndpoints = [\n \"https://primary.reforge.com/api/v2\",\n \"https://secondary.reforge.com/api/v2\",\n];\n\nconst EARLY_TIMEOUT = 2000;\n\nexport default class Loader {\n sdkKey: string;\n\n context: Context;\n\n endpoints: string[];\n\n timeout: number;\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n collectContextMode: CollectContextModeType = \"PERIODIC_EXAMPLE\";\n\n clientVersion: string;\n\n abortController: AbortController | undefined;\n\n isAborted = false;\n\n constructor({\n sdkKey,\n context,\n endpoints = undefined,\n timeout,\n collectContextMode = \"PERIODIC_EXAMPLE\",\n clientVersion = \"\",\n }: LoaderParams) {\n this.sdkKey = sdkKey;\n this.context = context;\n this.endpoints = endpoints || defaultEndpoints;\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.collectContextMode = collectContextMode;\n this.clientVersion = clientVersion;\n }\n\n url(root: string) {\n return `${root}/configs/eval-with-context/${this.context.encode()}?collectContextMode=${\n this.collectContextMode\n }`;\n }\n\n loadFromEndpoint(\n index: number,\n options: FetchOptions,\n resolve: (value: any) => void,\n reject: (value: any) => void\n ) {\n this.abortController = new AbortController() as AbortController;\n const { signal } = this.abortController;\n this.isAborted = false;\n\n const endpoint = this.endpoints[index];\n const url = this.url(endpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n throw new Error(`${response.status} ${response.statusText}`);\n })\n .then((data) => {\n if (!(\"evaluations\" in data)) {\n throw new Error(`Invalid payload:${JSON.stringify(data)}`);\n }\n\n resolve(data as EvaluationPayload);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n if (index < this.endpoints.length - 1) {\n this.loadFromEndpoint(index + 1, options, resolve, reject);\n } else {\n reject(error);\n }\n });\n\n // Use an early timeout if we're not on the last endpoint. But if the user-provided timeout is less than EARLY_TIMEOUT, use that\n const timeout =\n index < this.endpoints.length - 1 ? Math.min(this.timeout, EARLY_TIMEOUT) : this.timeout;\n\n this.abortTimeoutId = setTimeout(() => {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n }, timeout);\n }\n\n load() {\n if (!this.isAborted) {\n this.isAborted = true;\n this.abortController?.abort();\n }\n\n const options = {\n headers: headers(this.sdkKey, this.clientVersion),\n };\n\n const promise = new Promise((resolve, reject) => {\n this.loadFromEndpoint(0, options, resolve, reject);\n });\n\n return promise;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n}\n","import { DEFAULT_TIMEOUT, headers } from \"./apiHelpers\";\nimport { TelemetryEvents } from \"./types\";\n\nexport type TelemetryUploaderParams = {\n sdkKey: string;\n apiEndpoint?: string;\n timeout?: number;\n clientVersion: string;\n};\n\nexport default class TelemetryUploader {\n sdkKey: Required<TelemetryUploaderParams>[\"sdkKey\"];\n\n apiEndpoint: Required<TelemetryUploaderParams>[\"apiEndpoint\"];\n\n timeout: Required<TelemetryUploaderParams>[\"timeout\"];\n\n clientVersion: Required<TelemetryUploaderParams>[\"clientVersion\"];\n\n abortTimeoutId: ReturnType<typeof setTimeout> | undefined;\n\n constructor({\n sdkKey,\n apiEndpoint = undefined,\n timeout,\n clientVersion,\n }: TelemetryUploaderParams) {\n this.sdkKey = sdkKey;\n this.apiEndpoint = apiEndpoint || \"https://telemetry.prefab.cloud/api/v1\";\n this.timeout = timeout || DEFAULT_TIMEOUT;\n this.clientVersion = clientVersion;\n }\n\n clearAbortTimeout() {\n clearTimeout(this.abortTimeoutId);\n }\n\n static postUrl(root: string) {\n return `${root}/telemetry`;\n }\n\n postToEndpoint(\n options: RequestInit,\n resolve: (value: unknown) => void,\n reject: (value: unknown) => void\n ) {\n const controller = new AbortController() as AbortController;\n const signal = controller?.signal;\n let isAborted = false;\n\n const url = TelemetryUploader.postUrl(this.apiEndpoint);\n\n fetch(url, { signal, ...options })\n .then((response) => {\n this.clearAbortTimeout();\n\n if (response.ok) {\n return response.json();\n }\n\n // eslint-disable-next-line no-console\n console.warn(\n `Reforge warning: Error uploading telemetry ${response.status} ${response.statusText}`\n );\n\n return response.status;\n })\n .then((response) => {\n resolve(response);\n })\n .catch((error) => {\n this.clearAbortTimeout();\n\n // Silently handle AbortErrors (from timeouts or page navigations)\n if (error.name === \"AbortError\") {\n try {\n // eslint-disable-next-line no-console\n console.debug(\"Reforge telemetry request aborted\");\n } catch (e) {\n // no-op\n }\n resolve({ status: \"aborted\" });\n return;\n }\n\n reject(error);\n });\n\n this.abortTimeoutId = setTimeout(() => {\n if (!isAborted) {\n isAborted = true;\n controller.abort();\n }\n }, this.timeout);\n }\n\n post(data: TelemetryEvents) {\n const options = {\n method: \"POST\",\n headers: {\n ...headers(this.sdkKey, this.clientVersion),\n \"Content-Type\": \"application/json\",\n Accept: \"application/json\",\n },\n body: JSON.stringify(data),\n keepalive: true, // needed for flushing when the window is closed\n };\n\n const promise = new Promise((resolve, reject) => {\n this.postToEndpoint(options, resolve, reject);\n });\n\n return promise;\n }\n}\n","// TODO: should we retry the data chunk if a flush fails?\n\n// TODO: pause when offline?\n\nimport { ReforgeLogLevel } from \"./logger\";\nimport { PeriodicSync } from \"./periodicSync\";\nimport { type reforge } from \"./reforge\";\nimport { LoggerCounter, LoggersTelemetryEvent, TelemetryEvents } from \"./types\";\n\nconst SEVERITY_KEY: { [key in ReforgeLogLevel]: Omit<keyof LoggerCounter, \"loggerName\"> } = {\n [ReforgeLogLevel.Trace]: \"traces\",\n [ReforgeLogLevel.Debug]: \"debugs\",\n [ReforgeLogLevel.Info]: \"infos\",\n [ReforgeLogLevel.Warn]: \"warns\",\n [ReforgeLogLevel.Error]: \"errors\",\n [ReforgeLogLevel.Fatal]: \"fatals\",\n};\n\nclass LoggerAggregator extends PeriodicSync<LoggerCounter> {\n private maxLoggers: number;\n\n constructor(client: typeof reforge, maxLoggers: number, syncInterval?: number) {\n super(client, \"LoggerAggregator\", syncInterval ?? 30000);\n\n this.maxLoggers = maxLoggers;\n }\n\n record(logger: string, level: ReforgeLogLevel): void {\n if (this.data.size >= this.maxLoggers) return;\n\n // create counter entry if it doesn't exist\n if (!this.data.has(logger)) {\n this.data.set(logger, {\n loggerName: logger,\n traces: 0,\n debugs: 0,\n infos: 0,\n warns: 0,\n errors: 0,\n fatals: 0,\n });\n }\n\n // increment count\n const counter = this.data.get(logger);\n if (counter) {\n const severityKey = SEVERITY_KEY[level] as keyof LoggerCounter;\n (counter[severityKey] as number) += 1;\n }\n }\n\n protected flush(toShip: Map<string, LoggerCounter>, startAtWas: Date): void {\n const loggers = {\n startAt: startAtWas.getTime(),\n endAt: new Date().getTime(),\n loggers: Array.from(toShip.values()),\n };\n\n this.client.telemetryUploader?.post(this.events(loggers));\n }\n\n private events(loggers: LoggersTelemetryEvent): TelemetryEvents {\n const event = { loggers };\n\n return {\n instanceHash: this.client.instanceHash,\n events: [event],\n };\n }\n}\n\nexport { LoggerAggregator };\n","import { reforge, Reforge, ReforgeInitParams, ReforgeBootstrap } from \"./src/reforge\";\nimport { Config } from \"./src/config\";\nimport Context from \"./src/context\";\n// eslint-disable-next-line @typescript-eslint/no-var-requires\nconst { version } = require(\"./package.json\");\n\nexport { reforge, Reforge, ReforgeInitParams, Config, Context, version };\n\nexport { ReforgeBootstrap };\n\nexport type { ConfigValue } from \"./src/config\";\nexport type {\n Duration,\n ContextValue,\n Contexts,\n TypedFrontEndConfigurationRaw,\n FrontEndConfigurationRaw,\n} from \"./src/types\";\nexport type { CollectContextModeType } from \"./src/loader\";\n"],"mappings":"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","names":["version"]}
{
"packageManager": "yarn@4.9.2",
"name": "@reforge-com/javascript",
"version": "0.0.1",
"version": "0.0.2",
"description": "Feature Flags & Dynamic Configuration as a Service",

@@ -18,2 +18,3 @@ "main": "dist/index.cjs",

"@typescript-eslint/parser": "^5.33.0",
"esbuild": "^0.25.11",
"eslint": "^8.21.0",

@@ -20,0 +21,0 @@ "eslint-config-airbnb": "^19.0.4",