Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

@harnessio/ff-javascript-client-sdk

Package Overview
Dependencies
Maintainers
8
Versions
113
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

@harnessio/ff-javascript-client-sdk - npm Package Compare versions

Comparing version 1.23.1-alpha.2 to 1.23.1-alpha.3

2

dist/sdk.cjs.js

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

var Oe=Object.create;var P=Object.defineProperty,we=Object.defineProperties,Ae=Object.getOwnPropertyDescriptor,De=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ne=Object.getOwnPropertySymbols,Ce=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty,Pe=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,I=(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))Pe.call(e,a)&&ae(i,a,e[a]);return i},j=(i,e)=>we(i,De(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?Oe(Ce(i)):{},oe(e||!i||!i.__esModule?P(a,"default",{value:i,enumerable:!0}):a,i)),Ve=i=>oe(P({},"__esModule",{value:!0}),i);var y=(i,e,a)=>new Promise((o,l)=>{var h=b=>{try{E(a.next(b))}catch(w){l(w)}},v=b=>{try{E(a.throw(b))}catch(w){l(w)}},E=b=>b.done?o(b.value):Promise.resolve(b.value).then(h,v);E((a=a.apply(i,e)).next())});var Ge={};Ne(Ge,{Event:()=>N,initialize:()=>He});module.exports=Ve(Ge);var me=se(require("jwt-decode")),pe=se(require("mitt"));var N=(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))(N||{});var _e={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=I(I({},_e),i);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},T=(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 y(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(v=>v.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 ke(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 ue(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 de(i,e){let a=L(i),o=a.findIndex(({flag:l})=>l===e);o>-1&&(a.splice(o,1),H(i,a))}function ke(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 xe=3e4,G=class{constructor(e,a,o,l,h,v,E){this.eventBus=e;this.configurations=a;this.url=o;this.apiKey=l;this.standardHeaders=h;this.fallbackPoller=v;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(a=>y(this,null,function*(){this.stopFallbackPolling();let o=new TextDecoder,l=a.body.getReader(),h;do if(h=yield l.read(),!h.done){this.recordAccess();let v=o.decode(h.value);this.logDebug(`SSE GOT: ${v}`),v.split(/\r?\n/).forEach(E=>{if(E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!h.done)})).catch(a=>{(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||a)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),xe)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&T("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=M(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 fe(i,e,a,o,l){let h=i in a,v=h?a[i]:e;return h&&o(i,v),l?{value:v,isDefaultValue:!h}:v}var V=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 y(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(T("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 Ee="1.23.0",ve=`Javascript ${Ee} 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){T(a)}return e},He=(i,e,a)=>{let o=!1,l,h,v,E,b,w,A=!0,D={},_=J(t=>t),z=0,Q=!1,f=()=>{A=!1},k=()=>{A=!0},R=[],c=(0,pe.default)(),u=le(a);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let p=(t,...n)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...n)},$=t=>{if(A){let n=Date.now();n-t.lastAccessed>Me&&(t.count++,t.lastAccessed=n)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),k())};let be=(t,n)=>y(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(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,K=()=>{if(R.length){p("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:Ee}]}))};_(`${u.eventUrl}/metrics/${l}?cluster=${h}`,{method:"POST",headers:I({"Content-Type":"application/json"},D),body:JSON.stringify(t)}).then(()=>{R=[],B=0}).catch(n=>{B++&&(R=[],B=0),p(n),c.emit("metrics error",n)}).finally(()=>{w=window.setTimeout(K,u.eventsSyncInterval)})}else w=window.setTimeout(K,u.eventsSyncInterval)},S={},Re=t=>{p("Sending event for",t.flag),W?c.emit("changed",new Proxy(t,{get(n,s){var d;if(A&&n.hasOwnProperty(s)&&s==="value"){let g=n.flag,r=t.value,m=R.find(C=>C.featureIdentifier===g&&C.featureValue===r);m?($(m),m.variationIdentifier=((d=S[g])==null?void 0:d.identifier)||""):R.push({featureIdentifier:g,featureValue:String(r),variationIdentifier:S[g].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",s,"has been read with value via stream update",r)}return s==="value"?Y(t):t[s]}})):c.emit("changed",{deleted:t.deleted,flag:t.flag,value:Y(t)})},X=function(){return W?new Proxy({},{get(t,n){var d,g,r;let s=t[n];if(A&&t.hasOwnProperty(n)){let m=t[n],C=R.find(ie=>ie.featureIdentifier===n&&m===ie.featureValue);C?(C.variationIdentifier=((d=S[n])==null?void 0:d.identifier)||"",$(C)):R.push({featureIdentifier:n,featureValue:m,variationIdentifier:((g=S[n])==null?void 0:g.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",n,"has been read with value:",m,"variationIdentifier:",(r=S[n])==null?void 0:r.identifier)}return s}}):{}},O=X();be(i,u).then(t=>y(void 0,null,function*(){if(o)return;b=t;let n=(0,me.default)(t);if(D={Authorization:`Bearer ${b}`,"Harness-AccountID":n.accountID,"Harness-EnvironmentID":n.environmentIdentifier,"Harness-SDK-Info":ve},globalThis.btoa){let g=globalThis.btoa(JSON.stringify(e));g.length<262144&&(D["Harness-Target"]=g)}if(p("Authenticated",n),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,p("Picking up metrics from previous session")}catch(g){}w=window.setTimeout(K,u.eventsSyncInterval),l=n.environment,h=n.clusterIdentifier;let s=!!Object.keys(S).length;if((yield x()).type==="success"&&p("Fetch all flags ok",O),!o){if(u.streamEnabled?(p("Streaming mode enabled"),Se()):u.pollingEnabled?(p("Polling mode enabled"),Ie()):p("Streaming and polling mode disabled"),!s){f();let g=I({},O);k(),c.emit("ready",g)}Q=!0}})).catch(t=>{T("Authentication error: ",t),c.emit("auth error",t),c.emit("error",t)});let x=()=>y(void 0,null,function*(){try{let t=yield _(`${u.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${h}`,{headers:D});if(t.ok){let n=yield t.json();return n.forEach(F),c.emit("flags loaded",n),{type:"success",data:n}}else return T("Features fetch operation error: ",t),c.emit("fetch flags error",t),c.emit("error",t),{type:"error",error:t}}catch(t){return T("Features fetch operation error: ",t),c.emit("fetch flags error",t),c.emit("error",t),{type:"error",error:t}}}),Z=t=>y(void 0,null,function*(){try{let n=yield _(`${u.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${h}`,{headers:D});if(n.ok){let s=yield n.json();F(s)}else T("Feature fetch operation error: ",n),c.emit("fetch flag error",n),c.emit("error",n)}catch(n){T("Feature fetch operation error: ",n),c.emit("fetch flag error",n),c.emit("error",n)}}),F=t=>{f();let n=Y(t);n!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=n,S[t.flag]=j(I({},t),{value:n}),Re(t)),k()};E=new V(x,u,c);let Se=()=>{let t=r=>{switch(r.event){case"create":s(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":s(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):Z(r.identifier);break;case"delete":delete O[r.identifier],c.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),p("Evaluation deleted",{message:r,storage:O});break}},n=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),s=r=>!(!r||r.length==0||!r.every(m=>n(m))),d=r=>{r.event==="patch"&&(s(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):x())},g=`${u.baseUrl}/stream?cluster=${h}`;v=new G(c,u,g,i,D,E,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&d(r)}),v.start()},Ie=()=>{E.start()},U=(t,n)=>c.on(t,n),ye=(t,n)=>{t?c.off(t,n):ee()},Te=(t,n)=>{var r;if(!A||W||n===void 0)return;let s=n,d=t,g=R.find(m=>m.featureIdentifier===d&&m.featureValue===s);g?($(g),g.variationIdentifier=((r=S[d])==null?void 0:r.identifier)||""):R.push({featureIdentifier:d,featureValue:s,count:1,variationIdentifier:S[d].identifier||"",lastAccessed:Date.now()})},ee=()=>{o=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),c.all.clear()),u.pollingEnabled&&E.isPolling()&&(p("Closing Poller"),E.stop()),O=X(),S={},clearTimeout(w)},te=(t,n=!0)=>{t.length&&q(()=>{let s=!!Object.keys(S).length;if(t.forEach(F),!s){f();let d=I({},O);k(),c.emit("ready",d)}},n)};return u.cache&&"localStorage"in window&&ce(e.identifier+i).then(t=>{let n=!0,s=L(t,typeof u.cache=="boolean"?{}:u.cache);s!=null&&s.length&&q(()=>{p("loading from cache",s),te(s,!1),c.emit("cache loaded",s)}),U("flags loaded",d=>{H(t,d),n=!1}),U("changed",d=>{n||(d.deleted?de(t,d.flag):ue(t,d))})}),{on:U,off:ye,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{_=J(t)},refreshEvaluations:()=>{Q&&!o&&Date.now()-z>=6e4&&(x(),z=Date.now())},variation:(t,n,s=!1)=>fe(t,n,O,Te,s)}};0&&(module.exports={Event,initialize});
var De=Object.create;var P=Object.defineProperty,Fe=Object.defineProperties,Ce=Object.getOwnPropertyDescriptor,Oe=Object.getOwnPropertyDescriptors,we=Object.getOwnPropertyNames,ne=Object.getOwnPropertySymbols,Ae=Object.getPrototypeOf,re=Object.prototype.hasOwnProperty,Pe=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,I=(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))Pe.call(e,a)&&ae(i,a,e[a]);return i},j=(i,e)=>Fe(i,Oe(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 we(e))!re.call(i,l)&&l!==a&&P(i,l,{get:()=>e[l],enumerable:!(o=Ce(e,l))||o.enumerable});return i};var se=(i,e,a)=>(a=i!=null?De(Ae(i)):{},oe(e||!i||!i.__esModule?P(a,"default",{value:i,enumerable:!0}):a,i)),Ve=i=>oe(P({},"__esModule",{value:!0}),i);var T=(i,e,a)=>new Promise((o,l)=>{var h=b=>{try{E(a.next(b))}catch(F){l(F)}},v=b=>{try{E(a.throw(b))}catch(F){l(F)}},E=b=>b.done?o(b.value):Promise.resolve(b.value).then(h,v);E((a=a.apply(i,e)).next())});var Ge={};Ne(Ge,{Event:()=>N,initialize:()=>He});module.exports=Ve(Ge);var me=se(require("jwt-decode")),pe=se(require("mitt"));var N=(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))(N||{});var _e={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=I(I({},_e),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 T(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(v=>v.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 ke(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 ue(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 de(i,e){let a=L(i),o=a.findIndex(({flag:l})=>l===e);o>-1&&(a.splice(o,1),H(i,a))}function ke(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 xe=3e4,G=class{constructor(e,a,o,l,h,v,E){this.eventBus=e;this.configurations=a;this.url=o;this.apiKey=l;this.standardHeaders=h;this.fallbackPoller=v;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(a=>T(this,null,function*(){this.logDebug("FETCH 1"),this.stopFallbackPolling();let o=new TextDecoder,l=a.body.getReader(),h;do if(h=yield l.read(),this.logDebug("FETCH 2"),!h.done){this.logDebug("FETCH 3"),this.recordAccess();let v=o.decode(h.value);this.logDebug(`SSE GOT: ${v}`),v.split(/\r?\n/).forEach(E=>{if(this.logDebug("FETCH 4"),E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!h.done)})).catch(a=>{this.logDebug("FETCH 5"),(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||a)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),xe)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=M(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 fe(i,e,a,o,l){let h=i in a,v=h?a[i]:e;return h&&o(i,v),l?{value:v,isDefaultValue:!h}:v}var V=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 T(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 Ee="1.23.0",ve=`Javascript ${Ee} 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,v,E,b,F,C=!0,O={},_=J(t=>t),z=0,Q=!1,f=()=>{C=!1},k=()=>{C=!0},R=[],c=(0,pe.default)(),u=le(a);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let p=(t,...n)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...n)},$=t=>{if(C){let n=Date.now();n-t.lastAccessed>Me&&(t.count++,t.lastAccessed=n)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),k())};let be=(t,n)=>T(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(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,K=()=>{if(R.length){p("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:Ee}]}))};_(`${u.eventUrl}/metrics/${l}?cluster=${h}`,{method:"POST",headers:I({"Content-Type":"application/json"},O),body:JSON.stringify(t)}).then(()=>{R=[],B=0}).catch(n=>{B++&&(R=[],B=0),p(n),c.emit("metrics error",n)}).finally(()=>{F=window.setTimeout(K,u.eventsSyncInterval)})}else F=window.setTimeout(K,u.eventsSyncInterval)},S={},Re=t=>{p("Sending event for",t.flag),W?c.emit("changed",new Proxy(t,{get(n,s){var d;if(C&&n.hasOwnProperty(s)&&s==="value"){let g=n.flag,r=t.value,m=R.find(A=>A.featureIdentifier===g&&A.featureValue===r);m?($(m),m.variationIdentifier=((d=S[g])==null?void 0:d.identifier)||""):R.push({featureIdentifier:g,featureValue:String(r),variationIdentifier:S[g].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",s,"has been read with value via stream update",r)}return s==="value"?Y(t):t[s]}})):c.emit("changed",{deleted:t.deleted,flag:t.flag,value:Y(t)})},X=function(){return W?new Proxy({},{get(t,n){var d,g,r;let s=t[n];if(C&&t.hasOwnProperty(n)){let m=t[n],A=R.find(ie=>ie.featureIdentifier===n&&m===ie.featureValue);A?(A.variationIdentifier=((d=S[n])==null?void 0:d.identifier)||"",$(A)):R.push({featureIdentifier:n,featureValue:m,variationIdentifier:((g=S[n])==null?void 0:g.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",n,"has been read with value:",m,"variationIdentifier:",(r=S[n])==null?void 0:r.identifier)}return s}}):{}},D=X();be(i,u).then(t=>T(void 0,null,function*(){if(o)return;b=t;let n=(0,me.default)(t);if(O={Authorization:`Bearer ${b}`,"Harness-AccountID":n.accountID,"Harness-EnvironmentID":n.environmentIdentifier,"Harness-SDK-Info":ve},globalThis.btoa){let g=globalThis.btoa(JSON.stringify(e));g.length<262144&&(O["Harness-Target"]=g)}if(p("Authenticated",n),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,p("Picking up metrics from previous session")}catch(g){}F=window.setTimeout(K,u.eventsSyncInterval),l=n.environment,h=n.clusterIdentifier;let s=!!Object.keys(S).length;if((yield x()).type==="success"&&p("Fetch all flags ok",D),!o){if(u.streamEnabled?(p("Streaming mode enabled"),Se()):u.pollingEnabled?(p("Polling mode enabled"),Ie()):p("Streaming and polling mode disabled"),!s){f();let g=I({},D);k(),c.emit("ready",g)}Q=!0}})).catch(t=>{y("Authentication error: ",t),c.emit("auth error",t),c.emit("error",t)});let x=()=>T(void 0,null,function*(){try{let t=yield _(`${u.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${h}`,{headers:O});if(t.ok){let n=yield t.json();return n.forEach(w),c.emit("flags loaded",n),{type:"success",data:n}}else return y("Features fetch operation error: ",t),c.emit("fetch flags error",t),c.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),c.emit("fetch flags error",t),c.emit("error",t),{type:"error",error:t}}}),Z=t=>T(void 0,null,function*(){try{let n=yield _(`${u.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${h}`,{headers:O});if(n.ok){let s=yield n.json();w(s)}else y("Feature fetch operation error: ",n),c.emit("fetch flag error",n),c.emit("error",n)}catch(n){y("Feature fetch operation error: ",n),c.emit("fetch flag error",n),c.emit("error",n)}}),w=t=>{f();let n=Y(t);n!==D[t.flag]&&(p("Flag variation has changed for ",t.identifier),D[t.flag]=n,S[t.flag]=j(I({},t),{value:n}),Re(t)),k()};E=new V(x,u,c);let Se=()=>{let t=r=>{switch(r.event){case"create":s(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":s(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):Z(r.identifier);break;case"delete":delete D[r.identifier],c.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),p("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(m=>n(m))),d=r=>{r.event==="patch"&&(s(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):x())},g=`${u.baseUrl}/stream?cluster=${h}`;v=new G(c,u,g,i,O,E,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&d(r)}),v.start()},Ie=()=>{E.start()},U=(t,n)=>c.on(t,n),Te=(t,n)=>{t?c.off(t,n):ee()},ye=(t,n)=>{var r;if(!C||W||n===void 0)return;let s=n,d=t,g=R.find(m=>m.featureIdentifier===d&&m.featureValue===s);g?($(g),g.variationIdentifier=((r=S[d])==null?void 0:r.identifier)||""):R.push({featureIdentifier:d,featureValue:s,count:1,variationIdentifier:S[d].identifier||"",lastAccessed:Date.now()})},ee=()=>{o=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),c.all.clear()),u.pollingEnabled&&E.isPolling()&&(p("Closing Poller"),E.stop()),D=X(),S={},clearTimeout(F)},te=(t,n=!0)=>{t.length&&q(()=>{let s=!!Object.keys(S).length;if(t.forEach(w),!s){f();let d=I({},D);k(),c.emit("ready",d)}},n)};return u.cache&&"localStorage"in window&&ce(e.identifier+i).then(t=>{let n=!0,s=L(t,typeof u.cache=="boolean"?{}:u.cache);s!=null&&s.length&&q(()=>{p("loading from cache",s),te(s,!1),c.emit("cache loaded",s)}),U("flags loaded",d=>{H(t,d),n=!1}),U("changed",d=>{n||(d.deleted?de(t,d.flag):ue(t,d))})}),{on:U,off:Te,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{_=J(t)},refreshEvaluations:()=>{Q&&!o&&Date.now()-z>=6e4&&(x(),z=Date.now())},variation:(t,n,s=!1)=>fe(t,n,D,ye,s)}};0&&(module.exports={Event,initialize});

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

var HarnessFFSDK=(()=>{var x=Object.defineProperty,Oe=Object.defineProperties,Ae=Object.getOwnPropertyDescriptor,Ce=Object.getOwnPropertyDescriptors,De=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols;var se=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable;var oe=(t,e,n)=>e in t?x(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,I=(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))Fe.call(e,n)&&oe(t,n,e[n]);return t},J=(t,e)=>Oe(t,Ce(e));var Pe=(t,e)=>{for(var n in e)x(t,n,{get:e[n],enumerable:!0})},Ne=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of De(e))!se.call(t,s)&&s!==n&&x(t,s,{get:()=>e[s],enumerable:!(a=Ae(e,s))||a.enumerable});return t};var ke=t=>Ne(x({},"__esModule",{value:!0}),t);var w=(t,e,n)=>new Promise((a,s)=>{var c=b=>{try{E(n.next(b))}catch(O){s(O)}},g=b=>{try{E(n.throw(b))}catch(O){s(O)}},E=b=>b.done?a(b.value):Promise.resolve(b.value).then(c,g);E((n=n.apply(t,e)).next())});var Be={};Pe(Be,{Event:()=>P,initialize:()=>$e});function q(t){this.message=t}q.prototype=new Error,q.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 q("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,s=0,c=0,g="";a=e.charAt(c++);~a&&(n=s%4?64*n+a:a,s++%4)?g+=String.fromCharCode(255&n>>(-2*s&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return g};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 c=s.charCodeAt(0).toString(16).toUpperCase();return c.length<2&&(c="0"+c),"%"+c}))}(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 ue(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 P=(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))(P||{});var xe={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=t=>{let e=I(I({},xe),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 w(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(g=>g.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 Me(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 pe(t,e){let n=H(t),a=n.findIndex(({flag:s})=>s===e);a>-1&&(n.splice(a,1),G(t,n))}function Me(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 Le=3e4,$=class{constructor(e,n,a,s,c,g,E){this.eventBus=e;this.configurations=n;this.url=a;this.apiKey=s;this.standardHeaders=c;this.fallbackPoller=g;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(n=>w(this,null,function*(){this.stopFallbackPolling();let a=new TextDecoder,s=n.body.getReader(),c;do if(c=yield s.read(),!c.done){this.recordAccess();let g=a.decode(c.value);this.logDebug(`SSE GOT: ${g}`),g.split(/\r?\n/).forEach(E=>{if(E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!c.done)})).catch(n=>{(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||n)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),Le)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=L(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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(t,e,n,a,s){let c=t in n,g=c?n[t]:e;return c&&a(t,g),s?{value:g,isDefaultValue:!c}:g}var N=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 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 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 be="1.23.0",Ee=`Javascript ${be} 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(n){y(n)}return e},$e=(t,e,n)=>{let a=!1,s,c,g,E,b,O,A=!0,C={},k=Y(i=>i),X=0,Z=!1,p=()=>{A=!1},V=()=>{A=!0},R=[],u=ue(),d=de(n);d.eventsSyncInterval<6e4&&(d.eventsSyncInterval=6e4),d.pollingInterval<6e4&&(d.pollingInterval=6e4);let m=(i,...r)=>{d.debug&&console.debug(`[FF-SDK] ${i}`,...r)},B=i=>{if(A){let r=Date.now();r-i.lastAccessed>He&&(i.count++,i.lastAccessed=r)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),V())};let Re=(i,r)=>w(void 0,null,function*(){return(yield(yield Ge(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":Ee},body:JSON.stringify({apiKey:i,target:J(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,U=()=>{if(R.length){m("Sending metrics...",{metrics:R,evaluations:S});let i={metricsData:R.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:be}]}))};k(`${d.eventUrl}/metrics/${s}?cluster=${c}`,{method:"POST",headers:I({"Content-Type":"application/json"},C),body:JSON.stringify(i)}).then(()=>{R=[],K=0}).catch(r=>{K++&&(R=[],K=0),m(r),u.emit("metrics error",r)}).finally(()=>{O=window.setTimeout(U,d.eventsSyncInterval)})}else O=window.setTimeout(U,d.eventsSyncInterval)},S={},Se=i=>{m("Sending event for",i.flag),z?u.emit("changed",new Proxy(i,{get(r,l){var f;if(A&&r.hasOwnProperty(l)&&l==="value"){let h=r.flag,o=i.value,v=R.find(F=>F.featureIdentifier===h&&F.featureValue===o);v?(B(v),v.variationIdentifier=((f=S[h])==null?void 0:f.identifier)||""):R.push({featureIdentifier:h,featureValue:String(o),variationIdentifier:S[h].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?Q(i):i[l]}})):u.emit("changed",{deleted:i.deleted,flag:i.flag,value:Q(i)})},ee=function(){return z?new Proxy({},{get(i,r){var f,h,o;let l=i[r];if(A&&i.hasOwnProperty(r)){let v=i[r],F=R.find(re=>re.featureIdentifier===r&&v===re.featureValue);F?(F.variationIdentifier=((f=S[r])==null?void 0:f.identifier)||"",B(F)):R.push({featureIdentifier:r,featureValue:v,variationIdentifier:((h=S[r])==null?void 0:h.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=S[r])==null?void 0:o.identifier)}return l}}):{}},T=ee();Re(t,d).then(i=>w(void 0,null,function*(){if(a)return;b=i;let r=ce(i);if(C={Authorization:`Bearer ${b}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":Ee},globalThis.btoa){let h=globalThis.btoa(JSON.stringify(e));h.length<262144&&(C["Harness-Target"]=h)}if(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(h){}O=window.setTimeout(U,d.eventsSyncInterval),s=r.environment,c=r.clusterIdentifier;let l=!!Object.keys(S).length;if((yield _()).type==="success"&&m("Fetch all flags ok",T),!a){if(d.streamEnabled?(m("Streaming mode enabled"),Ie()):d.pollingEnabled?(m("Polling mode enabled"),we()):m("Streaming and polling mode disabled"),!l){p();let h=I({},T);V(),u.emit("ready",h)}Z=!0}})).catch(i=>{y("Authentication error: ",i),u.emit("auth error",i),u.emit("error",i)});let _=()=>w(void 0,null,function*(){try{let i=yield k(`${d.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${c}`,{headers:C});if(i.ok){let r=yield i.json();return r.forEach(D),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=>w(void 0,null,function*(){try{let r=yield k(`${d.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${i}?cluster=${c}`,{headers:C});if(r.ok){let l=yield r.json();D(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)}}),D=i=>{p();let r=Q(i);r!==T[i.flag]&&(m("Flag variation has changed for ",i.identifier),T[i.flag]=r,S[i.flag]=J(I({},i),{value:r}),Se(i)),V()};E=new N(_,d,u);let Ie=()=>{let i=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(v=>{D(v)}):setTimeout(()=>te(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(v=>{D(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=>{D(v)}):_())},h=`${d.baseUrl}/stream?cluster=${c}`;g=new $(u,d,h,t,C,E,o=>{o.domain==="flag"?i(o):o.domain==="target-segment"&&f(o)}),g.start()},we=()=>{E.start()},j=(i,r)=>u.on(i,r),ye=(i,r)=>{i?u.off(i,r):ie()},Te=(i,r)=>{var o;if(!A||z||r===void 0)return;let l=r,f=i,h=R.find(v=>v.featureIdentifier===f&&v.featureValue===l);h?(B(h),h.variationIdentifier=((o=S[f])==null?void 0:o.identifier)||""):R.push({featureIdentifier:f,featureValue:l,count:1,variationIdentifier:S[f].identifier||"",lastAccessed:Date.now()})},ie=()=>{a=!0,d.streamEnabled&&(m("Closing event stream"),typeof(g==null?void 0:g.close)=="function"&&g.close(),u.all.clear()),d.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=ee(),S={},clearTimeout(O)},ne=(i,r=!0)=>{i.length&&W(()=>{let l=!!Object.keys(S).length;if(i.forEach(D),!l){p();let f=I({},T);V(),u.emit("ready",f)}},r)};return d.cache&&"localStorage"in window&&fe(e.identifier+t).then(i=>{let r=!0,l=H(i,typeof d.cache=="boolean"?{}:d.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?pe(i,f.flag):ge(i,f))})}),{on:j,off:ye,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:i=>{k=Y(i)},refreshEvaluations:()=>{Z&&!a&&Date.now()-X>=6e4&&(_(),X=Date.now())},variation:(i,r,l=!1)=>he(i,r,T,Te,l)}};return ke(Be);})();
var HarnessFFSDK=(()=>{var x=Object.defineProperty,Ce=Object.defineProperties,De=Object.getOwnPropertyDescriptor,Oe=Object.getOwnPropertyDescriptors,Ae=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols;var se=Object.prototype.hasOwnProperty,Fe=Object.prototype.propertyIsEnumerable;var oe=(t,e,n)=>e in t?x(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n,I=(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))Fe.call(e,n)&&oe(t,n,e[n]);return t},J=(t,e)=>Ce(t,Oe(e));var Pe=(t,e)=>{for(var n in e)x(t,n,{get:e[n],enumerable:!0})},Ne=(t,e,n,a)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of Ae(e))!se.call(t,s)&&s!==n&&x(t,s,{get:()=>e[s],enumerable:!(a=De(e,s))||a.enumerable});return t};var ke=t=>Ne(x({},"__esModule",{value:!0}),t);var w=(t,e,n)=>new Promise((a,s)=>{var c=b=>{try{E(n.next(b))}catch(C){s(C)}},g=b=>{try{E(n.throw(b))}catch(C){s(C)}},E=b=>b.done?a(b.value):Promise.resolve(b.value).then(c,g);E((n=n.apply(t,e)).next())});var Be={};Pe(Be,{Event:()=>P,initialize:()=>$e});function q(t){this.message=t}q.prototype=new Error,q.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 q("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,s=0,c=0,g="";a=e.charAt(c++);~a&&(n=s%4?64*n+a:a,s++%4)?g+=String.fromCharCode(255&n>>(-2*s&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return g};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 c=s.charCodeAt(0).toString(16).toUpperCase();return c.length<2&&(c="0"+c),"%"+c}))}(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 ue(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 P=(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))(P||{});var xe={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=t=>{let e=I(I({},xe),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 w(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(g=>g.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 Me(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 pe(t,e){let n=H(t),a=n.findIndex(({flag:s})=>s===e);a>-1&&(n.splice(a,1),G(t,n))}function Me(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 Le=3e4,$=class{constructor(e,n,a,s,c,g,E){this.eventBus=e;this.configurations=n;this.url=a;this.apiKey=s;this.standardHeaders=c;this.fallbackPoller=g;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(n=>w(this,null,function*(){this.logDebug("FETCH 1"),this.stopFallbackPolling();let a=new TextDecoder,s=n.body.getReader(),c;do if(c=yield s.read(),this.logDebug("FETCH 2"),!c.done){this.logDebug("FETCH 3"),this.recordAccess();let g=a.decode(c.value);this.logDebug(`SSE GOT: ${g}`),g.split(/\r?\n/).forEach(E=>{if(this.logDebug("FETCH 4"),E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!c.done)})).catch(n=>{this.logDebug("FETCH 5"),(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||n)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),Le)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=L(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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(t,e,n,a,s){let c=t in n,g=c?n[t]:e;return c&&a(t,g),s?{value:g,isDefaultValue:!c}:g}var N=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 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 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 be="1.23.0",Ee=`Javascript ${be} 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(n){y(n)}return e},$e=(t,e,n)=>{let a=!1,s,c,g,E,b,C,D=!0,O={},k=Y(i=>i),X=0,Z=!1,p=()=>{D=!1},V=()=>{D=!0},R=[],u=ue(),d=de(n);d.eventsSyncInterval<6e4&&(d.eventsSyncInterval=6e4),d.pollingInterval<6e4&&(d.pollingInterval=6e4);let m=(i,...r)=>{d.debug&&console.debug(`[FF-SDK] ${i}`,...r)},B=i=>{if(D){let r=Date.now();r-i.lastAccessed>He&&(i.count++,i.lastAccessed=r)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),V())};let Re=(i,r)=>w(void 0,null,function*(){return(yield(yield Ge(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":Ee},body:JSON.stringify({apiKey:i,target:J(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,U=()=>{if(R.length){m("Sending metrics...",{metrics:R,evaluations:S});let i={metricsData:R.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:be}]}))};k(`${d.eventUrl}/metrics/${s}?cluster=${c}`,{method:"POST",headers:I({"Content-Type":"application/json"},O),body:JSON.stringify(i)}).then(()=>{R=[],K=0}).catch(r=>{K++&&(R=[],K=0),m(r),u.emit("metrics error",r)}).finally(()=>{C=window.setTimeout(U,d.eventsSyncInterval)})}else C=window.setTimeout(U,d.eventsSyncInterval)},S={},Se=i=>{m("Sending event for",i.flag),z?u.emit("changed",new Proxy(i,{get(r,l){var f;if(D&&r.hasOwnProperty(l)&&l==="value"){let h=r.flag,o=i.value,v=R.find(F=>F.featureIdentifier===h&&F.featureValue===o);v?(B(v),v.variationIdentifier=((f=S[h])==null?void 0:f.identifier)||""):R.push({featureIdentifier:h,featureValue:String(o),variationIdentifier:S[h].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?Q(i):i[l]}})):u.emit("changed",{deleted:i.deleted,flag:i.flag,value:Q(i)})},ee=function(){return z?new Proxy({},{get(i,r){var f,h,o;let l=i[r];if(D&&i.hasOwnProperty(r)){let v=i[r],F=R.find(re=>re.featureIdentifier===r&&v===re.featureValue);F?(F.variationIdentifier=((f=S[r])==null?void 0:f.identifier)||"",B(F)):R.push({featureIdentifier:r,featureValue:v,variationIdentifier:((h=S[r])==null?void 0:h.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=S[r])==null?void 0:o.identifier)}return l}}):{}},T=ee();Re(t,d).then(i=>w(void 0,null,function*(){if(a)return;b=i;let r=ce(i);if(O={Authorization:`Bearer ${b}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":Ee},globalThis.btoa){let h=globalThis.btoa(JSON.stringify(e));h.length<262144&&(O["Harness-Target"]=h)}if(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(h){}C=window.setTimeout(U,d.eventsSyncInterval),s=r.environment,c=r.clusterIdentifier;let l=!!Object.keys(S).length;if((yield _()).type==="success"&&m("Fetch all flags ok",T),!a){if(d.streamEnabled?(m("Streaming mode enabled"),Ie()):d.pollingEnabled?(m("Polling mode enabled"),we()):m("Streaming and polling mode disabled"),!l){p();let h=I({},T);V(),u.emit("ready",h)}Z=!0}})).catch(i=>{y("Authentication error: ",i),u.emit("auth error",i),u.emit("error",i)});let _=()=>w(void 0,null,function*(){try{let i=yield k(`${d.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${c}`,{headers:O});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=>w(void 0,null,function*(){try{let r=yield k(`${d.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${i}?cluster=${c}`,{headers:O});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=Q(i);r!==T[i.flag]&&(m("Flag variation has changed for ",i.identifier),T[i.flag]=r,S[i.flag]=J(I({},i),{value:r}),Se(i)),V()};E=new N(_,d,u);let Ie=()=>{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)}):_())},h=`${d.baseUrl}/stream?cluster=${c}`;g=new $(u,d,h,t,O,E,o=>{o.domain==="flag"?i(o):o.domain==="target-segment"&&f(o)}),g.start()},we=()=>{E.start()},j=(i,r)=>u.on(i,r),ye=(i,r)=>{i?u.off(i,r):ie()},Te=(i,r)=>{var o;if(!D||z||r===void 0)return;let l=r,f=i,h=R.find(v=>v.featureIdentifier===f&&v.featureValue===l);h?(B(h),h.variationIdentifier=((o=S[f])==null?void 0:o.identifier)||""):R.push({featureIdentifier:f,featureValue:l,count:1,variationIdentifier:S[f].identifier||"",lastAccessed:Date.now()})},ie=()=>{a=!0,d.streamEnabled&&(m("Closing event stream"),typeof(g==null?void 0:g.close)=="function"&&g.close(),u.all.clear()),d.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=ee(),S={},clearTimeout(C)},ne=(i,r=!0)=>{i.length&&W(()=>{let l=!!Object.keys(S).length;if(i.forEach(A),!l){p();let f=I({},T);V(),u.emit("ready",f)}},r)};return d.cache&&"localStorage"in window&&fe(e.identifier+t).then(i=>{let r=!0,l=H(i,typeof d.cache=="boolean"?{}:d.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?pe(i,f.flag):ge(i,f))})}),{on:j,off:ye,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:i=>{k=Y(i)},refreshEvaluations:()=>{Z&&!a&&Date.now()-X>=6e4&&(_(),X=Date.now())},variation:(i,r,l=!1)=>he(i,r,T,Te,l)}};return ke(Be);})();

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

var ye=Object.defineProperty,Te=Object.defineProperties;var Oe=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var Ae=Object.prototype.hasOwnProperty,Ce=Object.prototype.propertyIsEnumerable;var ae=(i,e,n)=>e in i?ye(i,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):i[e]=n,I=(i,e)=>{for(var n in e||(e={}))Ae.call(e,n)&&ae(i,n,e[n]);if(re)for(var n of re(e))Ce.call(e,n)&&ae(i,n,e[n]);return i},j=(i,e)=>Te(i,Oe(e));var w=(i,e,n)=>new Promise((a,l)=>{var c=b=>{try{E(n.next(b))}catch(O){l(O)}},g=b=>{try{E(n.throw(b))}catch(O){l(O)}},E=b=>b.done?a(b.value):Promise.resolve(b.value).then(c,g);E((n=n.apply(i,e)).next())});function J(i){this.message=i}J.prototype=new Error,J.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 J("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,l=0,c=0,g="";a=e.charAt(c++);~a&&(n=l%4?64*n+a:a,l++%4)?g+=String.fromCharCode(255&n>>(-2*l&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return g};function De(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 c=l.charCodeAt(0).toString(16).toUpperCase();return c.length<2&&(c="0"+c),"%"+c}))}(e)}catch(n){return oe(e)}}function _(i){this.message=i}function Fe(i,e){if(typeof i!="string")throw new _("Invalid token specified");var n=(e=e||{}).header===!0?0:1;try{return JSON.parse(De(i.split(".")[n]))}catch(a){throw new _("Invalid token specified: "+a.message)}}_.prototype=new Error,_.prototype.name="InvalidTokenError";var se=Fe;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 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 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=I(I({},Pe),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 ue(i){return w(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(g=>g.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 Ne(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 de(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 Ne(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 ke=3e4,G=class{constructor(e,n,a,l,c,g,E){this.eventBus=e;this.configurations=n;this.url=a;this.apiKey=l;this.standardHeaders=c;this.fallbackPoller=g;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(n=>w(this,null,function*(){this.stopFallbackPolling();let a=new TextDecoder,l=n.body.getReader(),c;do if(c=yield l.read(),!c.done){this.recordAccess();let g=a.decode(c.value);this.logDebug(`SSE GOT: ${g}`),g.split(/\r?\n/).forEach(E=>{if(E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!c.done)})).catch(n=>{(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||n)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),ke)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=M(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 ge(i,e,n,a,l){let c=i in n,g=c?n[i]:e;return c&&a(i,g),l?{value:g,isDefaultValue:!c}:g}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 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 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 me="1.23.0",ve=`Javascript ${me} Client`,Ve=500,_e=globalThis.fetch,Y=!!globalThis.Proxy,z=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},mt=(i,e,n)=>{let a=!1,l,c,g,E,b,O,A=!0,C={},N=W(t=>t),Q=0,X=!1,p=()=>{A=!1},k=()=>{A=!0},R=[],u=le(),d=ce(n);d.eventsSyncInterval<6e4&&(d.eventsSyncInterval=6e4),d.pollingInterval<6e4&&(d.pollingInterval=6e4);let m=(t,...r)=>{d.debug&&console.debug(`[FF-SDK] ${t}`,...r)},$=t=>{if(A){let r=Date.now();r-t.lastAccessed>Ve&&(t.count++,t.lastAccessed=r)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),k())};let Ee=(t,r)=>w(void 0,null,function*(){return(yield(yield _e(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":ve},body:JSON.stringify({apiKey:t,target:j(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,K=()=>{if(R.length){m("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:me}]}))};N(`${d.eventUrl}/metrics/${l}?cluster=${c}`,{method:"POST",headers:I({"Content-Type":"application/json"},C),body:JSON.stringify(t)}).then(()=>{R=[],B=0}).catch(r=>{B++&&(R=[],B=0),m(r),u.emit("metrics error",r)}).finally(()=>{O=window.setTimeout(K,d.eventsSyncInterval)})}else O=window.setTimeout(K,d.eventsSyncInterval)},S={},be=t=>{m("Sending event for",t.flag),Y?u.emit("changed",new Proxy(t,{get(r,s){var f;if(A&&r.hasOwnProperty(s)&&s==="value"){let h=r.flag,o=t.value,v=R.find(F=>F.featureIdentifier===h&&F.featureValue===o);v?($(v),v.variationIdentifier=((f=S[h])==null?void 0:f.identifier)||""):R.push({featureIdentifier:h,featureValue:String(o),variationIdentifier:S[h].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",s,"has been read with value via stream update",o)}return s==="value"?z(t):t[s]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:z(t)})},Z=function(){return Y?new Proxy({},{get(t,r){var f,h,o;let s=t[r];if(A&&t.hasOwnProperty(r)){let v=t[r],F=R.find(ne=>ne.featureIdentifier===r&&v===ne.featureValue);F?(F.variationIdentifier=((f=S[r])==null?void 0:f.identifier)||"",$(F)):R.push({featureIdentifier:r,featureValue:v,variationIdentifier:((h=S[r])==null?void 0:h.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=S[r])==null?void 0:o.identifier)}return s}}):{}},T=Z();Ee(i,d).then(t=>w(void 0,null,function*(){if(a)return;b=t;let r=se(t);if(C={Authorization:`Bearer ${b}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":ve},globalThis.btoa){let h=globalThis.btoa(JSON.stringify(e));h.length<262144&&(C["Harness-Target"]=h)}if(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(h){}O=window.setTimeout(K,d.eventsSyncInterval),l=r.environment,c=r.clusterIdentifier;let s=!!Object.keys(S).length;if((yield V()).type==="success"&&m("Fetch all flags ok",T),!a){if(d.streamEnabled?(m("Streaming mode enabled"),Re()):d.pollingEnabled?(m("Polling mode enabled"),Se()):m("Streaming and polling mode disabled"),!s){p();let h=I({},T);k(),u.emit("ready",h)}X=!0}})).catch(t=>{y("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let V=()=>w(void 0,null,function*(){try{let t=yield N(`${d.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${c}`,{headers:C});if(t.ok){let r=yield t.json();return r.forEach(D),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=>w(void 0,null,function*(){try{let r=yield N(`${d.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${c}`,{headers:C});if(r.ok){let s=yield r.json();D(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)}}),D=t=>{p();let r=z(t);r!==T[t.flag]&&(m("Flag variation has changed for ",t.identifier),T[t.flag]=r,S[t.flag]=j(I({},t),{value:r}),be(t)),k()};E=new P(V,d,u);let Re=()=>{let t=o=>{switch(o.event){case"create":s(o.evaluations)?o.evaluations.forEach(v=>{D(v)}):setTimeout(()=>ee(o.identifier),1e3);break;case"patch":s(o.evaluations)?o.evaluations.forEach(v=>{D(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=>{D(v)}):V())},h=`${d.baseUrl}/stream?cluster=${c}`;g=new G(u,d,h,i,C,E,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&f(o)}),g.start()},Se=()=>{E.start()},U=(t,r)=>u.on(t,r),Ie=(t,r)=>{t?u.off(t,r):te()},we=(t,r)=>{var o;if(!A||Y||r===void 0)return;let s=r,f=t,h=R.find(v=>v.featureIdentifier===f&&v.featureValue===s);h?($(h),h.variationIdentifier=((o=S[f])==null?void 0:o.identifier)||""):R.push({featureIdentifier:f,featureValue:s,count:1,variationIdentifier:S[f].identifier||"",lastAccessed:Date.now()})},te=()=>{a=!0,d.streamEnabled&&(m("Closing event stream"),typeof(g==null?void 0:g.close)=="function"&&g.close(),u.all.clear()),d.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=Z(),S={},clearTimeout(O)},ie=(t,r=!0)=>{t.length&&q(()=>{let s=!!Object.keys(S).length;if(t.forEach(D),!s){p();let f=I({},T);k(),u.emit("ready",f)}},r)};return d.cache&&"localStorage"in window&&ue(e.identifier+i).then(t=>{let r=!0,s=L(t,typeof d.cache=="boolean"?{}:d.cache);s!=null&&s.length&&q(()=>{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):de(t,f))})}),{on:U,off:Ie,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{N=W(t)},refreshEvaluations:()=>{X&&!a&&Date.now()-Q>=6e4&&(V(),Q=Date.now())},variation:(t,r,s=!1)=>ge(t,r,T,we,s)}};export{x as Event,mt as initialize};
var ye=Object.defineProperty,Te=Object.defineProperties;var Ce=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var De=Object.prototype.hasOwnProperty,Oe=Object.prototype.propertyIsEnumerable;var ae=(i,e,n)=>e in i?ye(i,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):i[e]=n,I=(i,e)=>{for(var n in e||(e={}))De.call(e,n)&&ae(i,n,e[n]);if(re)for(var n of re(e))Oe.call(e,n)&&ae(i,n,e[n]);return i},j=(i,e)=>Te(i,Ce(e));var w=(i,e,n)=>new Promise((a,l)=>{var c=b=>{try{E(n.next(b))}catch(C){l(C)}},g=b=>{try{E(n.throw(b))}catch(C){l(C)}},E=b=>b.done?a(b.value):Promise.resolve(b.value).then(c,g);E((n=n.apply(i,e)).next())});function J(i){this.message=i}J.prototype=new Error,J.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 J("'atob' failed: The string to be decoded is not correctly encoded.");for(var n,a,l=0,c=0,g="";a=e.charAt(c++);~a&&(n=l%4?64*n+a:a,l++%4)?g+=String.fromCharCode(255&n>>(-2*l&6)):0)a="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(a);return g};function Ae(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 c=l.charCodeAt(0).toString(16).toUpperCase();return c.length<2&&(c="0"+c),"%"+c}))}(e)}catch(n){return oe(e)}}function _(i){this.message=i}function Fe(i,e){if(typeof i!="string")throw new _("Invalid token specified");var n=(e=e||{}).header===!0?0:1;try{return JSON.parse(Ae(i.split(".")[n]))}catch(a){throw new _("Invalid token specified: "+a.message)}}_.prototype=new Error,_.prototype.name="InvalidTokenError";var se=Fe;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 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 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=I(I({},Pe),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 ue(i){return w(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(g=>g.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 Ne(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 de(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 Ne(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 ke=3e4,G=class{constructor(e,n,a,l,c,g,E){this.eventBus=e;this.configurations=n;this.url=a;this.apiKey=l;this.standardHeaders=c;this.fallbackPoller=g;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(n=>w(this,null,function*(){this.logDebug("FETCH 1"),this.stopFallbackPolling();let a=new TextDecoder,l=n.body.getReader(),c;do if(c=yield l.read(),this.logDebug("FETCH 2"),!c.done){this.logDebug("FETCH 3"),this.recordAccess();let g=a.decode(c.value);this.logDebug(`SSE GOT: ${g}`),g.split(/\r?\n/).forEach(E=>{if(this.logDebug("FETCH 4"),E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!c.done)})).catch(n=>{this.logDebug("FETCH 5"),(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||n)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),ke)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=M(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 ge(i,e,n,a,l){let c=i in n,g=c?n[i]:e;return c&&a(i,g),l?{value:g,isDefaultValue:!c}:g}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 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 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 me="1.23.0",ve=`Javascript ${me} Client`,Ve=500,_e=globalThis.fetch,Y=!!globalThis.Proxy,z=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},mt=(i,e,n)=>{let a=!1,l,c,g,E,b,C,D=!0,O={},N=W(t=>t),Q=0,X=!1,p=()=>{D=!1},k=()=>{D=!0},R=[],u=le(),d=ce(n);d.eventsSyncInterval<6e4&&(d.eventsSyncInterval=6e4),d.pollingInterval<6e4&&(d.pollingInterval=6e4);let m=(t,...r)=>{d.debug&&console.debug(`[FF-SDK] ${t}`,...r)},$=t=>{if(D){let r=Date.now();r-t.lastAccessed>Ve&&(t.count++,t.lastAccessed=r)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(p(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),k())};let Ee=(t,r)=>w(void 0,null,function*(){return(yield(yield _e(`${r.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":ve},body:JSON.stringify({apiKey:t,target:j(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,K=()=>{if(R.length){m("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:me}]}))};N(`${d.eventUrl}/metrics/${l}?cluster=${c}`,{method:"POST",headers:I({"Content-Type":"application/json"},O),body:JSON.stringify(t)}).then(()=>{R=[],B=0}).catch(r=>{B++&&(R=[],B=0),m(r),u.emit("metrics error",r)}).finally(()=>{C=window.setTimeout(K,d.eventsSyncInterval)})}else C=window.setTimeout(K,d.eventsSyncInterval)},S={},be=t=>{m("Sending event for",t.flag),Y?u.emit("changed",new Proxy(t,{get(r,s){var f;if(D&&r.hasOwnProperty(s)&&s==="value"){let h=r.flag,o=t.value,v=R.find(F=>F.featureIdentifier===h&&F.featureValue===o);v?($(v),v.variationIdentifier=((f=S[h])==null?void 0:f.identifier)||""):R.push({featureIdentifier:h,featureValue:String(o),variationIdentifier:S[h].identifier||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag",s,"has been read with value via stream update",o)}return s==="value"?z(t):t[s]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:z(t)})},Z=function(){return Y?new Proxy({},{get(t,r){var f,h,o;let s=t[r];if(D&&t.hasOwnProperty(r)){let v=t[r],F=R.find(ne=>ne.featureIdentifier===r&&v===ne.featureValue);F?(F.variationIdentifier=((f=S[r])==null?void 0:f.identifier)||"",$(F)):R.push({featureIdentifier:r,featureValue:v,variationIdentifier:((h=S[r])==null?void 0:h.identifier)||"",count:1,lastAccessed:Date.now()}),m("Metrics event: Flag:",r,"has been read with value:",v,"variationIdentifier:",(o=S[r])==null?void 0:o.identifier)}return s}}):{}},T=Z();Ee(i,d).then(t=>w(void 0,null,function*(){if(a)return;b=t;let r=se(t);if(O={Authorization:`Bearer ${b}`,"Harness-AccountID":r.accountID,"Harness-EnvironmentID":r.environmentIdentifier,"Harness-SDK-Info":ve},globalThis.btoa){let h=globalThis.btoa(JSON.stringify(e));h.length<262144&&(O["Harness-Target"]=h)}if(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(h){}C=window.setTimeout(K,d.eventsSyncInterval),l=r.environment,c=r.clusterIdentifier;let s=!!Object.keys(S).length;if((yield V()).type==="success"&&m("Fetch all flags ok",T),!a){if(d.streamEnabled?(m("Streaming mode enabled"),Re()):d.pollingEnabled?(m("Polling mode enabled"),Se()):m("Streaming and polling mode disabled"),!s){p();let h=I({},T);k(),u.emit("ready",h)}X=!0}})).catch(t=>{y("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let V=()=>w(void 0,null,function*(){try{let t=yield N(`${d.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations?cluster=${c}`,{headers:O});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=>w(void 0,null,function*(){try{let r=yield N(`${d.baseUrl}/client/env/${l}/target/${e.identifier}/evaluations/${t}?cluster=${c}`,{headers:O});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=z(t);r!==T[t.flag]&&(m("Flag variation has changed for ",t.identifier),T[t.flag]=r,S[t.flag]=j(I({},t),{value:r}),be(t)),k()};E=new P(V,d,u);let Re=()=>{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)}):V())},h=`${d.baseUrl}/stream?cluster=${c}`;g=new G(u,d,h,i,O,E,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&f(o)}),g.start()},Se=()=>{E.start()},U=(t,r)=>u.on(t,r),Ie=(t,r)=>{t?u.off(t,r):te()},we=(t,r)=>{var o;if(!D||Y||r===void 0)return;let s=r,f=t,h=R.find(v=>v.featureIdentifier===f&&v.featureValue===s);h?($(h),h.variationIdentifier=((o=S[f])==null?void 0:o.identifier)||""):R.push({featureIdentifier:f,featureValue:s,count:1,variationIdentifier:S[f].identifier||"",lastAccessed:Date.now()})},te=()=>{a=!0,d.streamEnabled&&(m("Closing event stream"),typeof(g==null?void 0:g.close)=="function"&&g.close(),u.all.clear()),d.pollingEnabled&&E.isPolling()&&(m("Closing Poller"),E.stop()),T=Z(),S={},clearTimeout(C)},ie=(t,r=!0)=>{t.length&&q(()=>{let s=!!Object.keys(S).length;if(t.forEach(A),!s){p();let f=I({},T);k(),u.emit("ready",f)}},r)};return d.cache&&"localStorage"in window&&ue(e.identifier+i).then(t=>{let r=!0,s=L(t,typeof d.cache=="boolean"?{}:d.cache);s!=null&&s.length&&q(()=>{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):de(t,f))})}),{on:U,off:Ie,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{N=W(t)},refreshEvaluations:()=>{X&&!a&&Date.now()-Q>=6e4&&(V(),Q=Date.now())},variation:(t,r,s=!1)=>ge(t,r,T,we,s)}};export{x as Event,mt as initialize};

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

var be=Object.defineProperty,Re=Object.defineProperties;var Se=Object.getOwnPropertyDescriptors;var ie=Object.getOwnPropertySymbols;var Ie=Object.prototype.hasOwnProperty,ye=Object.prototype.propertyIsEnumerable;var ne=(n,e,a)=>e in n?be(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,I=(n,e)=>{for(var a in e||(e={}))Ie.call(e,a)&&ne(n,a,e[a]);if(ie)for(var a of ie(e))ye.call(e,a)&&ne(n,a,e[a]);return n},U=(n,e)=>Re(n,Se(e));var y=(n,e,a)=>new Promise((s,c)=>{var h=b=>{try{E(a.next(b))}catch(w){c(w)}},v=b=>{try{E(a.throw(b))}catch(w){c(w)}},E=b=>b.done?s(b.value):Promise.resolve(b.value).then(h,v);E((a=a.apply(n,e)).next())});import Ae from"jwt-decode";import De 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},ae=n=>{let e=I(I({},Te),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},T=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),j=(n,e=!0)=>{e?setTimeout(n,0):n()},x=(n,e)=>Math.round(Math.random()*(e-n)+n);function re(n){return y(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(v=>v.toString(16).padStart(2,"0")).join("")})}function M(n,e={}){let a=parseInt(window.localStorage.getItem(n+".ts"));if(e!=null&&e.ttl&&!isNaN(a)&&a+e.ttl<Date.now())return Oe(n),[];let s=window.localStorage.getItem(n);if(s)try{return JSON.parse(s)}catch(c){}return[]}function L(n,e){window.localStorage.setItem(n,JSON.stringify(e)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(n,e){let a=M(n),s=a.find(({flag:c})=>c===e.flag);s?Object.assign(s,e):a.push(e),L(n,a)}function se(n,e){let a=M(n),s=a.findIndex(({flag:c})=>c===e);s>-1&&(a.splice(s,1),L(n,a))}function Oe(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 we=3e4,H=class{constructor(e,a,s,c,h,v,E){this.eventBus=e;this.configurations=a;this.url=s;this.apiKey=c;this.standardHeaders=h;this.fallbackPoller=v;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(a=>y(this,null,function*(){this.stopFallbackPolling();let s=new TextDecoder,c=a.body.getReader(),h;do if(h=yield c.read(),!h.done){this.recordAccess();let v=s.decode(h.value);this.logDebug(`SSE GOT: ${v}`),v.split(/\r?\n/).forEach(E=>{if(E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!h.done)})).catch(a=>{(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||a)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),we)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&T("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=x(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 le(n,e,a,s,c){let h=n in a,v=h?a[n]:e;return h&&s(n,v),c?{value:v,isDefaultValue:!h}:v}var P=class{constructor(e,a,s){this.fetchFlagsFn=e;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 y(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(T("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 s=x(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,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var fe="1.23.0",de=`Javascript ${fe} Client`,Fe=500,Ce=globalThis.fetch,J=!!globalThis.Proxy,W=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){T(a)}return e},ut=(n,e,a)=>{let s=!1,c,h,v,E,b,w,A=!0,D={},N=q(t=>t),Y=0,z=!1,f=()=>{A=!1},V=()=>{A=!0},R=[],l=De(),u=ae(a);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let p=(t,...i)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...i)},G=t=>{if(A){let i=Date.now();i-t.lastAccessed>Fe&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),V())};let ge=(t,i)=>y(void 0,null,function*(){return(yield(yield Ce(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":de},body:JSON.stringify({apiKey:t,target:U(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,B=()=>{if(R.length){p("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:fe}]}))};N(`${u.eventUrl}/metrics/${c}?cluster=${h}`,{method:"POST",headers:I({"Content-Type":"application/json"},D),body:JSON.stringify(t)}).then(()=>{R=[],$=0}).catch(i=>{$++&&(R=[],$=0),p(i),l.emit("metrics error",i)}).finally(()=>{w=window.setTimeout(B,u.eventsSyncInterval)})}else w=window.setTimeout(B,u.eventsSyncInterval)},S={},he=t=>{p("Sending event for",t.flag),J?l.emit("changed",new Proxy(t,{get(i,o){var d;if(A&&i.hasOwnProperty(o)&&o==="value"){let g=i.flag,r=t.value,m=R.find(C=>C.featureIdentifier===g&&C.featureValue===r);m?(G(m),m.variationIdentifier=((d=S[g])==null?void 0:d.identifier)||""):R.push({featureIdentifier:g,featureValue:String(r),variationIdentifier:S[g].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?W(t):t[o]}})):l.emit("changed",{deleted:t.deleted,flag:t.flag,value:W(t)})},Q=function(){return J?new Proxy({},{get(t,i){var d,g,r;let o=t[i];if(A&&t.hasOwnProperty(i)){let m=t[i],C=R.find(te=>te.featureIdentifier===i&&m===te.featureValue);C?(C.variationIdentifier=((d=S[i])==null?void 0:d.identifier)||"",G(C)):R.push({featureIdentifier:i,featureValue:m,variationIdentifier:((g=S[i])==null?void 0:g.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",m,"variationIdentifier:",(r=S[i])==null?void 0:r.identifier)}return o}}):{}},O=Q();ge(n,u).then(t=>y(void 0,null,function*(){if(s)return;b=t;let i=Ae(t);if(D={Authorization:`Bearer ${b}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":de},globalThis.btoa){let g=globalThis.btoa(JSON.stringify(e));g.length<262144&&(D["Harness-Target"]=g)}if(p("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,p("Picking up metrics from previous session")}catch(g){}w=window.setTimeout(B,u.eventsSyncInterval),c=i.environment,h=i.clusterIdentifier;let o=!!Object.keys(S).length;if((yield _()).type==="success"&&p("Fetch all flags ok",O),!s){if(u.streamEnabled?(p("Streaming mode enabled"),ve()):u.pollingEnabled?(p("Polling mode enabled"),me()):p("Streaming and polling mode disabled"),!o){f();let g=I({},O);V(),l.emit("ready",g)}z=!0}})).catch(t=>{T("Authentication error: ",t),l.emit("auth error",t),l.emit("error",t)});let _=()=>y(void 0,null,function*(){try{let t=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations?cluster=${h}`,{headers:D});if(t.ok){let i=yield t.json();return i.forEach(F),l.emit("flags loaded",i),{type:"success",data:i}}else return T("Features fetch operation error: ",t),l.emit("fetch flags error",t),l.emit("error",t),{type:"error",error:t}}catch(t){return T("Features fetch operation error: ",t),l.emit("fetch flags error",t),l.emit("error",t),{type:"error",error:t}}}),X=t=>y(void 0,null,function*(){try{let i=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations/${t}?cluster=${h}`,{headers:D});if(i.ok){let o=yield i.json();F(o)}else T("Feature fetch operation error: ",i),l.emit("fetch flag error",i),l.emit("error",i)}catch(i){T("Feature fetch operation error: ",i),l.emit("fetch flag error",i),l.emit("error",i)}}),F=t=>{f();let i=W(t);i!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=i,S[t.flag]=U(I({},t),{value:i}),he(t)),V()};E=new P(_,u,l);let ve=()=>{let t=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):setTimeout(()=>X(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):X(r.identifier);break;case"delete":delete O[r.identifier],l.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),p("Evaluation deleted",{message:r,storage:O});break}},i=r=>!(!r||!r.flag||!r.identifier||!r.kind||!r.value),o=r=>!(!r||r.length==0||!r.every(m=>i(m))),d=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(m=>{F(m)}):_())},g=`${u.baseUrl}/stream?cluster=${h}`;v=new H(l,u,g,n,D,E,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&d(r)}),v.start()},me=()=>{E.start()},K=(t,i)=>l.on(t,i),pe=(t,i)=>{t?l.off(t,i):Z()},Ee=(t,i)=>{var r;if(!A||J||i===void 0)return;let o=i,d=t,g=R.find(m=>m.featureIdentifier===d&&m.featureValue===o);g?(G(g),g.variationIdentifier=((r=S[d])==null?void 0:r.identifier)||""):R.push({featureIdentifier:d,featureValue:o,count:1,variationIdentifier:S[d].identifier||"",lastAccessed:Date.now()})},Z=()=>{s=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),l.all.clear()),u.pollingEnabled&&E.isPolling()&&(p("Closing Poller"),E.stop()),O=Q(),S={},clearTimeout(w)},ee=(t,i=!0)=>{t.length&&j(()=>{let o=!!Object.keys(S).length;if(t.forEach(F),!o){f();let d=I({},O);V(),l.emit("ready",d)}},i)};return u.cache&&"localStorage"in window&&re(e.identifier+n).then(t=>{let i=!0,o=M(t,typeof u.cache=="boolean"?{}:u.cache);o!=null&&o.length&&j(()=>{p("loading from cache",o),ee(o,!1),l.emit("cache loaded",o)}),K("flags loaded",d=>{L(t,d),i=!1}),K("changed",d=>{i||(d.deleted?se(t,d.flag):oe(t,d))})}),{on:K,off:pe,close:Z,setEvaluations:ee,registerAPIRequestMiddleware:t=>{N=q(t)},refreshEvaluations:()=>{z&&!s&&Date.now()-Y>=6e4&&(_(),Y=Date.now())},variation:(t,i,o=!1)=>le(t,i,O,Ee,o)}};export{k as Event,ut as initialize};
var be=Object.defineProperty,Re=Object.defineProperties;var Se=Object.getOwnPropertyDescriptors;var ie=Object.getOwnPropertySymbols;var Ie=Object.prototype.hasOwnProperty,Te=Object.prototype.propertyIsEnumerable;var ne=(n,e,a)=>e in n?be(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,I=(n,e)=>{for(var a in e||(e={}))Ie.call(e,a)&&ne(n,a,e[a]);if(ie)for(var a of ie(e))Te.call(e,a)&&ne(n,a,e[a]);return n},U=(n,e)=>Re(n,Se(e));var T=(n,e,a)=>new Promise((s,c)=>{var h=b=>{try{E(a.next(b))}catch(F){c(F)}},v=b=>{try{E(a.throw(b))}catch(F){c(F)}},E=b=>b.done?s(b.value):Promise.resolve(b.value).then(h,v);E((a=a.apply(n,e)).next())});import Ce from"jwt-decode";import Oe 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 ye={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 e=I(I({},ye),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()},x=(n,e)=>Math.round(Math.random()*(e-n)+n);function re(n){return T(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(v=>v.toString(16).padStart(2,"0")).join("")})}function M(n,e={}){let a=parseInt(window.localStorage.getItem(n+".ts"));if(e!=null&&e.ttl&&!isNaN(a)&&a+e.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,e){window.localStorage.setItem(n,JSON.stringify(e)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(n,e){let a=M(n),s=a.find(({flag:c})=>c===e.flag);s?Object.assign(s,e):a.push(e),L(n,a)}function se(n,e){let a=M(n),s=a.findIndex(({flag:c})=>c===e);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 Fe=3e4,H=class{constructor(e,a,s,c,h,v,E){this.eventBus=e;this.configurations=a;this.url=s;this.apiKey=c;this.standardHeaders=h;this.fallbackPoller=v;this.eventCallback=E;this.abortController=new AbortController;this.disconnectEventEmitted=!1}start(){let e=I({Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),fetch(this.url,{headers:e,signal:this.abortController.signal,cache:"no-cache"}).then(a=>T(this,null,function*(){this.logDebug("FETCH 1"),this.stopFallbackPolling();let s=new TextDecoder,c=a.body.getReader(),h;do if(h=yield c.read(),this.logDebug("FETCH 2"),!h.done){this.logDebug("FETCH 3"),this.recordAccess();let v=s.decode(h.value);this.logDebug(`SSE GOT: ${v}`),v.split(/\r?\n/).forEach(E=>{if(this.logDebug("FETCH 4"),E.startsWith("data:")){let b=JSON.parse(E.substring(5));this.logDebug("Received event from stream: ",b),this.eventCallback(b)}})}while(!h.done)})).catch(a=>{this.logDebug("FETCH 5"),(!this.abortController.signal.aborted||this.abortController.signal.reason!=="closed")&&this.onFailed(this.abortController.signal.reason||a)})}close(){this.timeout&&clearTimeout(this.timeout),this.abortController.abort("closed"),this.eventBus.emit("stopped"),this.stopFallbackPolling()}recordAccess(){this.timeout&&clearTimeout(this.timeout),this.timeout=setTimeout(()=>this.streamTimeout(),Fe)}streamTimeout(){this.abortController.abort("SSE read timeout"),this.fallbackToPolling()}onFailed(e){e&&y("Stream has issue",e),this.fallbackToPolling(),this.eventBus.emit("stream error",e),this.eventBus.emit("error",e),this.onDisconnect()}onDisconnect(){this.timeout&&clearTimeout(this.timeout);let e=x(1e3,1e4);this.logDebug(`Stream disconnected, will reconnect in ${e}ms`),this.disconnectEventEmitted||(this.eventBus.emit("disconnected"),this.disconnectEventEmitted=!0),setTimeout(()=>{this.abortController=new AbortController,this.start()},e)}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 le(n,e,a,s,c){let h=n in a,v=h?a[n]:e;return h&&s(n,v),c?{value:v,isDefaultValue:!h}:v}var P=class{constructor(e,a,s){this.fetchFlagsFn=e;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 T(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 s=x(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,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var fe="1.23.0",de=`Javascript ${fe} Client`,we=500,Ae=globalThis.fetch,J=!!globalThis.Proxy,W=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},ut=(n,e,a)=>{let s=!1,c,h,v,E,b,F,C=!0,O={},N=q(t=>t),Y=0,z=!1,f=()=>{C=!1},V=()=>{C=!0},R=[],l=Oe(),u=ae(a);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let p=(t,...i)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...i)},G=t=>{if(C){let i=Date.now();i-t.lastAccessed>we&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{R.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(R),V())};let ge=(t,i)=>T(void 0,null,function*(){return(yield(yield Ae(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":de},body:JSON.stringify({apiKey:t,target:U(I({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,B=()=>{if(R.length){p("Sending metrics...",{metrics:R,evaluations:S});let t={metricsData:R.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:fe}]}))};N(`${u.eventUrl}/metrics/${c}?cluster=${h}`,{method:"POST",headers:I({"Content-Type":"application/json"},O),body:JSON.stringify(t)}).then(()=>{R=[],$=0}).catch(i=>{$++&&(R=[],$=0),p(i),l.emit("metrics error",i)}).finally(()=>{F=window.setTimeout(B,u.eventsSyncInterval)})}else F=window.setTimeout(B,u.eventsSyncInterval)},S={},he=t=>{p("Sending event for",t.flag),J?l.emit("changed",new Proxy(t,{get(i,o){var d;if(C&&i.hasOwnProperty(o)&&o==="value"){let g=i.flag,r=t.value,m=R.find(A=>A.featureIdentifier===g&&A.featureValue===r);m?(G(m),m.variationIdentifier=((d=S[g])==null?void 0:d.identifier)||""):R.push({featureIdentifier:g,featureValue:String(r),variationIdentifier:S[g].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?W(t):t[o]}})):l.emit("changed",{deleted:t.deleted,flag:t.flag,value:W(t)})},Q=function(){return J?new Proxy({},{get(t,i){var d,g,r;let o=t[i];if(C&&t.hasOwnProperty(i)){let m=t[i],A=R.find(te=>te.featureIdentifier===i&&m===te.featureValue);A?(A.variationIdentifier=((d=S[i])==null?void 0:d.identifier)||"",G(A)):R.push({featureIdentifier:i,featureValue:m,variationIdentifier:((g=S[i])==null?void 0:g.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",m,"variationIdentifier:",(r=S[i])==null?void 0:r.identifier)}return o}}):{}},D=Q();ge(n,u).then(t=>T(void 0,null,function*(){if(s)return;b=t;let i=Ce(t);if(O={Authorization:`Bearer ${b}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":de},globalThis.btoa){let g=globalThis.btoa(JSON.stringify(e));g.length<262144&&(O["Harness-Target"]=g)}if(p("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,p("Picking up metrics from previous session")}catch(g){}F=window.setTimeout(B,u.eventsSyncInterval),c=i.environment,h=i.clusterIdentifier;let o=!!Object.keys(S).length;if((yield _()).type==="success"&&p("Fetch all flags ok",D),!s){if(u.streamEnabled?(p("Streaming mode enabled"),ve()):u.pollingEnabled?(p("Polling mode enabled"),me()):p("Streaming and polling mode disabled"),!o){f();let g=I({},D);V(),l.emit("ready",g)}z=!0}})).catch(t=>{y("Authentication error: ",t),l.emit("auth error",t),l.emit("error",t)});let _=()=>T(void 0,null,function*(){try{let t=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations?cluster=${h}`,{headers:O});if(t.ok){let i=yield t.json();return i.forEach(w),l.emit("flags loaded",i),{type:"success",data:i}}else return y("Features fetch operation error: ",t),l.emit("fetch flags error",t),l.emit("error",t),{type:"error",error:t}}catch(t){return y("Features fetch operation error: ",t),l.emit("fetch flags error",t),l.emit("error",t),{type:"error",error:t}}}),X=t=>T(void 0,null,function*(){try{let i=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations/${t}?cluster=${h}`,{headers:O});if(i.ok){let o=yield i.json();w(o)}else y("Feature fetch operation error: ",i),l.emit("fetch flag error",i),l.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),l.emit("fetch flag error",i),l.emit("error",i)}}),w=t=>{f();let i=W(t);i!==D[t.flag]&&(p("Flag variation has changed for ",t.identifier),D[t.flag]=i,S[t.flag]=U(I({},t),{value:i}),he(t)),V()};E=new P(_,u,l);let ve=()=>{let t=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):setTimeout(()=>X(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):X(r.identifier);break;case"delete":delete D[r.identifier],l.emit("changed",{flag:r.identifier,value:void 0,deleted:!0}),p("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(m=>i(m))),d=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(m=>{w(m)}):_())},g=`${u.baseUrl}/stream?cluster=${h}`;v=new H(l,u,g,n,O,E,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&d(r)}),v.start()},me=()=>{E.start()},K=(t,i)=>l.on(t,i),pe=(t,i)=>{t?l.off(t,i):Z()},Ee=(t,i)=>{var r;if(!C||J||i===void 0)return;let o=i,d=t,g=R.find(m=>m.featureIdentifier===d&&m.featureValue===o);g?(G(g),g.variationIdentifier=((r=S[d])==null?void 0:r.identifier)||""):R.push({featureIdentifier:d,featureValue:o,count:1,variationIdentifier:S[d].identifier||"",lastAccessed:Date.now()})},Z=()=>{s=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),l.all.clear()),u.pollingEnabled&&E.isPolling()&&(p("Closing Poller"),E.stop()),D=Q(),S={},clearTimeout(F)},ee=(t,i=!0)=>{t.length&&j(()=>{let o=!!Object.keys(S).length;if(t.forEach(w),!o){f();let d=I({},D);V(),l.emit("ready",d)}},i)};return u.cache&&"localStorage"in window&&re(e.identifier+n).then(t=>{let i=!0,o=M(t,typeof u.cache=="boolean"?{}:u.cache);o!=null&&o.length&&j(()=>{p("loading from cache",o),ee(o,!1),l.emit("cache loaded",o)}),K("flags loaded",d=>{L(t,d),i=!1}),K("changed",d=>{i||(d.deleted?se(t,d.flag):oe(t,d))})}),{on:K,off:pe,close:Z,setEvaluations:ee,registerAPIRequestMiddleware:t=>{N=q(t)},refreshEvaluations:()=>{z&&!s&&Date.now()-Y>=6e4&&(_(),Y=Date.now())},variation:(t,i,o=!1)=>le(t,i,D,Ee,o)}};export{k as Event,ut as initialize};
{
"name": "@harnessio/ff-javascript-client-sdk",
"version": "1.23.1-alpha.2",
"version": "1.23.1-alpha.3",
"author": "Harness",

@@ -5,0 +5,0 @@ "license": "Apache-2.0",

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc