@harnessio/ff-javascript-client-sdk
Advanced tools
Comparing version 1.21.0 to 1.22.0
import type { CacheOptions, Evaluation } from './types'; | ||
export declare function getCacheId(targetIdentifier: string): string; | ||
export declare function loadFromCache(targetIdentifier: string, cacheOptions?: CacheOptions): Evaluation[]; | ||
export declare function saveToCache(targetIdentifier: string, evaluations: Evaluation[]): void; | ||
export declare function updateCachedEvaluation(targetIdentifier: string, evaluation: Evaluation): void; | ||
export declare function removeCachedEvaluation(targetIdentifier: string, flagIdentifier: string): void; | ||
export declare function clearCachedEvaluations(targetIdentifier: string): void; | ||
export declare function getCacheId(seed: string): Promise<string>; | ||
export declare function loadFromCache(cacheId: string, cacheOptions?: CacheOptions): Evaluation[]; | ||
export declare function saveToCache(cacheId: string, evaluations: Evaluation[]): void; | ||
export declare function updateCachedEvaluation(cacheId: string, evaluation: Evaluation): void; | ||
export declare function removeCachedEvaluation(cacheId: string, flagIdentifier: string): void; | ||
export declare function clearCachedEvaluations(cacheId: string): void; |
@@ -1,1 +0,1 @@ | ||
var De=Object.create;var P=Object.defineProperty,we=Object.defineProperties,Ce=Object.getOwnPropertyDescriptor,Fe=Object.getOwnPropertyDescriptors,Ae=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols,Pe=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty,xe=Object.prototype.propertyIsEnumerable;var re=(n,e,a)=>e in n?P(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,T=(n,e)=>{for(var a in e||(e={}))oe.call(e,a)&&re(n,a,e[a]);if(ae)for(var a of ae(e))xe.call(e,a)&&re(n,a,e[a]);return n},U=(n,e)=>we(n,Fe(e));var Ne=(n,e)=>{for(var a in e)P(n,a,{get:e[a],enumerable:!0})},se=(n,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ae(e))!oe.call(n,s)&&s!==a&&P(n,s,{get:()=>e[s],enumerable:!(o=Ce(e,s))||o.enumerable});return n};var le=(n,e,a)=>(a=n!=null?De(Pe(n)):{},se(e||!n||!n.__esModule?P(a,"default",{value:n,enumerable:!0}):a,n)),Ve=n=>se(P({},"__esModule",{value:!0}),n);var w=(n,e,a)=>new Promise((o,s)=>{var g=b=>{try{m(a.next(b))}catch(c){s(c)}},v=b=>{try{m(a.throw(b))}catch(c){s(c)}},m=b=>b.done?o(b.value):Promise.resolve(b.value).then(g,v);m((a=a.apply(n,e)).next())});var Ge={};Ne(Ge,{Event:()=>x,initialize:()=>He});module.exports=Ve(Ge);var Ee=le(require("jwt-decode")),me=le(require("mitt"));var x=(f=>(f.READY="ready",f.CONNECTED="connected",f.DISCONNECTED="disconnected",f.STOPPED="stopped",f.POLLING="polling",f.POLLING_STOPPED="polling stopped",f.FLAGS_LOADED="flags loaded",f.CACHE_LOADED="cache loaded",f.CHANGED="changed",f.ERROR="error",f.ERROR_METRICS="metrics error",f.ERROR_AUTH="auth error",f.ERROR_FETCH_FLAGS="fetch flags error",f.ERROR_FETCH_FLAG="fetch flag error",f.ERROR_STREAM="stream error",f))(x||{});var ke={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},ce=n=>{let e=T(T({},ke),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),j=(n,e=!0)=>{e?setTimeout(n,0):n()},M=(n,e)=>Math.round(Math.random()*(e-n)+n);function J(n){return"HARNESS_FF_CACHE_"+n}function L(n,e={}){let a=J(n),o=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(o)&&o+e.ttl<Date.now())return _e(n),[];let s=window.localStorage.getItem(a);if(s)try{return JSON.parse(s)}catch(g){}return[]}function H(n,e){let a=J(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function de(n,e){let a=L(n),o=a.find(({flag:s})=>s===e.flag);o?Object.assign(o,e):a.push(e),H(n,a)}function ue(n,e){let a=L(n),o=a.findIndex(({flag:s})=>s===e);o>-1&&(a.splice(o,1),H(n,a))}function _e(n){let e=J(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function W(n){return function(...a){let[o,s]=n(a);return fetch(o,s)}}var fe=3e4,G=class{constructor(e,a,o,s,g,v,m){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=a,this.url=o,this.apiKey=s,this.standardHeaders=g,this.eventCallback=m,this.fallbackPoller=v}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let O=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",O),this.eventCallback(O)}},o=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},g=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,O]of Object.entries(v))this.xhr.setRequestHeader(c,O);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,g("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||g(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,g("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){g(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(o(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let m=0,b=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(o(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),b=Date.now();let c=this.xhr.responseText.slice(m);m+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{b<Date.now()-fe&&(y("SSE read timeout"),this.xhr.abort())},fe),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function ge(n,e,a,o,s){let g=n in a,v=g?a[n]:e;return g&&o(n,v),s?{value:v,isDefaultValue:!g}:v}var N=class{constructor(e,a,o){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=o;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return w(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(a.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",a.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,a.error);let o=M(1e3,1e4);yield new Promise(s=>setTimeout(s,o))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var Re="1.21.0",ve=`Javascript ${Re} Client`,Me=500,Le=globalThis.fetch,Y=!!globalThis.Proxy,X=n=>{let{value:e}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){y(a)}return e},He=(n,e,a)=>{let o=!1,s,g,v,m,b,c,O=!0,C={},V=W(t=>t),z=0,Q=!1,f=()=>{O=!1},k=()=>{O=!0},S=[],d=(0,me.default)(),u=ce(a);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let E=(t,...i)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...i)},B=t=>{if(O){let i=Date.now();i-t.lastAccessed>Me&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),k())};let be=(t,i)=>w(void 0,null,function*(){return(yield(yield Le(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":ve},body:JSON.stringify({apiKey:t,target:U(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(S.length){E("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Re}]}))};V(`${u.eventUrl}/metrics/${s}?cluster=${g}`,{method:"POST",headers:T({"Content-Type":"application/json"},C),body:JSON.stringify(t)}).then(()=>{S=[],$=0}).catch(i=>{$++&&(S=[],$=0),E(i),d.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(K,u.eventsSyncInterval)})}else c=window.setTimeout(K,u.eventsSyncInterval)},I={},Se=t=>{E("Sending event for",t.flag),Y?d.emit("changed",new Proxy(t,{get(i,l){var p;if(O&&i.hasOwnProperty(l)&&l==="value"){let R=i.flag,r=t.value,h=S.find(A=>A.featureIdentifier===R&&A.featureValue===r);h?(B(h),h.variationIdentifier=((p=I[R])==null?void 0:p.identifier)||""):S.push({featureIdentifier:R,featureValue:String(r),variationIdentifier:I[R].identifier||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag",l,"has been read with value via stream update",r)}return l==="value"?X(t):t[l]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:X(t)})},Z=function(){return Y?new Proxy({},{get(t,i){var p,R,r;let l=t[i];if(O&&t.hasOwnProperty(i)){let h=t[i],A=S.find(ne=>ne.featureIdentifier===i&&h===ne.featureValue);A?(A.variationIdentifier=((p=I[i])==null?void 0:p.identifier)||"",B(A)):S.push({featureIdentifier:i,featureValue:h,variationIdentifier:((R=I[i])==null?void 0:R.identifier)||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag:",i,"has been read with value:",h,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return l}}):{}},D=Z();be(n,u).then(t=>w(void 0,null,function*(){if(o)return;b=t;let i=(0,Ee.default)(t);C={Authorization:`Bearer ${b}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":ve};let l=btoa(JSON.stringify(e));if(l.length<262144&&(C["Harness-Target"]=l),E("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,E("Picking up metrics from previous session")}catch(r){}c=window.setTimeout(K,u.eventsSyncInterval),s=i.environment,g=i.clusterIdentifier;let p=!!Object.keys(I).length;if((yield _()).type==="success"&&E("Fetch all flags ok",D),!o){if(u.streamEnabled?(E("Streaming mode enabled"),Ie()):u.pollingEnabled?(E("Polling mode enabled"),ye()):E("Streaming and polling mode disabled"),!p){f();let r=T({},D);k(),d.emit("ready",r)}Q=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let _=()=>w(void 0,null,function*(){try{let t=yield V(`${u.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${g}`,{headers:C});if(t.ok){let i=yield t.json();return i.forEach(F),d.emit("flags loaded",i),{type:"success",data:i}}else return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}}),ee=t=>w(void 0,null,function*(){try{let i=yield V(`${u.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${t}?cluster=${g}`,{headers:C});if(i.ok){let l=yield i.json();F(l)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),F=t=>{f();let i=X(t);i!==D[t.flag]&&(E("Flag variation has changed for ",t.identifier),D[t.flag]=i,I[t.flag]=U(T({},t),{value:i}),Se(t)),k()};m=new N(_,u,d);let Ie=()=>{let t=r=>{switch(r.event){case"create":l(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):setTimeout(()=>ee(r.identifier),1e3);break;case"patch":l(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):ee(r.identifier);break;case"delete":delete D[r.identifier],d.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),E("Evaluation deleted",{message:r,storage:D});break}},i=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),l=r=>!(!r||r.length==0||!r.every(h=>i(h))),p=r=>{r.event==="patch"&&(l(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):_())},R=`${u.baseUrl}/stream?cluster=${g}`;v=new G(d,u,R,n,C,m,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&p(r)}),v.start()},ye=()=>{m.start()},q=(t,i)=>d.on(t,i),Oe=(t,i)=>{t?d.off(t,i):te()},Te=(t,i)=>{var r;if(!O||Y||i===void 0)return;let l=i,p=t,R=S.find(h=>h.featureIdentifier===p&&h.featureValue===l);R?(B(R),R.variationIdentifier=((r=I[p])==null?void 0:r.identifier)||""):S.push({featureIdentifier:p,featureValue:l,count:1,variationIdentifier:I[p].identifier||"",lastAccessed:Date.now()})},te=()=>{o=!0,u.streamEnabled&&(E("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&m.isPolling()&&(E("Closing Poller"),m.stop()),D=Z(),I={},clearTimeout(c)},ie=(t,i=!0)=>{t.length&&j(()=>{let l=!!Object.keys(I).length;if(t.forEach(F),!l){f();let p=T({},D);k(),d.emit("ready",p)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=L(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&j(()=>{E("loading from cache",i),ie(i,!1),d.emit("cache loaded",i)}),q("flags loaded",l=>{H(e.identifier,l),t=!1}),q("changed",l=>{t||(l.deleted?ue(e.identifier,l.flag):de(e.identifier,l))})}return{on:q,off:Oe,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{V=W(t)},refreshEvaluations:()=>{Q&&!o&&Date.now()-z>=6e4&&(_(),z=Date.now())},variation:(t,i,l=!1)=>ge(t,i,D,Te,l)}};0&&(module.exports={Event,initialize}); | ||
var De=Object.create;var P=Object.defineProperty,we=Object.defineProperties,Ae=Object.getOwnPropertyDescriptor,Ce=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ne=Object.getOwnPropertySymbols,Pe=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty,xe=Object.prototype.propertyIsEnumerable;var ae=(i,e,a)=>e in i?P(i,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):i[e]=a,T=(i,e)=>{for(var a in e||(e={}))re.call(e,a)&&ae(i,a,e[a]);if(ne)for(var a of ne(e))xe.call(e,a)&&ae(i,a,e[a]);return i},j=(i,e)=>we(i,Ce(e));var Ne=(i,e)=>{for(var a in e)P(i,a,{get:e[a],enumerable:!0})},oe=(i,e,a,o)=>{if(e&&typeof e=="object"||typeof e=="function")for(let l of Fe(e))!re.call(i,l)&&l!==a&&P(i,l,{get:()=>e[l],enumerable:!(o=Ae(e,l))||o.enumerable});return i};var se=(i,e,a)=>(a=i!=null?De(Pe(i)):{},oe(e||!i||!i.__esModule?P(a,"default",{value:i,enumerable:!0}):a,i)),Ve=i=>oe(P({},"__esModule",{value:!0}),i);var w=(i,e,a)=>new Promise((o,l)=>{var h=R=>{try{m(a.next(R))}catch(c){l(c)}},p=R=>{try{m(a.throw(R))}catch(c){l(c)}},m=R=>R.done?o(R.value):Promise.resolve(R.value).then(h,p);m((a=a.apply(i,e)).next())});var Ge={};Ne(Ge,{Event:()=>x,initialize:()=>He});module.exports=Ve(Ge);var Ee=se(require("jwt-decode")),me=se(require("mitt"));var x=(g=>(g.READY="ready",g.CONNECTED="connected",g.DISCONNECTED="disconnected",g.STOPPED="stopped",g.POLLING="polling",g.POLLING_STOPPED="polling stopped",g.FLAGS_LOADED="flags loaded",g.CACHE_LOADED="cache loaded",g.CHANGED="changed",g.ERROR="error",g.ERROR_METRICS="metrics error",g.ERROR_AUTH="auth error",g.ERROR_FETCH_FLAGS="fetch flags error",g.ERROR_FETCH_FLAG="fetch flag error",g.ERROR_STREAM="stream error",g))(x||{});var ke={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},le=i=>{let e=T(T({},ke),i);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(i,...e)=>console.error(`[FF-SDK] ${i}`,...e),q=(i,e=!0)=>{e?setTimeout(i,0):i()},M=(i,e)=>Math.round(Math.random()*(e-i)+i);function ce(i){return w(this,null,function*(){let a=new TextEncoder().encode(i),o=yield crypto.subtle.digest("SHA-256",a);return"HARNESS_FF_CACHE_"+Array.from(new Uint8Array(o)).map(p=>p.toString(16).padStart(2,"0")).join("")})}function L(i,e={}){let a=parseInt(window.localStorage.getItem(i+".ts"));if(e!=null&&e.ttl&&!isNaN(a)&&a+e.ttl<Date.now())return _e(i),[];let o=window.localStorage.getItem(i);if(o)try{return JSON.parse(o)}catch(l){}return[]}function H(i,e){window.localStorage.setItem(i,JSON.stringify(e)),window.localStorage.setItem(i+".ts",Date.now().toString())}function de(i,e){let a=L(i),o=a.find(({flag:l})=>l===e.flag);o?Object.assign(o,e):a.push(e),H(i,a)}function ue(i,e){let a=L(i),o=a.findIndex(({flag:l})=>l===e);o>-1&&(a.splice(o,1),H(i,a))}function _e(i){window.localStorage.removeItem(i),window.localStorage.removeItem(i+".ts")}function J(i){return function(...a){let[o,l]=i(a);return fetch(o,l)}}var fe=3e4,G=class{constructor(e,a,o,l,h,p,m){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=a,this.url=o,this.apiKey=l,this.standardHeaders=h,this.eventCallback=m,this.fallbackPoller=p}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let O=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",O),this.eventCallback(O)}},o=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},l=()=>{clearInterval(this.readTimeoutCheckerId);let c=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},h=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),l()},p=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,O]of Object.entries(p))this.xhr.setRequestHeader(c,O);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,h("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||h(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,h("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){h(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(o(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let m=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(o(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(m);m+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-fe&&(y("SSE read timeout"),this.xhr.abort())},fe),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function ge(i,e,a,o,l){let h=i in a,p=h?a[i]:e;return h&&o(i,p),l?{value:p,isDefaultValue:!h}:p}var N=class{constructor(e,a,o){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=o;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return w(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(a.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",a.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,a.error);let o=M(1e3,1e4);yield new Promise(l=>setTimeout(l,o))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var be="1.22.0",ve=`Javascript ${be} Client`,Me=500,Le=globalThis.fetch,W=!!globalThis.Proxy,Y=i=>{let{value:e}=i;try{switch(i.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){y(a)}return e},He=(i,e,a)=>{let o=!1,l,h,p,m,R,c,O=!0,A={},V=J(t=>t),X=0,z=!1,g=()=>{O=!1},k=()=>{O=!0},S=[],d=(0,me.default)(),f=le(a);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let E=(t,...n)=>{f.debug&&console.debug(`[FF-SDK] ${t}`,...n)},B=t=>{if(O){let n=Date.now();n-t.lastAccessed>Me&&(t.count++,t.lastAccessed=n)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(g(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),k())};let Re=(t,n)=>w(void 0,null,function*(){return(yield(yield Le(`${n.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":ve},body:JSON.stringify({apiKey:t,target:j(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(S.length){E("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(n=>({timestamp:Date.now(),count:n.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:n.featureIdentifier},{key:"featureName",value:n.featureIdentifier},{key:"variationIdentifier",value:n.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:be}]}))};V(`${f.eventUrl}/metrics/${l}?cluster=${h}`,{method:"POST",headers:T({"Content-Type":"application/json"},A),body:JSON.stringify(t)}).then(()=>{S=[],$=0}).catch(n=>{$++&&(S=[],$=0),E(n),d.emit("metrics error",n)}).finally(()=>{c=window.setTimeout(K,f.eventsSyncInterval)})}else c=window.setTimeout(K,f.eventsSyncInterval)},I={},Se=t=>{E("Sending event for",t.flag),W?d.emit("changed",new Proxy(t,{get(n,s){var u;if(O&&n.hasOwnProperty(s)&&s==="value"){let b=n.flag,r=t.value,v=S.find(F=>F.featureIdentifier===b&&F.featureValue===r);v?(B(v),v.variationIdentifier=((u=I[b])==null?void 0:u.identifier)||""):S.push({featureIdentifier:b,featureValue:String(r),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag",s,"has been read with value via stream update",r)}return s==="value"?Y(t):t[s]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:Y(t)})},Q=function(){return W?new Proxy({},{get(t,n){var u,b,r;let s=t[n];if(O&&t.hasOwnProperty(n)){let v=t[n],F=S.find(ie=>ie.featureIdentifier===n&&v===ie.featureValue);F?(F.variationIdentifier=((u=I[n])==null?void 0:u.identifier)||"",B(F)):S.push({featureIdentifier:n,featureValue:v,variationIdentifier:((b=I[n])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag:",n,"has been read with value:",v,"variationIdentifier:",(r=I[n])==null?void 0:r.identifier)}return s}}):{}},D=Q();Re(i,f).then(t=>w(void 0,null,function*(){if(o)return;R=t;let n=(0,Ee.default)(t);A={Authorization:`Bearer ${R}`,"Harness-AccountID":n.accountID,"Harness-EnvironmentID":n.environmentIdentifier,"Harness-SDK-Info":ve};let s=btoa(JSON.stringify(e));if(s.length<262144&&(A["Harness-Target"]=s),E("Authenticated",n),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,E("Picking up metrics from previous session")}catch(r){}c=window.setTimeout(K,f.eventsSyncInterval),l=n.environment,h=n.clusterIdentifier;let u=!!Object.keys(I).length;if((yield _()).type==="success"&&E("Fetch all flags ok",D),!o){if(f.streamEnabled?(E("Streaming mode enabled"),Ie()):f.pollingEnabled?(E("Polling mode enabled"),ye()):E("Streaming and polling mode disabled"),!u){g();let r=T({},D);k(),d.emit("ready",r)}z=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let _=()=>w(void 0,null,function*(){try{let t=yield V(`${f.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${h}`,{headers:A});if(t.ok){let n=yield t.json();return n.forEach(C),d.emit("flags loaded",n),{type:"success",data:n}}else return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}}),Z=t=>w(void 0,null,function*(){try{let n=yield V(`${f.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${h}`,{headers:A});if(n.ok){let s=yield n.json();C(s)}else y("Feature fetch operation error: ",n),d.emit("fetch flag error",n),d.emit("error",n)}catch(n){y("Feature fetch operation error: ",n),d.emit("fetch flag error",n),d.emit("error",n)}}),C=t=>{g();let n=Y(t);n!==D[t.flag]&&(E("Flag variation has changed for ",t.identifier),D[t.flag]=n,I[t.flag]=j(T({},t),{value:n}),Se(t)),k()};m=new N(_,f,d);let Ie=()=>{let t=r=>{switch(r.event){case"create":s(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":s(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):Z(r.identifier);break;case"delete":delete D[r.identifier],d.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),E("Evaluation deleted",{message:r,storage:D});break}},n=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),s=r=>!(!r||r.length==0||!r.every(v=>n(v))),u=r=>{r.event==="patch"&&(s(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):_())},b=`${f.baseUrl}/stream?cluster=${h}`;p=new G(d,f,b,i,A,m,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&u(r)}),p.start()},ye=()=>{m.start()},U=(t,n)=>d.on(t,n),Oe=(t,n)=>{t?d.off(t,n):ee()},Te=(t,n)=>{var r;if(!O||W||n===void 0)return;let s=n,u=t,b=S.find(v=>v.featureIdentifier===u&&v.featureValue===s);b?(B(b),b.variationIdentifier=((r=I[u])==null?void 0:r.identifier)||""):S.push({featureIdentifier:u,featureValue:s,count:1,variationIdentifier:I[u].identifier||"",lastAccessed:Date.now()})},ee=()=>{o=!0,f.streamEnabled&&(E("Closing event stream"),typeof(p==null?void 0:p.close)=="function"&&p.close(),d.all.clear()),f.pollingEnabled&&m.isPolling()&&(E("Closing Poller"),m.stop()),D=Q(),I={},clearTimeout(c)},te=(t,n=!0)=>{t.length&&q(()=>{let s=!!Object.keys(I).length;if(t.forEach(C),!s){g();let u=T({},D);k(),d.emit("ready",u)}},n)};return f.cache&&"localStorage"in window&&ce(e.identifier+i).then(t=>{let n=!0,s=L(t,typeof f.cache=="boolean"?{}:f.cache);s!=null&&s.length&&q(()=>{E("loading from cache",s),te(s,!1),d.emit("cache loaded",s)}),U("flags loaded",u=>{H(t,u),n=!1}),U("changed",u=>{n||(u.deleted?ue(t,u.flag):de(t,u))})}),{on:U,off:Oe,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{V=J(t)},refreshEvaluations:()=>{z&&!o&&Date.now()-X>=6e4&&(_(),X=Date.now())},variation:(t,n,s=!1)=>ge(t,n,D,Te,s)}};0&&(module.exports={Event,initialize}); |
@@ -1,1 +0,1 @@ | ||
var HarnessFFSDK=(()=>{var _=Object.defineProperty,De=Object.defineProperties,Ce=Object.getOwnPropertyDescriptor,Fe=Object.getOwnPropertyDescriptors,Ae=Object.getOwnPropertyNames,oe=Object.getOwnPropertySymbols;var le=Object.prototype.hasOwnProperty,xe=Object.prototype.propertyIsEnumerable;var se=(t,e,i)=>e in t?_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:i}):t[e]=i,O=(t,e)=>{for(var i in e||(e={}))le.call(e,i)&&se(t,i,e[i]);if(oe)for(var i of oe(e))xe.call(e,i)&&se(t,i,e[i]);return t},j=(t,e)=>De(t,Fe(e));var Pe=(t,e)=>{for(var i in e)_(t,i,{get:e[i],enumerable:!0})},ke=(t,e,i,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ae(e))!le.call(t,s)&&s!==i&&_(t,s,{get:()=>e[s],enumerable:!(r=Ce(e,s))||r.enumerable});return t};var Ne=t=>ke(_({},"__esModule",{value:!0}),t);var D=(t,e,i)=>new Promise((r,s)=>{var d=R=>{try{E(i.next(R))}catch(c){s(c)}},h=R=>{try{E(i.throw(R))}catch(c){s(c)}},E=R=>R.done?r(R.value):Promise.resolve(R.value).then(d,h);E((i=i.apply(t,e)).next())});var $e={};Pe($e,{Event:()=>x,initialize:()=>Be});function J(t){this.message=t}J.prototype=new Error,J.prototype.name="InvalidCharacterError";var ce=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new J("'atob' failed: The string to be decoded is not correctly encoded.");for(var i,r,s=0,d=0,h="";r=e.charAt(d++);~r&&(i=s%4?64*i+r:r,s++%4)?h+=String.fromCharCode(255&i>>(-2*s&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return h};function Ve(t){var e=t.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(i){return decodeURIComponent(ce(i).replace(/(.)/g,function(r,s){var d=s.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(i){return ce(e)}}function M(t){this.message=t}function _e(t,e){if(typeof t!="string")throw new M("Invalid token specified");var i=(e=e||{}).header===!0?0:1;try{return JSON.parse(Ve(t.split(".")[i]))}catch(r){throw new M("Invalid token specified: "+r.message)}}M.prototype=new Error,M.prototype.name="InvalidTokenError";var de=_e;function ue(t){return{all:t=t||new Map,on:function(e,i){var r=t.get(e);r&&r.push(i)||t.set(e,[i])},off:function(e,i){var r=t.get(e);r&&r.splice(r.indexOf(i)>>>0,1)},emit:function(e,i){(t.get(e)||[]).slice().map(function(r){r(i)}),(t.get("*")||[]).slice().map(function(r){r(e,i)})}}}var x=(g=>(g.READY="ready",g.CONNECTED="connected",g.DISCONNECTED="disconnected",g.STOPPED="stopped",g.POLLING="polling",g.POLLING_STOPPED="polling stopped",g.FLAGS_LOADED="flags loaded",g.CACHE_LOADED="cache loaded",g.CHANGED="changed",g.ERROR="error",g.ERROR_METRICS="metrics error",g.ERROR_AUTH="auth error",g.ERROR_FETCH_FLAGS="fetch flags error",g.ERROR_FETCH_FLAG="fetch flag error",g.ERROR_STREAM="stream error",g))(x||{});var Me={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},fe=t=>{let e=O(O({},Me),t);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(t,...e)=>console.error(`[FF-SDK] ${t}`,...e),W=(t,e=!0)=>{e?setTimeout(t,0):t()},L=(t,e)=>Math.round(Math.random()*(e-t)+t);function Y(t){return"HARNESS_FF_CACHE_"+t}function H(t,e={}){let i=Y(t),r=parseInt(window.localStorage.getItem(i+".ts"));if(e!=null&&e.ttl&&!isNaN(r)&&r+e.ttl<Date.now())return Le(t),[];let s=window.localStorage.getItem(i);if(s)try{return JSON.parse(s)}catch(d){}return[]}function G(t,e){let i=Y(t);window.localStorage.setItem(i,JSON.stringify(e)),window.localStorage.setItem(i+".ts",Date.now().toString())}function ge(t,e){let i=H(t),r=i.find(({flag:s})=>s===e.flag);r?Object.assign(r,e):i.push(e),G(t,i)}function he(t,e){let i=H(t),r=i.findIndex(({flag:s})=>s===e);r>-1&&(i.splice(r,1),G(t,i))}function Le(t){let e=Y(t);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function X(t){return function(...i){let[r,s]=t(i);return fetch(r,s)}}var pe=3e4,B=class{constructor(e,i,r,s,d,h,E){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=i,this.url=r,this.apiKey=s,this.standardHeaders=d,this.eventCallback=E,this.fallbackPoller=h}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(i)},i=c=>{if(c.startsWith("data:")){let w=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",w),this.eventCallback(w)}},r=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=L(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},d=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},h=O({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,w]of Object.entries(h))this.xhr.setRequestHeader(c,w);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(r(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let E=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(r(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(E);E+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-pe&&(y("SSE read timeout"),this.xhr.abort())},pe),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...i){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...i)}};function ve(t,e,i,r,s){let d=t in i,h=d?i[t]:e;return d&&r(t,h),s?{value:h,isDefaultValue:!d}:h}var P=class{constructor(e,i,r){this.fetchFlagsFn=e;this.configurations=i;this.eventBus=r;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let i=yield this.fetchFlagsFn();if(i.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",i.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,i.error);let r=L(1e3,1e4);yield new Promise(s=>setTimeout(s,r))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...i){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...i)}};var Re="1.21.0",be=`Javascript ${Re} Client`,He=500,Ge=globalThis.fetch,z=!!globalThis.Proxy,Q=t=>{let{value:e}=t;try{switch(t.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(i){y(i)}return e},Be=(t,e,i)=>{let r=!1,s,d,h,E,R,c,w=!0,C={},k=X(n=>n),Z=0,ee=!1,g=()=>{w=!1},N=()=>{w=!0},S=[],u=ue(),f=fe(i);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let m=(n,...a)=>{f.debug&&console.debug(`[FF-SDK] ${n}`,...a)},$=n=>{if(w){let a=Date.now();a-n.lastAccessed>He&&(n.count++,n.lastAccessed=a)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(g(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),N())};let Se=(n,a)=>D(void 0,null,function*(){return(yield(yield Ge(`${a.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":be},body:JSON.stringify({apiKey:n,target:j(O({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,U=()=>{if(S.length){m("Sending metrics...",{metrics:S,evaluations:I});let n={metricsData:S.map(a=>({timestamp:Date.now(),count:a.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:a.featureIdentifier},{key:"featureName",value:a.featureIdentifier},{key:"variationIdentifier",value:a.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Re}]}))};k(`${f.eventUrl}/metrics/${s}?cluster=${d}`,{method:"POST",headers:O({"Content-Type":"application/json"},C),body:JSON.stringify(n)}).then(()=>{S=[],K=0}).catch(a=>{K++&&(S=[],K=0),m(a),u.emit("metrics error",a)}).finally(()=>{c=window.setTimeout(U,f.eventsSyncInterval)})}else c=window.setTimeout(U,f.eventsSyncInterval)},I={},Ie=n=>{m("Sending event for",n.flag),z?u.emit("changed",new Proxy(n,{get(a,l){var v;if(w&&a.hasOwnProperty(l)&&l==="value"){let b=a.flag,o=n.value,p=S.find(A=>A.featureIdentifier===b&&A.featureValue===o);p?($(p),p.variationIdentifier=((v=I[b])==null?void 0:v.identifier)||""):S.push({featureIdentifier:b,featureValue:String(o),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?Q(n):n[l]}})):u.emit("changed",{deleted:n.deleted,flag:n.flag,value:Q(n)})},te=function(){return z?new Proxy({},{get(n,a){var v,b,o;let l=n[a];if(w&&n.hasOwnProperty(a)){let p=n[a],A=S.find(re=>re.featureIdentifier===a&&p===re.featureValue);A?(A.variationIdentifier=((v=I[a])==null?void 0:v.identifier)||"",$(A)):S.push({featureIdentifier:a,featureValue:p,variationIdentifier:((b=I[a])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",a,"has been read with value:",p,"variationIdentifier:",(o=I[a])==null?void 0:o.identifier)}return l}}):{}},T=te();Se(t,f).then(n=>D(void 0,null,function*(){if(r)return;R=n;let a=de(n);C={Authorization:`Bearer ${R}`,"Harness-AccountID":a.accountID,"Harness-EnvironmentID":a.environmentIdentifier,"Harness-SDK-Info":be};let l=btoa(JSON.stringify(e));if(l.length<262144&&(C["Harness-Target"]=l),m("Authenticated",a),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,m("Picking up metrics from previous session")}catch(o){}c=window.setTimeout(U,f.eventsSyncInterval),s=a.environment,d=a.clusterIdentifier;let v=!!Object.keys(I).length;if((yield V()).type==="success"&&m("Fetch all flags ok",T),!r){if(f.streamEnabled?(m("Streaming mode enabled"),ye()):f.pollingEnabled?(m("Polling mode enabled"),we()):m("Streaming and polling mode disabled"),!v){g();let o=O({},T);N(),u.emit("ready",o)}ee=!0}})).catch(n=>{y("Authentication error: ",n),u.emit("auth error",n),u.emit("error",n)});let V=()=>D(void 0,null,function*(){try{let n=yield k(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:C});if(n.ok){let a=yield n.json();return a.forEach(F),u.emit("flags loaded",a),{type:"success",data:a}}else return y("Features fetch operation error: ",n),u.emit("fetch flags error",n),u.emit("error",n),{type:"error",error:n}}catch(n){return y("Features fetch operation error: ",n),u.emit("fetch flags error",n),u.emit("error",n),{type:"error",error:n}}}),ie=n=>D(void 0,null,function*(){try{let a=yield k(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${n}?cluster=${d}`,{headers:C});if(a.ok){let l=yield a.json();F(l)}else y("Feature fetch operation error: ",a),u.emit("fetch flag error",a),u.emit("error",a)}catch(a){y("Feature fetch operation error: ",a),u.emit("fetch flag error",a),u.emit("error",a)}}),F=n=>{g();let a=Q(n);a!==T[n.flag]&&(m("Flag variation has changed for ",n.identifier),T[n.flag]=a,I[n.flag]=j(O({},n),{value:a}),Ie(n)),N()};E=new P(V,f,u);let ye=()=>{let n=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):setTimeout(()=>ie(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):ie(o.identifier);break;case"delete":delete T[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),m("Evaluation deleted",{message:o,storage:T});break}},a=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),l=o=>!(!o||o.length==0||!o.every(p=>a(p))),v=o=>{o.event==="patch"&&(l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):V())},b=`${f.baseUrl}/stream?cluster=${d}`;h=new B(u,f,b,t,C,E,o=>{o.domain==="flag"?n(o):o.domain==="target-segment"&&v(o)}),h.start()},we=()=>{E.start()},q=(n,a)=>u.on(n,a),Oe=(n,a)=>{n?u.off(n,a):ne()},Te=(n,a)=>{var o;if(!w||z||a===void 0)return;let l=a,v=n,b=S.find(p=>p.featureIdentifier===v&&p.featureValue===l);b?($(b),b.variationIdentifier=((o=I[v])==null?void 0:o.identifier)||""):S.push({featureIdentifier:v,featureValue:l,count:1,variationIdentifier:I[v].identifier||"",lastAccessed:Date.now()})},ne=()=>{r=!0,f.streamEnabled&&(m("Closing event stream"),typeof(h==null?void 0:h.close)=="function"&&h.close(),u.all.clear()),f.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=te(),I={},clearTimeout(c)},ae=(n,a=!0)=>{n.length&&W(()=>{let l=!!Object.keys(I).length;if(n.forEach(F),!l){g();let v=O({},T);N(),u.emit("ready",v)}},a)};if(f.cache&&"localStorage"in window){let n=!0,a=H(e.identifier,typeof f.cache=="boolean"?{}:f.cache);a!=null&&a.length&&W(()=>{m("loading from cache",a),ae(a,!1),u.emit("cache loaded",a)}),q("flags loaded",l=>{G(e.identifier,l),n=!1}),q("changed",l=>{n||(l.deleted?he(e.identifier,l.flag):ge(e.identifier,l))})}return{on:q,off:Oe,close:ne,setEvaluations:ae,registerAPIRequestMiddleware:n=>{k=X(n)},refreshEvaluations:()=>{ee&&!r&&Date.now()-Z>=6e4&&(V(),Z=Date.now())},variation:(n,a,l=!1)=>ve(n,a,T,Te,l)}};return Ne($e);})(); | ||
var HarnessFFSDK=(()=>{var _=Object.defineProperty,De=Object.defineProperties,Ce=Object.getOwnPropertyDescriptor,Ae=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols;var se=Object.prototype.hasOwnProperty,xe=Object.prototype.propertyIsEnumerable;var oe=(t,e,n)=>e in t?_(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,O=(t,e)=>{for(var n in e||(e={}))se.call(e,n)&&oe(t,n,e[n]);if(ae)for(var n of ae(e))xe.call(e,n)&&oe(t,n,e[n]);return t},q=(t,e)=>De(t,Ae(e));var Pe=(t,e)=>{for(var n in e)_(t,n,{get:e[n],enumerable:!0})},ke=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Fe(e))!se.call(t,s)&&s!==n&&_(t,s,{get:()=>e[s],enumerable:!(a=Ce(e,s))||a.enumerable});return t};var Ne=t=>ke(_({},"__esModule",{value:!0}),t);var D=(t,e,n)=>new Promise((a,s)=>{var d=R=>{try{E(n.next(R))}catch(c){s(c)}},h=R=>{try{E(n.throw(R))}catch(c){s(c)}},E=R=>R.done?a(R.value):Promise.resolve(R.value).then(d,h);E((n=n.apply(t,e)).next())});var $e={};Pe($e,{Event:()=>x,initialize:()=>Be});function J(t){this.message=t}J.prototype=new Error,J.prototype.name="InvalidCharacterError";var le=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(t){var e=String(t).replace(/=+$/,"");if(e.length%4==1)throw new J("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,s=0,d=0,h="";a=e.charAt(d++);~a&&(n=s%4?64*n+a:a,s++%4)?h+=String.fromCharCode(255&n>>(-2*s&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return h};function Ve(t){var e=t.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(n){return decodeURIComponent(le(n).replace(/(.)/g,function(a,s){var d=s.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(n){return le(e)}}function M(t){this.message=t}function _e(t,e){if(typeof t!="string")throw new M("Invalid token specified");var n=(e=e||{}).header===!0?0:1;try{return JSON.parse(Ve(t.split(".")[n]))}catch(a){throw new M("Invalid token specified: "+a.message)}}M.prototype=new Error,M.prototype.name="InvalidTokenError";var ce=_e;function de(t){return{all:t=t||new Map,on:function(e,n){var a=t.get(e);a&&a.push(n)||t.set(e,[n])},off:function(e,n){var a=t.get(e);a&&a.splice(a.indexOf(n)>>>0,1)},emit:function(e,n){(t.get(e)||[]).slice().map(function(a){a(n)}),(t.get("*")||[]).slice().map(function(a){a(e,n)})}}}var x=(p=>(p.READY="ready",p.CONNECTED="connected",p.DISCONNECTED="disconnected",p.STOPPED="stopped",p.POLLING="polling",p.POLLING_STOPPED="polling stopped",p.FLAGS_LOADED="flags loaded",p.CACHE_LOADED="cache loaded",p.CHANGED="changed",p.ERROR="error",p.ERROR_METRICS="metrics error",p.ERROR_AUTH="auth error",p.ERROR_FETCH_FLAGS="fetch flags error",p.ERROR_FETCH_FLAG="fetch flag error",p.ERROR_STREAM="stream error",p))(x||{});var Me={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},ue=t=>{let e=O(O({},Me),t);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(t,...e)=>console.error(`[FF-SDK] ${t}`,...e),W=(t,e=!0)=>{e?setTimeout(t,0):t()},L=(t,e)=>Math.round(Math.random()*(e-t)+t);function fe(t){return D(this,null,function*(){let n=new TextEncoder().encode(t),a=yield crypto.subtle.digest("SHA-256",n);return"HARNESS_FF_CACHE_"+Array.from(new Uint8Array(a)).map(h=>h.toString(16).padStart(2,"0")).join("")})}function H(t,e={}){let n=parseInt(window.localStorage.getItem(t+".ts"));if(e!=null&&e.ttl&&!isNaN(n)&&n+e.ttl<Date.now())return Le(t),[];let a=window.localStorage.getItem(t);if(a)try{return JSON.parse(a)}catch(s){}return[]}function G(t,e){window.localStorage.setItem(t,JSON.stringify(e)),window.localStorage.setItem(t+".ts",Date.now().toString())}function ge(t,e){let n=H(t),a=n.find(({flag:s})=>s===e.flag);a?Object.assign(a,e):n.push(e),G(t,n)}function he(t,e){let n=H(t),a=n.findIndex(({flag:s})=>s===e);a>-1&&(n.splice(a,1),G(t,n))}function Le(t){window.localStorage.removeItem(t),window.localStorage.removeItem(t+".ts")}function Y(t){return function(...n){let[a,s]=t(n);return fetch(a,s)}}var pe=3e4,B=class{constructor(e,n,a,s,d,h,E){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=n,this.url=a,this.apiKey=s,this.standardHeaders=d,this.eventCallback=E,this.fallbackPoller=h}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(n)},n=c=>{if(c.startsWith("data:")){let w=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",w),this.eventCallback(w)}},a=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=L(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},d=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},h=O({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,w]of Object.entries(h))this.xhr.setRequestHeader(c,w);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(a(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let E=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(a(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(E);E+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-pe&&(y("SSE read timeout"),this.xhr.abort())},pe),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...n)}};function ve(t,e,n,a,s){let d=t in n,h=d?n[t]:e;return d&&a(t,h),s?{value:h,isDefaultValue:!d}:h}var P=class{constructor(e,n,a){this.fetchFlagsFn=e;this.configurations=n;this.eventBus=a;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let n=yield this.fetchFlagsFn();if(n.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",n.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,n.error);let a=L(1e3,1e4);yield new Promise(s=>setTimeout(s,a))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...n)}};var Re="1.22.0",be=`Javascript ${Re} Client`,He=500,Ge=globalThis.fetch,X=!!globalThis.Proxy,z=t=>{let{value:e}=t;try{switch(t.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(n){y(n)}return e},Be=(t,e,n)=>{let a=!1,s,d,h,E,R,c,w=!0,C={},k=Y(i=>i),Q=0,Z=!1,p=()=>{w=!1},N=()=>{w=!0},S=[],u=de(),g=ue(n);g.eventsSyncInterval<6e4&&(g.eventsSyncInterval=6e4),g.pollingInterval<6e4&&(g.pollingInterval=6e4);let m=(i,...r)=>{g.debug&&console.debug(`[FF-SDK] ${i}`,...r)},$=i=>{if(w){let r=Date.now();r-i.lastAccessed>He&&(i.count++,i.lastAccessed=r)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),N())};let Se=(i,r)=>D(void 0,null,function*(){return(yield(yield Ge(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":be},body:JSON.stringify({apiKey:i,target:q(O({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,U=()=>{if(S.length){m("Sending metrics...",{metrics:S,evaluations:I});let i={metricsData:S.map(r=>({timestamp:Date.now(),count:r.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:r.featureIdentifier},{key:"featureName",value:r.featureIdentifier},{key:"variationIdentifier",value:r.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Re}]}))};k(`${g.eventUrl}/metrics/${s}?cluster=${d}`,{method:"POST",headers:O({"Content-Type":"application/json"},C),body:JSON.stringify(i)}).then(()=>{S=[],K=0}).catch(r=>{K++&&(S=[],K=0),m(r),u.emit("metrics error",r)}).finally(()=>{c=window.setTimeout(U,g.eventsSyncInterval)})}else c=window.setTimeout(U,g.eventsSyncInterval)},I={},Ie=i=>{m("Sending event for",i.flag),X?u.emit("changed",new Proxy(i,{get(r,l){var f;if(w&&r.hasOwnProperty(l)&&l==="value"){let b=r.flag,o=i.value,v=S.find(F=>F.featureIdentifier===b&&F.featureValue===o);v?($(v),v.variationIdentifier=((f=I[b])==null?void 0:f.identifier)||""):S.push({featureIdentifier:b,featureValue:String(o),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?z(i):i[l]}})):u.emit("changed",{deleted:i.deleted,flag:i.flag,value:z(i)})},ee=function(){return X?new Proxy({},{get(i,r){var f,b,o;let l=i[r];if(w&&i.hasOwnProperty(r)){let v=i[r],F=S.find(re=>re.featureIdentifier===r&&v===re.featureValue);F?(F.variationIdentifier=((f=I[r])==null?void 0:f.identifier)||"",$(F)):S.push({featureIdentifier:r,featureValue:v,variationIdentifier:((b=I[r])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=I[r])==null?void 0:o.identifier)}return l}}):{}},T=ee();Se(t,g).then(i=>D(void 0,null,function*(){if(a)return;R=i;let r=ce(i);C={Authorization:`Bearer ${R}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":be};let l=btoa(JSON.stringify(e));if(l.length<262144&&(C["Harness-Target"]=l),m("Authenticated",r),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,m("Picking up metrics from previous session")}catch(o){}c=window.setTimeout(U,g.eventsSyncInterval),s=r.environment,d=r.clusterIdentifier;let f=!!Object.keys(I).length;if((yield V()).type==="success"&&m("Fetch all flags ok",T),!a){if(g.streamEnabled?(m("Streaming mode enabled"),ye()):g.pollingEnabled?(m("Polling mode enabled"),we()):m("Streaming and polling mode disabled"),!f){p();let o=O({},T);N(),u.emit("ready",o)}Z=!0}})).catch(i=>{y("Authentication error: ",i),u.emit("auth error",i),u.emit("error",i)});let V=()=>D(void 0,null,function*(){try{let i=yield k(`${g.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:C});if(i.ok){let r=yield i.json();return r.forEach(A),u.emit("flags loaded",r),{type:"success",data:r}}else return y("Features fetch operation error: ",i),u.emit("fetch flags error",i),u.emit("error",i),{type:"error",error:i}}catch(i){return y("Features fetch operation error: ",i),u.emit("fetch flags error",i),u.emit("error",i),{type:"error",error:i}}}),te=i=>D(void 0,null,function*(){try{let r=yield k(`${g.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${i}?cluster=${d}`,{headers:C});if(r.ok){let l=yield r.json();A(l)}else y("Feature fetch operation error: ",r),u.emit("fetch flag error",r),u.emit("error",r)}catch(r){y("Feature fetch operation error: ",r),u.emit("fetch flag error",r),u.emit("error",r)}}),A=i=>{p();let r=z(i);r!==T[i.flag]&&(m("Flag variation has changed for ",i.identifier),T[i.flag]=r,I[i.flag]=q(O({},i),{value:r}),Ie(i)),N()};E=new P(V,g,u);let ye=()=>{let i=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):setTimeout(()=>te(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):te(o.identifier);break;case"delete":delete T[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),m("Evaluation deleted",{message:o,storage:T});break}},r=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),l=o=>!(!o||o.length==0||!o.every(v=>r(v))),f=o=>{o.event==="patch"&&(l(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):V())},b=`${g.baseUrl}/stream?cluster=${d}`;h=new B(u,g,b,t,C,E,o=>{o.domain==="flag"?i(o):o.domain==="target-segment"&&f(o)}),h.start()},we=()=>{E.start()},j=(i,r)=>u.on(i,r),Oe=(i,r)=>{i?u.off(i,r):ie()},Te=(i,r)=>{var o;if(!w||X||r===void 0)return;let l=r,f=i,b=S.find(v=>v.featureIdentifier===f&&v.featureValue===l);b?($(b),b.variationIdentifier=((o=I[f])==null?void 0:o.identifier)||""):S.push({featureIdentifier:f,featureValue:l,count:1,variationIdentifier:I[f].identifier||"",lastAccessed:Date.now()})},ie=()=>{a=!0,g.streamEnabled&&(m("Closing event stream"),typeof(h==null?void 0:h.close)=="function"&&h.close(),u.all.clear()),g.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=ee(),I={},clearTimeout(c)},ne=(i,r=!0)=>{i.length&&W(()=>{let l=!!Object.keys(I).length;if(i.forEach(A),!l){p();let f=O({},T);N(),u.emit("ready",f)}},r)};return g.cache&&"localStorage"in window&&fe(e.identifier+t).then(i=>{let r=!0,l=H(i,typeof g.cache=="boolean"?{}:g.cache);l!=null&&l.length&&W(()=>{m("loading from cache",l),ne(l,!1),u.emit("cache loaded",l)}),j("flags loaded",f=>{G(i,f),r=!1}),j("changed",f=>{r||(f.deleted?he(i,f.flag):ge(i,f))})}),{on:j,off:Oe,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:i=>{k=Y(i)},refreshEvaluations:()=>{Z&&!a&&Date.now()-Q>=6e4&&(V(),Q=Date.now())},variation:(i,r,l=!1)=>ve(i,r,T,Te,l)}};return Ne($e);})(); |
@@ -1,1 +0,1 @@ | ||
var Oe=Object.defineProperty,Te=Object.defineProperties;var De=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var Ce=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable;var oe=(n,e,a)=>e in n?Oe(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,O=(n,e)=>{for(var a in e||(e={}))Ce.call(e,a)&&oe(n,a,e[a]);if(re)for(var a of re(e))Fe.call(e,a)&&oe(n,a,e[a]);return n},q=(n,e)=>Te(n,De(e));var D=(n,e,a)=>new Promise((r,s)=>{var d=R=>{try{E(a.next(R))}catch(c){s(c)}},h=R=>{try{E(a.throw(R))}catch(c){s(c)}},E=R=>R.done?r(R.value):Promise.resolve(R.value).then(d,h);E((a=a.apply(n,e)).next())});function j(n){this.message=n}j.prototype=new Error,j.prototype.name="InvalidCharacterError";var se=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(n){var e=String(n).replace(/=+$/,"");if(e.length%4==1)throw new j("'atob' failed: The string to be decoded is not correctly encoded.");for(var a,r,s=0,d=0,h="";r=e.charAt(d++);~r&&(a=s%4?64*a+r:r,s++%4)?h+=String.fromCharCode(255&a>>(-2*s&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return h};function Ae(n){var e=n.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(a){return decodeURIComponent(se(a).replace(/(.)/g,function(r,s){var d=s.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(a){return se(e)}}function V(n){this.message=n}function xe(n,e){if(typeof n!="string")throw new V("Invalid token specified");var a=(e=e||{}).header===!0?0:1;try{return JSON.parse(Ae(n.split(".")[a]))}catch(r){throw new V("Invalid token specified: "+r.message)}}V.prototype=new Error,V.prototype.name="InvalidTokenError";var le=xe;function ce(n){return{all:n=n||new Map,on:function(e,a){var r=n.get(e);r&&r.push(a)||n.set(e,[a])},off:function(e,a){var r=n.get(e);r&&r.splice(r.indexOf(a)>>>0,1)},emit:function(e,a){(n.get(e)||[]).slice().map(function(r){r(a)}),(n.get("*")||[]).slice().map(function(r){r(e,a)})}}}var _=(g=>(g.READY="ready",g.CONNECTED="connected",g.DISCONNECTED="disconnected",g.STOPPED="stopped",g.POLLING="polling",g.POLLING_STOPPED="polling stopped",g.FLAGS_LOADED="flags loaded",g.CACHE_LOADED="cache loaded",g.CHANGED="changed",g.ERROR="error",g.ERROR_METRICS="metrics error",g.ERROR_AUTH="auth error",g.ERROR_FETCH_FLAGS="fetch flags error",g.ERROR_FETCH_FLAG="fetch flag error",g.ERROR_STREAM="stream error",g))(_||{});var Pe={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},de=n=>{let e=O(O({},Pe),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),J=(n,e=!0)=>{e?setTimeout(n,0):n()},M=(n,e)=>Math.round(Math.random()*(e-n)+n);function W(n){return"HARNESS_FF_CACHE_"+n}function L(n,e={}){let a=W(n),r=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(r)&&r+e.ttl<Date.now())return ke(n),[];let s=window.localStorage.getItem(a);if(s)try{return JSON.parse(s)}catch(d){}return[]}function H(n,e){let a=W(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function ue(n,e){let a=L(n),r=a.find(({flag:s})=>s===e.flag);r?Object.assign(r,e):a.push(e),H(n,a)}function fe(n,e){let a=L(n),r=a.findIndex(({flag:s})=>s===e);r>-1&&(a.splice(r,1),H(n,a))}function ke(n){let e=W(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function Y(n){return function(...a){let[r,s]=n(a);return fetch(r,s)}}var ge=3e4,G=class{constructor(e,a,r,s,d,h,E){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=a,this.url=r,this.apiKey=s,this.standardHeaders=d,this.eventCallback=E,this.fallbackPoller=h}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let w=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",w),this.eventCallback(w)}},r=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},d=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},h=O({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,w]of Object.entries(h))this.xhr.setRequestHeader(c,w);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(r(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let E=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(r(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(E);E+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-ge&&(y("SSE read timeout"),this.xhr.abort())},ge),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function he(n,e,a,r,s){let d=n in a,h=d?a[n]:e;return d&&r(n,h),s?{value:h,isDefaultValue:!d}:h}var x=class{constructor(e,a,r){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=r;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(a.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",a.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,a.error);let r=M(1e3,1e4);yield new Promise(s=>setTimeout(s,r))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var Ee="1.21.0",me=`Javascript ${Ee} Client`,Ne=500,Ve=globalThis.fetch,X=!!globalThis.Proxy,z=n=>{let{value:e}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){y(a)}return e},pt=(n,e,a)=>{let r=!1,s,d,h,E,R,c,w=!0,C={},P=Y(t=>t),Q=0,Z=!1,g=()=>{w=!1},k=()=>{w=!0},S=[],u=ce(),f=de(a);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let m=(t,...i)=>{f.debug&&console.debug(`[FF-SDK] ${t}`,...i)},B=t=>{if(w){let i=Date.now();i-t.lastAccessed>Ne&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(g(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),k())};let be=(t,i)=>D(void 0,null,function*(){return(yield(yield Ve(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":me},body:JSON.stringify({apiKey:t,target:q(O({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(S.length){m("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Ee}]}))};P(`${f.eventUrl}/metrics/${s}?cluster=${d}`,{method:"POST",headers:O({"Content-Type":"application/json"},C),body:JSON.stringify(t)}).then(()=>{S=[],$=0}).catch(i=>{$++&&(S=[],$=0),m(i),u.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(K,f.eventsSyncInterval)})}else c=window.setTimeout(K,f.eventsSyncInterval)},I={},Re=t=>{m("Sending event for",t.flag),X?u.emit("changed",new Proxy(t,{get(i,l){var v;if(w&&i.hasOwnProperty(l)&&l==="value"){let b=i.flag,o=t.value,p=S.find(A=>A.featureIdentifier===b&&A.featureValue===o);p?(B(p),p.variationIdentifier=((v=I[b])==null?void 0:v.identifier)||""):S.push({featureIdentifier:b,featureValue:String(o),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?z(t):t[l]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:z(t)})},ee=function(){return X?new Proxy({},{get(t,i){var v,b,o;let l=t[i];if(w&&t.hasOwnProperty(i)){let p=t[i],A=S.find(ae=>ae.featureIdentifier===i&&p===ae.featureValue);A?(A.variationIdentifier=((v=I[i])==null?void 0:v.identifier)||"",B(A)):S.push({featureIdentifier:i,featureValue:p,variationIdentifier:((b=I[i])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",i,"has been read with value:",p,"variationIdentifier:",(o=I[i])==null?void 0:o.identifier)}return l}}):{}},T=ee();be(n,f).then(t=>D(void 0,null,function*(){if(r)return;R=t;let i=le(t);C={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":me};let l=btoa(JSON.stringify(e));if(l.length<262144&&(C["Harness-Target"]=l),m("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,m("Picking up metrics from previous session")}catch(o){}c=window.setTimeout(K,f.eventsSyncInterval),s=i.environment,d=i.clusterIdentifier;let v=!!Object.keys(I).length;if((yield N()).type==="success"&&m("Fetch all flags ok",T),!r){if(f.streamEnabled?(m("Streaming mode enabled"),Se()):f.pollingEnabled?(m("Polling mode enabled"),Ie()):m("Streaming and polling mode disabled"),!v){g();let o=O({},T);k(),u.emit("ready",o)}Z=!0}})).catch(t=>{y("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let N=()=>D(void 0,null,function*(){try{let t=yield P(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:C});if(t.ok){let i=yield t.json();return i.forEach(F),u.emit("flags loaded",i),{type:"success",data:i}}else return y("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),{type:"error",error:t}}}),te=t=>D(void 0,null,function*(){try{let i=yield P(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${t}?cluster=${d}`,{headers:C});if(i.ok){let l=yield i.json();F(l)}else y("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}}),F=t=>{g();let i=z(t);i!==T[t.flag]&&(m("Flag variation has changed for ",t.identifier),T[t.flag]=i,I[t.flag]=q(O({},t),{value:i}),Re(t)),k()};E=new x(N,f,u);let Se=()=>{let t=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):setTimeout(()=>te(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):te(o.identifier);break;case"delete":delete T[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),m("Evaluation deleted",{message:o,storage:T});break}},i=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),l=o=>!(!o||o.length==0||!o.every(p=>i(p))),v=o=>{o.event==="patch"&&(l(o.evaluations)?o.evaluations.forEach(p=>{F(p)}):N())},b=`${f.baseUrl}/stream?cluster=${d}`;h=new G(u,f,b,n,C,E,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&v(o)}),h.start()},Ie=()=>{E.start()},U=(t,i)=>u.on(t,i),ye=(t,i)=>{t?u.off(t,i):ie()},we=(t,i)=>{var o;if(!w||X||i===void 0)return;let l=i,v=t,b=S.find(p=>p.featureIdentifier===v&&p.featureValue===l);b?(B(b),b.variationIdentifier=((o=I[v])==null?void 0:o.identifier)||""):S.push({featureIdentifier:v,featureValue:l,count:1,variationIdentifier:I[v].identifier||"",lastAccessed:Date.now()})},ie=()=>{r=!0,f.streamEnabled&&(m("Closing event stream"),typeof(h==null?void 0:h.close)=="function"&&h.close(),u.all.clear()),f.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=ee(),I={},clearTimeout(c)},ne=(t,i=!0)=>{t.length&&J(()=>{let l=!!Object.keys(I).length;if(t.forEach(F),!l){g();let v=O({},T);k(),u.emit("ready",v)}},i)};if(f.cache&&"localStorage"in window){let t=!0,i=L(e.identifier,typeof f.cache=="boolean"?{}:f.cache);i!=null&&i.length&&J(()=>{m("loading from cache",i),ne(i,!1),u.emit("cache loaded",i)}),U("flags loaded",l=>{H(e.identifier,l),t=!1}),U("changed",l=>{t||(l.deleted?fe(e.identifier,l.flag):ue(e.identifier,l))})}return{on:U,off:ye,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:t=>{P=Y(t)},refreshEvaluations:()=>{Z&&!r&&Date.now()-Q>=6e4&&(N(),Q=Date.now())},variation:(t,i,l=!1)=>he(t,i,T,we,l)}};export{_ as Event,pt as initialize}; | ||
var Oe=Object.defineProperty,Te=Object.defineProperties;var De=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var Ce=Object.prototype.hasOwnProperty,Ae=Object.prototype.propertyIsEnumerable;var ae=(i,e,n)=>e in i?Oe(i,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):i[e]=n,O=(i,e)=>{for(var n in e||(e={}))Ce.call(e,n)&&ae(i,n,e[n]);if(re)for(var n of re(e))Ae.call(e,n)&&ae(i,n,e[n]);return i},j=(i,e)=>Te(i,De(e));var D=(i,e,n)=>new Promise((a,l)=>{var d=R=>{try{E(n.next(R))}catch(c){l(c)}},h=R=>{try{E(n.throw(R))}catch(c){l(c)}},E=R=>R.done?a(R.value):Promise.resolve(R.value).then(d,h);E((n=n.apply(i,e)).next())});function q(i){this.message=i}q.prototype=new Error,q.prototype.name="InvalidCharacterError";var oe=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(i){var e=String(i).replace(/=+$/,"");if(e.length%4==1)throw new q("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,l=0,d=0,h="";a=e.charAt(d++);~a&&(n=l%4?64*n+a:a,l++%4)?h+=String.fromCharCode(255&n>>(-2*l&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return h};function Fe(i){var e=i.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(n){return decodeURIComponent(oe(n).replace(/(.)/g,function(a,l){var d=l.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(n){return oe(e)}}function V(i){this.message=i}function xe(i,e){if(typeof i!="string")throw new V("Invalid token specified");var n=(e=e||{}).header===!0?0:1;try{return JSON.parse(Fe(i.split(".")[n]))}catch(a){throw new V("Invalid token specified: "+a.message)}}V.prototype=new Error,V.prototype.name="InvalidTokenError";var se=xe;function le(i){return{all:i=i||new Map,on:function(e,n){var a=i.get(e);a&&a.push(n)||i.set(e,[n])},off:function(e,n){var a=i.get(e);a&&a.splice(a.indexOf(n)>>>0,1)},emit:function(e,n){(i.get(e)||[]).slice().map(function(a){a(n)}),(i.get("*")||[]).slice().map(function(a){a(e,n)})}}}var _=(p=>(p.READY="ready",p.CONNECTED="connected",p.DISCONNECTED="disconnected",p.STOPPED="stopped",p.POLLING="polling",p.POLLING_STOPPED="polling stopped",p.FLAGS_LOADED="flags loaded",p.CACHE_LOADED="cache loaded",p.CHANGED="changed",p.ERROR="error",p.ERROR_METRICS="metrics error",p.ERROR_AUTH="auth error",p.ERROR_FETCH_FLAGS="fetch flags error",p.ERROR_FETCH_FLAG="fetch flag error",p.ERROR_STREAM="stream error",p))(_||{});var Pe={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},ce=i=>{let e=O(O({},Pe),i);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(i,...e)=>console.error(`[FF-SDK] ${i}`,...e),J=(i,e=!0)=>{e?setTimeout(i,0):i()},M=(i,e)=>Math.round(Math.random()*(e-i)+i);function de(i){return D(this,null,function*(){let n=new TextEncoder().encode(i),a=yield crypto.subtle.digest("SHA-256",n);return"HARNESS_FF_CACHE_"+Array.from(new Uint8Array(a)).map(h=>h.toString(16).padStart(2,"0")).join("")})}function L(i,e={}){let n=parseInt(window.localStorage.getItem(i+".ts"));if(e!=null&&e.ttl&&!isNaN(n)&&n+e.ttl<Date.now())return ke(i),[];let a=window.localStorage.getItem(i);if(a)try{return JSON.parse(a)}catch(l){}return[]}function H(i,e){window.localStorage.setItem(i,JSON.stringify(e)),window.localStorage.setItem(i+".ts",Date.now().toString())}function ue(i,e){let n=L(i),a=n.find(({flag:l})=>l===e.flag);a?Object.assign(a,e):n.push(e),H(i,n)}function fe(i,e){let n=L(i),a=n.findIndex(({flag:l})=>l===e);a>-1&&(n.splice(a,1),H(i,n))}function ke(i){window.localStorage.removeItem(i),window.localStorage.removeItem(i+".ts")}function W(i){return function(...n){let[a,l]=i(n);return fetch(a,l)}}var ge=3e4,G=class{constructor(e,n,a,l,d,h,E){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=n,this.url=a,this.apiKey=l,this.standardHeaders=d,this.eventCallback=E,this.fallbackPoller=h}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(n)},n=c=>{if(c.startsWith("data:")){let w=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",w),this.eventCallback(w)}},a=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},l=()=>{clearInterval(this.readTimeoutCheckerId);let c=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),c)},d=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),l()},h=O({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,w]of Object.entries(h))this.xhr.setRequestHeader(c,w);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(a(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let E=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(a(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(E);E+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-ge&&(y("SSE read timeout"),this.xhr.abort())},ge),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...n)}};function he(i,e,n,a,l){let d=i in n,h=d?n[i]:e;return d&&a(i,h),l?{value:h,isDefaultValue:!d}:h}var x=class{constructor(e,n,a){this.fetchFlagsFn=e;this.configurations=n;this.eventBus=a;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let n=yield this.fetchFlagsFn();if(n.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",n.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,n.error);let a=M(1e3,1e4);yield new Promise(l=>setTimeout(l,a))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...n)}};var Ee="1.22.0",me=`Javascript ${Ee} Client`,Ne=500,Ve=globalThis.fetch,Y=!!globalThis.Proxy,X=i=>{let{value:e}=i;try{switch(i.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(n){y(n)}return e},vt=(i,e,n)=>{let a=!1,l,d,h,E,R,c,w=!0,C={},P=W(t=>t),z=0,Q=!1,p=()=>{w=!1},k=()=>{w=!0},S=[],u=le(),g=ce(n);g.eventsSyncInterval<6e4&&(g.eventsSyncInterval=6e4),g.pollingInterval<6e4&&(g.pollingInterval=6e4);let m=(t,...r)=>{g.debug&&console.debug(`[FF-SDK] ${t}`,...r)},B=t=>{if(w){let r=Date.now();r-t.lastAccessed>Ne&&(t.count++,t.lastAccessed=r)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),k())};let be=(t,r)=>D(void 0,null,function*(){return(yield(yield Ve(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":me},body:JSON.stringify({apiKey:t,target:j(O({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(S.length){m("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(r=>({timestamp:Date.now(),count:r.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:r.featureIdentifier},{key:"featureName",value:r.featureIdentifier},{key:"variationIdentifier",value:r.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Ee}]}))};P(`${g.eventUrl}/metrics/${l}?cluster=${d}`,{method:"POST",headers:O({"Content-Type":"application/json"},C),body:JSON.stringify(t)}).then(()=>{S=[],$=0}).catch(r=>{$++&&(S=[],$=0),m(r),u.emit("metrics error",r)}).finally(()=>{c=window.setTimeout(K,g.eventsSyncInterval)})}else c=window.setTimeout(K,g.eventsSyncInterval)},I={},Re=t=>{m("Sending event for",t.flag),Y?u.emit("changed",new Proxy(t,{get(r,s){var f;if(w&&r.hasOwnProperty(s)&&s==="value"){let b=r.flag,o=t.value,v=S.find(F=>F.featureIdentifier===b&&F.featureValue===o);v?(B(v),v.variationIdentifier=((f=I[b])==null?void 0:f.identifier)||""):S.push({featureIdentifier:b,featureValue:String(o),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",s,"has been read with value via stream update",o)}return s==="value"?X(t):t[s]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:X(t)})},Z=function(){return Y?new Proxy({},{get(t,r){var f,b,o;let s=t[r];if(w&&t.hasOwnProperty(r)){let v=t[r],F=S.find(ne=>ne.featureIdentifier===r&&v===ne.featureValue);F?(F.variationIdentifier=((f=I[r])==null?void 0:f.identifier)||"",B(F)):S.push({featureIdentifier:r,featureValue:v,variationIdentifier:((b=I[r])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=I[r])==null?void 0:o.identifier)}return s}}):{}},T=Z();be(i,g).then(t=>D(void 0,null,function*(){if(a)return;R=t;let r=se(t);C={Authorization:`Bearer ${R}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":me};let s=btoa(JSON.stringify(e));if(s.length<262144&&(C["Harness-Target"]=s),m("Authenticated",r),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,m("Picking up metrics from previous session")}catch(o){}c=window.setTimeout(K,g.eventsSyncInterval),l=r.environment,d=r.clusterIdentifier;let f=!!Object.keys(I).length;if((yield N()).type==="success"&&m("Fetch all flags ok",T),!a){if(g.streamEnabled?(m("Streaming mode enabled"),Se()):g.pollingEnabled?(m("Polling mode enabled"),Ie()):m("Streaming and polling mode disabled"),!f){p();let o=O({},T);k(),u.emit("ready",o)}Q=!0}})).catch(t=>{y("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let N=()=>D(void 0,null,function*(){try{let t=yield P(`${g.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:C});if(t.ok){let r=yield t.json();return r.forEach(A),u.emit("flags loaded",r),{type:"success",data:r}}else return y("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),{type:"error",error:t}}}),ee=t=>D(void 0,null,function*(){try{let r=yield P(`${g.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${d}`,{headers:C});if(r.ok){let s=yield r.json();A(s)}else y("Feature fetch operation error: ",r),u.emit("fetch flag error",r),u.emit("error",r)}catch(r){y("Feature fetch operation error: ",r),u.emit("fetch flag error",r),u.emit("error",r)}}),A=t=>{p();let r=X(t);r!==T[t.flag]&&(m("Flag variation has changed for ",t.identifier),T[t.flag]=r,I[t.flag]=j(O({},t),{value:r}),Re(t)),k()};E=new x(N,g,u);let Se=()=>{let t=o=>{switch(o.event){case"create":s(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):setTimeout(()=>ee(o.identifier),1e3);break;case"patch":s(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):ee(o.identifier);break;case"delete":delete T[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),m("Evaluation deleted",{message:o,storage:T});break}},r=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),s=o=>!(!o||o.length==0||!o.every(v=>r(v))),f=o=>{o.event==="patch"&&(s(o.evaluations)?o.evaluations.forEach(v=>{A(v)}):N())},b=`${g.baseUrl}/stream?cluster=${d}`;h=new G(u,g,b,i,C,E,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&f(o)}),h.start()},Ie=()=>{E.start()},U=(t,r)=>u.on(t,r),ye=(t,r)=>{t?u.off(t,r):te()},we=(t,r)=>{var o;if(!w||Y||r===void 0)return;let s=r,f=t,b=S.find(v=>v.featureIdentifier===f&&v.featureValue===s);b?(B(b),b.variationIdentifier=((o=I[f])==null?void 0:o.identifier)||""):S.push({featureIdentifier:f,featureValue:s,count:1,variationIdentifier:I[f].identifier||"",lastAccessed:Date.now()})},te=()=>{a=!0,g.streamEnabled&&(m("Closing event stream"),typeof(h==null?void 0:h.close)=="function"&&h.close(),u.all.clear()),g.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=Z(),I={},clearTimeout(c)},ie=(t,r=!0)=>{t.length&&J(()=>{let s=!!Object.keys(I).length;if(t.forEach(A),!s){p();let f=O({},T);k(),u.emit("ready",f)}},r)};return g.cache&&"localStorage"in window&&de(e.identifier+i).then(t=>{let r=!0,s=L(t,typeof g.cache=="boolean"?{}:g.cache);s!=null&&s.length&&J(()=>{m("loading from cache",s),ie(s,!1),u.emit("cache loaded",s)}),U("flags loaded",f=>{H(t,f),r=!1}),U("changed",f=>{r||(f.deleted?fe(t,f.flag):ue(t,f))})}),{on:U,off:ye,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{P=W(t)},refreshEvaluations:()=>{Q&&!a&&Date.now()-z>=6e4&&(N(),z=Date.now())},variation:(t,r,s=!1)=>he(t,r,T,we,s)}};export{_ as Event,vt as initialize}; |
@@ -1,1 +0,1 @@ | ||
var be=Object.defineProperty,Se=Object.defineProperties;var Ie=Object.getOwnPropertyDescriptors;var ne=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,Oe=Object.prototype.propertyIsEnumerable;var ae=(a,e,n)=>e in a?be(a,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[e]=n,T=(a,e)=>{for(var n in e||(e={}))ye.call(e,n)&&ae(a,n,e[n]);if(ne)for(var n of ne(e))Oe.call(e,n)&&ae(a,n,e[n]);return a},q=(a,e)=>Se(a,Ie(e));var w=(a,e,n)=>new Promise((s,c)=>{var g=b=>{try{m(n.next(b))}catch(l){c(l)}},v=b=>{try{m(n.throw(b))}catch(l){c(l)}},m=b=>b.done?s(b.value):Promise.resolve(b.value).then(g,v);m((n=n.apply(a,e)).next())});import we from"jwt-decode";import Ce from"mitt";var k=(f=>(f.READY="ready",f.CONNECTED="connected",f.DISCONNECTED="disconnected",f.STOPPED="stopped",f.POLLING="polling",f.POLLING_STOPPED="polling stopped",f.FLAGS_LOADED="flags loaded",f.CACHE_LOADED="cache loaded",f.CHANGED="changed",f.ERROR="error",f.ERROR_METRICS="metrics error",f.ERROR_AUTH="auth error",f.ERROR_FETCH_FLAGS="fetch flags error",f.ERROR_FETCH_FLAG="fetch flag error",f.ERROR_STREAM="stream error",f))(k||{});var Te={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},re=a=>{let e=T(T({},Te),a);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(a,...e)=>console.error(`[FF-SDK] ${a}`,...e),U=(a,e=!0)=>{e?setTimeout(a,0):a()},_=(a,e)=>Math.round(Math.random()*(e-a)+a);function j(a){return"HARNESS_FF_CACHE_"+a}function M(a,e={}){let n=j(a),s=parseInt(window.localStorage.getItem(n+".ts"));if(e!=null&&e.ttl&&!isNaN(s)&&s+e.ttl<Date.now())return De(a),[];let c=window.localStorage.getItem(n);if(c)try{return JSON.parse(c)}catch(g){}return[]}function L(a,e){let n=j(a);window.localStorage.setItem(n,JSON.stringify(e)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(a,e){let n=M(a),s=n.find(({flag:c})=>c===e.flag);s?Object.assign(s,e):n.push(e),L(a,n)}function se(a,e){let n=M(a),s=n.findIndex(({flag:c})=>c===e);s>-1&&(n.splice(s,1),L(a,n))}function De(a){let e=j(a);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function J(a){return function(...n){let[s,c]=a(n);return fetch(s,c)}}var le=3e4,H=class{constructor(e,n,s,c,g,v,m){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=e,this.configurations=n,this.url=s,this.apiKey=c,this.standardHeaders=g,this.eventCallback=m,this.fallbackPoller=v}start(){let e=l=>{l.toString().split(/\r?\n/).forEach(n)},n=l=>{if(l.startsWith("data:")){let O=JSON.parse(l.substring(5));this.logDebug("Received event from stream: ",O),this.eventCallback(O)}},s=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},c=()=>{clearInterval(this.readTimeoutCheckerId);let l=_(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+l+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),l)},g=l=>{l&&y("Stream has issue",l),this.fallBackToPolling(),this.eventBus.emit("stream error",l),this.eventBus.emit("error",l),c()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[l,O]of Object.entries(v))this.xhr.setRequestHeader(l,O);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,g("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||g(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,g("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){g(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(s(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let m=0,b=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(s(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),b=Date.now();let l=this.xhr.responseText.slice(m);m+=l.length,this.logDebug("SSE GOT: "+l),e(l)},this.readTimeoutCheckerId=setInterval(()=>{b<Date.now()-le&&(y("SSE read timeout"),this.xhr.abort())},le),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...n)}};function ce(a,e,n,s,c){let g=a in n,v=g?n[a]:e;return g&&s(a,v),c?{value:v,isDefaultValue:!g}:v}var P=class{constructor(e,n,s){this.fetchFlagsFn=e;this.configurations=n;this.eventBus=s;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return w(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let n=yield this.fetchFlagsFn();if(n.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",n.error),e>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${e} failed. Remaining attempts: ${this.maxAttempts-e}`,n.error);let s=_(1e3,1e4);yield new Promise(c=>setTimeout(c,s))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...n)}};var ge="1.21.0",fe=`Javascript ${ge} Client`,Fe=500,Ae=globalThis.fetch,W=!!globalThis.Proxy,Y=a=>{let{value:e}=a;try{switch(a.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(n){y(n)}return e},lt=(a,e,n)=>{let s=!1,c,g,v,m,b,l,O=!0,C={},x=J(t=>t),X=0,z=!1,f=()=>{O=!1},N=()=>{O=!0},S=[],d=Ce(),u=re(n);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let E=(t,...i)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...i)},G=t=>{if(O){let i=Date.now();i-t.lastAccessed>Fe&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),N())};let he=(t,i)=>w(void 0,null,function*(){return(yield(yield Ae(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":fe},body:JSON.stringify({apiKey:t,target:q(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,$=()=>{if(S.length){E("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:ge}]}))};x(`${u.eventUrl}/metrics/${c}?cluster=${g}`,{method:"POST",headers:T({"Content-Type":"application/json"},C),body:JSON.stringify(t)}).then(()=>{S=[],B=0}).catch(i=>{B++&&(S=[],B=0),E(i),d.emit("metrics error",i)}).finally(()=>{l=window.setTimeout($,u.eventsSyncInterval)})}else l=window.setTimeout($,u.eventsSyncInterval)},I={},pe=t=>{E("Sending event for",t.flag),W?d.emit("changed",new Proxy(t,{get(i,o){var p;if(O&&i.hasOwnProperty(o)&&o==="value"){let R=i.flag,r=t.value,h=S.find(A=>A.featureIdentifier===R&&A.featureValue===r);h?(G(h),h.variationIdentifier=((p=I[R])==null?void 0:p.identifier)||""):S.push({featureIdentifier:R,featureValue:String(r),variationIdentifier:I[R].identifier||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?Y(t):t[o]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:Y(t)})},Q=function(){return W?new Proxy({},{get(t,i){var p,R,r;let o=t[i];if(O&&t.hasOwnProperty(i)){let h=t[i],A=S.find(ie=>ie.featureIdentifier===i&&h===ie.featureValue);A?(A.variationIdentifier=((p=I[i])==null?void 0:p.identifier)||"",G(A)):S.push({featureIdentifier:i,featureValue:h,variationIdentifier:((R=I[i])==null?void 0:R.identifier)||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag:",i,"has been read with value:",h,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return o}}):{}},D=Q();he(a,u).then(t=>w(void 0,null,function*(){if(s)return;b=t;let i=we(t);C={Authorization:`Bearer ${b}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":fe};let o=btoa(JSON.stringify(e));if(o.length<262144&&(C["Harness-Target"]=o),E("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,E("Picking up metrics from previous session")}catch(r){}l=window.setTimeout($,u.eventsSyncInterval),c=i.environment,g=i.clusterIdentifier;let p=!!Object.keys(I).length;if((yield V()).type==="success"&&E("Fetch all flags ok",D),!s){if(u.streamEnabled?(E("Streaming mode enabled"),ve()):u.pollingEnabled?(E("Polling mode enabled"),Ee()):E("Streaming and polling mode disabled"),!p){f();let r=T({},D);N(),d.emit("ready",r)}z=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let V=()=>w(void 0,null,function*(){try{let t=yield x(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations?cluster=${g}`,{headers:C});if(t.ok){let i=yield t.json();return i.forEach(F),d.emit("flags loaded",i),{type:"success",data:i}}else return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),{type:"error",error:t}}}),Z=t=>w(void 0,null,function*(){try{let i=yield x(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations/${t}?cluster=${g}`,{headers:C});if(i.ok){let o=yield i.json();F(o)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),F=t=>{f();let i=Y(t);i!==D[t.flag]&&(E("Flag variation has changed for ",t.identifier),D[t.flag]=i,I[t.flag]=q(T({},t),{value:i}),pe(t)),N()};m=new P(V,u,d);let ve=()=>{let t=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):Z(r.identifier);break;case"delete":delete D[r.identifier],d.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),E("Evaluation deleted",{message:r,storage:D});break}},i=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),o=r=>!(!r||r.length==0||!r.every(h=>i(h))),p=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(h=>{F(h)}):V())},R=`${u.baseUrl}/stream?cluster=${g}`;v=new H(d,u,R,a,C,m,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&p(r)}),v.start()},Ee=()=>{m.start()},K=(t,i)=>d.on(t,i),me=(t,i)=>{t?d.off(t,i):ee()},Re=(t,i)=>{var r;if(!O||W||i===void 0)return;let o=i,p=t,R=S.find(h=>h.featureIdentifier===p&&h.featureValue===o);R?(G(R),R.variationIdentifier=((r=I[p])==null?void 0:r.identifier)||""):S.push({featureIdentifier:p,featureValue:o,count:1,variationIdentifier:I[p].identifier||"",lastAccessed:Date.now()})},ee=()=>{s=!0,u.streamEnabled&&(E("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&m.isPolling()&&(E("Closing Poller"),m.stop()),D=Q(),I={},clearTimeout(l)},te=(t,i=!0)=>{t.length&&U(()=>{let o=!!Object.keys(I).length;if(t.forEach(F),!o){f();let p=T({},D);N(),d.emit("ready",p)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=M(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&U(()=>{E("loading from cache",i),te(i,!1),d.emit("cache loaded",i)}),K("flags loaded",o=>{L(e.identifier,o),t=!1}),K("changed",o=>{t||(o.deleted?se(e.identifier,o.flag):oe(e.identifier,o))})}return{on:K,off:me,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{x=J(t)},refreshEvaluations:()=>{z&&!s&&Date.now()-X>=6e4&&(V(),X=Date.now())},variation:(t,i,o=!1)=>ce(t,i,D,Re,o)}};export{k as Event,lt as initialize}; | ||
var Re=Object.defineProperty,Se=Object.defineProperties;var Ie=Object.getOwnPropertyDescriptors;var ie=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,Oe=Object.prototype.propertyIsEnumerable;var ne=(n,t,a)=>t in n?Re(n,t,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[t]=a,T=(n,t)=>{for(var a in t||(t={}))ye.call(t,a)&&ne(n,a,t[a]);if(ie)for(var a of ie(t))Oe.call(t,a)&&ne(n,a,t[a]);return n},U=(n,t)=>Se(n,Ie(t));var w=(n,t,a)=>new Promise((s,c)=>{var h=R=>{try{m(a.next(R))}catch(l){c(l)}},p=R=>{try{m(a.throw(R))}catch(l){c(l)}},m=R=>R.done?s(R.value):Promise.resolve(R.value).then(h,p);m((a=a.apply(n,t)).next())});import we from"jwt-decode";import Ae from"mitt";var k=(g=>(g.READY="ready",g.CONNECTED="connected",g.DISCONNECTED="disconnected",g.STOPPED="stopped",g.POLLING="polling",g.POLLING_STOPPED="polling stopped",g.FLAGS_LOADED="flags loaded",g.CACHE_LOADED="cache loaded",g.CHANGED="changed",g.ERROR="error",g.ERROR_METRICS="metrics error",g.ERROR_AUTH="auth error",g.ERROR_FETCH_FLAGS="fetch flags error",g.ERROR_FETCH_FLAG="fetch flag error",g.ERROR_STREAM="stream error",g))(k||{});var Te={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,cache:!1},ae=n=>{let t=T(T({},Te),n);return t.pollingEnabled===void 0&&(t.pollingEnabled=t.streamEnabled),t},y=(n,...t)=>console.error(`[FF-SDK] ${n}`,...t),j=(n,t=!0)=>{t?setTimeout(n,0):n()},_=(n,t)=>Math.round(Math.random()*(t-n)+n);function re(n){return w(this,null,function*(){let a=new TextEncoder().encode(n),s=yield crypto.subtle.digest("SHA-256",a);return"HARNESS_FF_CACHE_"+Array.from(new Uint8Array(s)).map(p=>p.toString(16).padStart(2,"0")).join("")})}function M(n,t={}){let a=parseInt(window.localStorage.getItem(n+".ts"));if(t!=null&&t.ttl&&!isNaN(a)&&a+t.ttl<Date.now())return De(n),[];let s=window.localStorage.getItem(n);if(s)try{return JSON.parse(s)}catch(c){}return[]}function L(n,t){window.localStorage.setItem(n,JSON.stringify(t)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(n,t){let a=M(n),s=a.find(({flag:c})=>c===t.flag);s?Object.assign(s,t):a.push(t),L(n,a)}function se(n,t){let a=M(n),s=a.findIndex(({flag:c})=>c===t);s>-1&&(a.splice(s,1),L(n,a))}function De(n){window.localStorage.removeItem(n),window.localStorage.removeItem(n+".ts")}function q(n){return function(...a){let[s,c]=n(a);return fetch(s,c)}}var le=3e4,H=class{constructor(t,a,s,c,h,p,m){this.closed=!1;this.connectionOpened=!1;this.disconnectEventEmitted=!1;this.eventBus=t,this.configurations=a,this.url=s,this.apiKey=c,this.standardHeaders=h,this.eventCallback=m,this.fallbackPoller=p}start(){let t=l=>{l.toString().split(/\r?\n/).forEach(a)},a=l=>{if(l.startsWith("data:")){let O=JSON.parse(l.substring(5));this.logDebug("Received event from stream: ",O),this.eventCallback(O)}},s=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},c=()=>{clearInterval(this.readTimeoutCheckerId);let l=_(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+l+"ms"),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>this.start(),l)},h=l=>{l&&y("Stream has issue",l),this.fallBackToPolling(),this.eventBus.emit("stream error",l),this.eventBus.emit("error",l),c()},p=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[l,O]of Object.entries(p))this.xhr.setRequestHeader(l,O);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{this.connectionOpened=!1,h("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.connectionOpened=!1,this.logDebug("SSE aborted"),this.closed||h(null)},this.xhr.ontimeout=()=>{this.connectionOpened=!1,h("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){h(`HTTP code ${this.xhr.status}`);return}this.connectionOpened||(s(),this.connectionOpened=!0,this.disconnectEventEmitted=!1)};let m=0,R=Date.now();this.xhr.onprogress=()=>{this.connectionOpened||(s(),this.connectionOpened=!0,this.disconnectEventEmitted=!1),this.stopFallBackPolling(),R=Date.now();let l=this.xhr.responseText.slice(m);m+=l.length,this.logDebug("SSE GOT: "+l),t(l)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-le&&(y("SSE read timeout"),this.xhr.abort())},le),this.xhr.send()}close(){this.connectionOpened=!1,this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.eventBus.emit("stopped"),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(t,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${t}`,...a)}};function ce(n,t,a,s,c){let h=n in a,p=h?a[n]:t;return h&&s(n,p),c?{value:p,isDefaultValue:!h}:p}var P=class{constructor(t,a,s){this.fetchFlagsFn=t;this.configurations=a;this.eventBus=s;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return w(this,null,function*(){for(let t=1;t<=this.maxAttempts;t++){let a=yield this.fetchFlagsFn();if(a.type==="success"){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",a.error),t>=this.maxAttempts){this.logDebug(`Maximum attempts reached for polling for flags. Next poll in ${this.configurations.pollingInterval}ms.`);return}this.logDebug(`Polling for flags attempt #${t} failed. Remaining attempts: ${this.maxAttempts-t}`,a.error);let s=_(1e3,1e4);yield new Promise(c=>setTimeout(c,s))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(t,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${t}`,...a)}};var ge="1.22.0",fe=`Javascript ${ge} Client`,Ce=500,Fe=globalThis.fetch,J=!!globalThis.Proxy,W=n=>{let{value:t}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":t=Number(t);break;case"boolean":t=t.toString().toLowerCase()==="true";break;case"json":t=JSON.parse(t);break}}catch(a){y(a)}return t},ct=(n,t,a)=>{let s=!1,c,h,p,m,R,l,O=!0,A={},x=q(e=>e),Y=0,X=!1,g=()=>{O=!1},N=()=>{O=!0},S=[],d=Ae(),f=ae(a);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let E=(e,...i)=>{f.debug&&console.debug(`[FF-SDK] ${e}`,...i)},G=e=>{if(O){let i=Date.now();i-e.lastAccessed>Ce&&(e.count++,e.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(g(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),N())};let he=(e,i)=>w(void 0,null,function*(){return(yield(yield Fe(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":fe},body:JSON.stringify({apiKey:e,target:U(T({},t),{identifier:String(t.identifier)})})})).json()).authToken}),B=0,$=()=>{if(S.length){E("Sending metrics...",{metrics:S,evaluations:I});let e={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:t.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:ge}]}))};x(`${f.eventUrl}/metrics/${c}?cluster=${h}`,{method:"POST",headers:T({"Content-Type":"application/json"},A),body:JSON.stringify(e)}).then(()=>{S=[],B=0}).catch(i=>{B++&&(S=[],B=0),E(i),d.emit("metrics error",i)}).finally(()=>{l=window.setTimeout($,f.eventsSyncInterval)})}else l=window.setTimeout($,f.eventsSyncInterval)},I={},pe=e=>{E("Sending event for",e.flag),J?d.emit("changed",new Proxy(e,{get(i,o){var u;if(O&&i.hasOwnProperty(o)&&o==="value"){let b=i.flag,r=e.value,v=S.find(F=>F.featureIdentifier===b&&F.featureValue===r);v?(G(v),v.variationIdentifier=((u=I[b])==null?void 0:u.identifier)||""):S.push({featureIdentifier:b,featureValue:String(r),variationIdentifier:I[b].identifier||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?W(e):e[o]}})):d.emit("changed",{deleted:e.deleted,flag:e.flag,value:W(e)})},z=function(){return J?new Proxy({},{get(e,i){var u,b,r;let o=e[i];if(O&&e.hasOwnProperty(i)){let v=e[i],F=S.find(te=>te.featureIdentifier===i&&v===te.featureValue);F?(F.variationIdentifier=((u=I[i])==null?void 0:u.identifier)||"",G(F)):S.push({featureIdentifier:i,featureValue:v,variationIdentifier:((b=I[i])==null?void 0:b.identifier)||"",count:1,lastAccessed:Date.now()}),E("Metrics event: Flag:",i,"has been read with value:",v,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return o}}):{}},D=z();he(n,f).then(e=>w(void 0,null,function*(){if(s)return;R=e;let i=we(e);A={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":fe};let o=btoa(JSON.stringify(t));if(o.length<262144&&(A["Harness-Target"]=o),E("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,E("Picking up metrics from previous session")}catch(r){}l=window.setTimeout($,f.eventsSyncInterval),c=i.environment,h=i.clusterIdentifier;let u=!!Object.keys(I).length;if((yield V()).type==="success"&&E("Fetch all flags ok",D),!s){if(f.streamEnabled?(E("Streaming mode enabled"),ve()):f.pollingEnabled?(E("Polling mode enabled"),Ee()):E("Streaming and polling mode disabled"),!u){g();let r=T({},D);N(),d.emit("ready",r)}X=!0}})).catch(e=>{y("Authentication error: ",e),d.emit("auth error",e),d.emit("error",e)});let V=()=>w(void 0,null,function*(){try{let e=yield x(`${f.baseUrl}/client/env/${c}/target/${t.identifier}/evaluations?cluster=${h}`,{headers:A});if(e.ok){let i=yield e.json();return i.forEach(C),d.emit("flags loaded",i),{type:"success",data:i}}else return y("Features fetch operation error: ",e),d.emit("fetch flags error",e),d.emit("error",e),{type:"error",error:e}}catch(e){return y("Features fetch operation error: ",e),d.emit("fetch flags error",e),d.emit("error",e),{type:"error",error:e}}}),Q=e=>w(void 0,null,function*(){try{let i=yield x(`${f.baseUrl}/client/env/${c}/target/${t.identifier}/evaluations/${e}?cluster=${h}`,{headers:A});if(i.ok){let o=yield i.json();C(o)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),C=e=>{g();let i=W(e);i!==D[e.flag]&&(E("Flag variation has changed for ",e.identifier),D[e.flag]=i,I[e.flag]=U(T({},e),{value:i}),pe(e)),N()};m=new P(V,f,d);let ve=()=>{let e=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):setTimeout(()=>Q(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):Q(r.identifier);break;case"delete":delete D[r.identifier],d.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),E("Evaluation deleted",{message:r,storage:D});break}},i=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),o=r=>!(!r||r.length==0||!r.every(v=>i(v))),u=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(v=>{C(v)}):V())},b=`${f.baseUrl}/stream?cluster=${h}`;p=new H(d,f,b,n,A,m,r=>{r.domain==="flag"?e(r):r.domain==="target-segment"&&u(r)}),p.start()},Ee=()=>{m.start()},K=(e,i)=>d.on(e,i),me=(e,i)=>{e?d.off(e,i):Z()},be=(e,i)=>{var r;if(!O||J||i===void 0)return;let o=i,u=e,b=S.find(v=>v.featureIdentifier===u&&v.featureValue===o);b?(G(b),b.variationIdentifier=((r=I[u])==null?void 0:r.identifier)||""):S.push({featureIdentifier:u,featureValue:o,count:1,variationIdentifier:I[u].identifier||"",lastAccessed:Date.now()})},Z=()=>{s=!0,f.streamEnabled&&(E("Closing event stream"),typeof(p==null?void 0:p.close)=="function"&&p.close(),d.all.clear()),f.pollingEnabled&&m.isPolling()&&(E("Closing Poller"),m.stop()),D=z(),I={},clearTimeout(l)},ee=(e,i=!0)=>{e.length&&j(()=>{let o=!!Object.keys(I).length;if(e.forEach(C),!o){g();let u=T({},D);N(),d.emit("ready",u)}},i)};return f.cache&&"localStorage"in window&&re(t.identifier+n).then(e=>{let i=!0,o=M(e,typeof f.cache=="boolean"?{}:f.cache);o!=null&&o.length&&j(()=>{E("loading from cache",o),ee(o,!1),d.emit("cache loaded",o)}),K("flags loaded",u=>{L(e,u),i=!1}),K("changed",u=>{i||(u.deleted?se(e,u.flag):oe(e,u))})}),{on:K,off:me,close:Z,setEvaluations:ee,registerAPIRequestMiddleware:e=>{x=q(e)},refreshEvaluations:()=>{X&&!s&&Date.now()-Y>=6e4&&(V(),Y=Date.now())},variation:(e,i,o=!1)=>ce(e,i,D,be,o)}};export{k as Event,ct as initialize}; |
{ | ||
"name": "@harnessio/ff-javascript-client-sdk", | ||
"version": "1.21.0", | ||
"version": "1.22.0", | ||
"author": "Harness", | ||
@@ -5,0 +5,0 @@ "license": "Apache-2.0", |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
88721
398