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
6
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.17.1 to 1.18.0-rc.1

3

dist/poller.d.ts

@@ -6,6 +6,7 @@ import type { Options } from './types';

private eventBus;
private storage;
private timeoutId;
private isRunning;
private maxAttempts;
constructor(fetchFlagsFn: () => Promise<any>, configurations: Options, eventBus: any);
constructor(fetchFlagsFn: () => Promise<any>, configurations: Options, eventBus: any, storage: Record<string, any>);
start(): void;

@@ -12,0 +13,0 @@ private poll;

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

var Oe=Object.create;var x=Object.defineProperty,we=Object.defineProperties,Ce=Object.getOwnPropertyDescriptor,Ae=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols,xe=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty,Ne=Object.prototype.propertyIsEnumerable;var re=(n,e,a)=>e in n?x(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,T=(n,e)=>{for(var a in e||(e={}))oe.call(e,a)&&re(n,a,e[a]);if(ae)for(var a of ae(e))Ne.call(e,a)&&re(n,a,e[a]);return n},j=(n,e)=>we(n,Ae(e));var Pe=(n,e)=>{for(var a in e)x(n,a,{get:e[a],enumerable:!0})},se=(n,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Fe(e))!oe.call(n,o)&&o!==a&&x(n,o,{get:()=>e[o],enumerable:!(s=Ce(e,o))||s.enumerable});return n};var le=(n,e,a)=>(a=n!=null?Oe(xe(n)):{},se(e||!n||!n.__esModule?x(a,"default",{value:n,enumerable:!0}):a,n)),Ve=n=>se(x({},"__esModule",{value:!0}),n);var w=(n,e,a)=>new Promise((s,o)=>{var f=R=>{try{b(a.next(R))}catch(c){o(c)}},v=R=>{try{b(a.throw(R))}catch(c){o(c)}},b=R=>R.done?s(R.value):Promise.resolve(R.value).then(f,v);b((a=a.apply(n,e)).next())});var Ge={};Pe(Ge,{Event:()=>N,initialize:()=>He});module.exports=Ve(Ge);var me=le(require("jwt-decode")),Ee=le(require("mitt"));var N=(h=>(h.READY="ready",h.CONNECTED="connected",h.DISCONNECTED="disconnected",h.POLLING="polling",h.POLLING_STOPPED="polling stopped",h.FLAGS_LOADED="flags loaded",h.CACHE_LOADED="cache loaded",h.CHANGED="changed",h.ERROR="error",h.ERROR_METRICS="metrics error",h.ERROR_AUTH="auth error",h.ERROR_FETCH_FLAGS="fetch flags error",h.ERROR_FETCH_FLAG="fetch flag error",h.ERROR_STREAM="stream error",h))(N||{});var ke={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},ce=n=>{let e=T(T({},ke),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),W=(n,e=!0)=>{e?setTimeout(n,0):n()},L=(n,e)=>Math.round(Math.random()*(e-n)+n);function J(n){return"HARNESS_FF_CACHE_"+n}function H(n,e={}){let a=J(n),s=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(s)&&s+e.ttl<Date.now())return _e(n),[];let o=window.localStorage.getItem(a);if(o)try{return JSON.parse(o)}catch(f){}return[]}function G(n,e){let a=J(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function de(n,e){let a=H(n),s=a.find(({flag:o})=>o===e.flag);s?Object.assign(s,e):a.push(e),G(n,a)}function ue(n,e){let a=H(n),s=a.findIndex(({flag:o})=>o===e);s>-1&&(a.splice(s,1),G(n,a))}function _e(n){let e=J(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function Y(n){return function(...a){let[s,o]=n(a);return fetch(s,o)}}var fe=3e4,$=class{constructor(e,a,s,o,f,v,b){this.closed=!1;this.eventBus=e,this.configurations=a,this.url=s,this.apiKey=o,this.standardHeaders=f,this.eventCallback=b,this.fallbackPoller=v}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let D=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",D),this.eventCallback(D)}},s=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},o=()=>{clearInterval(this.readTimeoutCheckerId);let c=L(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),c)},f=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),o()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,D]of Object.entries(v))this.xhr.setRequestHeader(c,D);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{f("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||f(null)},this.xhr.ontimeout=()=>{f("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){f(`HTTP code ${this.xhr.status}`);return}s()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(b);b+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-fe&&(y("SSE read timeout"),this.xhr.abort())},fe),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function ge(n,e,a,s,o){let f=n in a,v=f?a[n]:e;return f&&s(n,v),o?{value:v,isDefaultValue:!f}: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 w(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(!a){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",a),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);let s=L(1e3,1e4);yield new Promise(o=>setTimeout(o,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 be="1.16.0",pe=`Javascript ${be} Client`,Me=500,Le=globalThis.fetch,X=!!globalThis.Proxy,z=n=>{let{value:e}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){y(a)}return e},He=(n,e,a)=>{let s=!1,o,f,v,b,R,c,D=!0,F={},V=Y(t=>t),Q=0,h=!1,k=()=>{D=!1},_=()=>{D=!0},S=[],d=(0,Ee.default)(),u=ce(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)},B=t=>{if(D){let i=Date.now();i-t.lastAccessed>Me&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(k(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),_())};let Re=(t,i)=>w(void 0,null,function*(){return(yield(yield Le(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":pe},body:JSON.stringify({apiKey:t,target:j(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,q=()=>{if(S.length){p("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:be}]}))};V(`${u.eventUrl}/metrics/${o}?cluster=${f}`,{method:"POST",headers:T({"Content-Type":"application/json"},F),body:JSON.stringify(t)}).then(()=>{S=[],K=0}).catch(i=>{K++&&(S=[],K=0),p(i),d.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(q,u.eventsSyncInterval)})}else c=window.setTimeout(q,u.eventsSyncInterval)},I={},Se=t=>{p("Sending event for",t.flag),X?d.emit("changed",new Proxy(t,{get(i,l){var m;if(D&&i.hasOwnProperty(l)&&l==="value"){let E=i.flag,r=t.value,g=S.find(A=>A.featureIdentifier===E&&A.featureValue===r);g?(B(g),g.variationIdentifier=((m=I[E])==null?void 0:m.identifier)||""):S.push({featureIdentifier:E,featureValue:String(r),variationIdentifier:I[E].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",l,"has been read with value via stream update",r)}return l==="value"?z(t):t[l]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:z(t)})},Z=function(){return X?new Proxy({},{get(t,i){var m,E,r;let l=t[i];if(D&&t.hasOwnProperty(i)){let g=t[i],A=S.find(ne=>ne.featureIdentifier===i&&g===ne.featureValue);A?(A.variationIdentifier=((m=I[i])==null?void 0:m.identifier)||"",B(A)):S.push({featureIdentifier:i,featureValue:g,variationIdentifier:((E=I[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",g,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return l}}):{}},O=Z();Re(n,u).then(t=>w(void 0,null,function*(){if(s)return;R=t;let i=(0,me.default)(t);if(F={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":pe},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(E){}c=window.setTimeout(q,u.eventsSyncInterval),o=i.environment,f=i.clusterIdentifier;let l=!!Object.keys(I).length;if((yield M())||p("Fetch all flags ok",O),!s){if(u.streamEnabled?(p("Streaming mode enabled"),Ie()):u.pollingEnabled?(p("Polling mode enabled"),ye()):p("Streaming and polling mode disabled"),!l){k();let E=T({},O);_(),d.emit("ready",E)}h=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let M=()=>w(void 0,null,function*(){try{let t=yield V(`${u.baseUrl}/client/env/${o}/target/${e.identifier}/evaluations?cluster=${f}`,{headers:F});if(t.ok){let i=yield t.json();i.forEach(C),d.emit("flags loaded",i)}else y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t)}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),t}}),ee=t=>w(void 0,null,function*(){try{let i=yield V(`${u.baseUrl}/client/env/${o}/target/${e.identifier}/evaluations/${t}?cluster=${f}`,{headers:F});if(i.ok){let l=yield i.json();C(l)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),C=t=>{k();let i=z(t);i!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=i,I[t.flag]=j(T({},t),{value:i}),Se(t)),_()};b=new P(M,u,d);let Ie=()=>{let t=r=>{switch(r.event){case"create":l(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):setTimeout(()=>ee(r.identifier),1e3);break;case"patch":l(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):ee(r.identifier);break;case"delete":delete O[r.identifier],d.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),l=r=>!(!r||r.length==0||!r.every(g=>i(g))),m=r=>{r.event==="patch"&&(l(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):M())},E=`${u.baseUrl}/stream?cluster=${f}`;v=new $(d,u,E,n,F,b,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&m(r)}),v.start()},ye=()=>{b.start()},U=(t,i)=>d.on(t,i),De=(t,i)=>{t?d.off(t,i):te()},Te=(t,i)=>{var r;if(!D||X||i===void 0)return;let l=i,m=t,E=S.find(g=>g.featureIdentifier===m&&g.featureValue===l);E?(B(E),E.variationIdentifier=((r=I[m])==null?void 0:r.identifier)||""):S.push({featureIdentifier:m,featureValue:l,count:1,variationIdentifier:I[m].identifier||"",lastAccessed:Date.now()})},te=()=>{s=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&b.isPolling()&&(p("Closing Poller"),b.stop()),O=Z(),I={},clearTimeout(c)},ie=(t,i=!0)=>{t.length&&W(()=>{let l=!!Object.keys(I).length;if(t.forEach(C),!l){k();let m=T({},O);_(),d.emit("ready",m)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=H(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&W(()=>{p("loading from cache",i),ie(i,!1),d.emit("cache loaded",i)}),U("flags loaded",l=>{G(e.identifier,l),t=!1}),U("changed",l=>{t||(l.deleted?ue(e.identifier,l.flag):de(e.identifier,l))})}return{on:U,off:De,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{V=Y(t)},refreshEvaluations:()=>{h&&!s&&Date.now()-Q>=6e4&&(M(),Q=Date.now())},variation:(t,i,l=!1)=>ge(t,i,O,Te,l)}};0&&(module.exports={Event,initialize});
var Oe=Object.create;var N=Object.defineProperty,Ce=Object.defineProperties,we=Object.getOwnPropertyDescriptor,Ae=Object.getOwnPropertyDescriptors,Fe=Object.getOwnPropertyNames,ae=Object.getOwnPropertySymbols,Ne=Object.getPrototypeOf,oe=Object.prototype.hasOwnProperty,xe=Object.prototype.propertyIsEnumerable;var re=(n,e,a)=>e in n?N(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,T=(n,e)=>{for(var a in e||(e={}))oe.call(e,a)&&re(n,a,e[a]);if(ae)for(var a of ae(e))xe.call(e,a)&&re(n,a,e[a]);return n},U=(n,e)=>Ce(n,Ae(e));var Pe=(n,e)=>{for(var a in e)N(n,a,{get:e[a],enumerable:!0})},se=(n,e,a,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let o of Fe(e))!oe.call(n,o)&&o!==a&&N(n,o,{get:()=>e[o],enumerable:!(s=we(e,o))||s.enumerable});return n};var le=(n,e,a)=>(a=n!=null?Oe(Ne(n)):{},se(e||!n||!n.__esModule?N(a,"default",{value:n,enumerable:!0}):a,n)),Ve=n=>se(N({},"__esModule",{value:!0}),n);var C=(n,e,a)=>new Promise((s,o)=>{var g=R=>{try{b(a.next(R))}catch(c){o(c)}},v=R=>{try{b(a.throw(R))}catch(c){o(c)}},b=R=>R.done?s(R.value):Promise.resolve(R.value).then(g,v);b((a=a.apply(n,e)).next())});var Ge={};Pe(Ge,{Event:()=>x,initialize:()=>He});module.exports=Ve(Ge);var me=le(require("jwt-decode")),Ee=le(require("mitt"));var x=(f=>(f.READY="ready",f.CONNECTED="connected",f.DISCONNECTED="disconnected",f.POLLING="polling",f.POLLING_STOPPED="polling stopped",f.POLLING_CHANGED="polling changed",f.FLAGS_LOADED="flags loaded",f.CACHE_LOADED="cache loaded",f.CHANGED="changed",f.ERROR="error",f.ERROR_METRICS="metrics error",f.ERROR_AUTH="auth error",f.ERROR_FETCH_FLAGS="fetch flags error",f.ERROR_FETCH_FLAG="fetch flag error",f.ERROR_STREAM="stream error",f))(x||{});var _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,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},ce=n=>{let e=T(T({},_e),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()},L=(n,e)=>Math.round(Math.random()*(e-n)+n);function W(n){return"HARNESS_FF_CACHE_"+n}function M(n,e={}){let a=W(n),s=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(s)&&s+e.ttl<Date.now())return ke(n),[];let o=window.localStorage.getItem(a);if(o)try{return JSON.parse(o)}catch(g){}return[]}function H(n,e){let a=W(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function de(n,e){let a=M(n),s=a.find(({flag:o})=>o===e.flag);s?Object.assign(s,e):a.push(e),H(n,a)}function ue(n,e){let a=M(n),s=a.findIndex(({flag:o})=>o===e);s>-1&&(a.splice(s,1),H(n,a))}function ke(n){let e=W(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function J(n){return function(...a){let[s,o]=n(a);return fetch(s,o)}}var fe=3e4,G=class{constructor(e,a,s,o,g,v,b){this.closed=!1;this.eventBus=e,this.configurations=a,this.url=s,this.apiKey=o,this.standardHeaders=g,this.eventCallback=b,this.fallbackPoller=v}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let D=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",D),this.eventCallback(D)}},s=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},o=()=>{clearInterval(this.readTimeoutCheckerId);let c=L(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),c)},g=c=>{c&&y("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),o()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,D]of Object.entries(v))this.xhr.setRequestHeader(c,D);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{g("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||g(null)},this.xhr.ontimeout=()=>{g("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){g(`HTTP code ${this.xhr.status}`);return}s()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(b);b+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-fe&&(y("SSE read timeout"),this.xhr.abort())},fe),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function ge(n,e,a,s,o){let g=n in a,v=g?a[n]:e;return g&&s(n,v),o?{value:v,isDefaultValue:!g}:v}var P=class{constructor(e,a,s,o){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=s;this.storage=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 C(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(!a){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `),this.eventBus.emit("polling changed",this.storage);return}if(y("Error when polling for flag updates",a),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);let s=L(1e3,1e4);yield new Promise(o=>setTimeout(o,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 be="1.16.0",pe=`Javascript ${be} Client`,Le=500,Me=globalThis.fetch,Y=!!globalThis.Proxy,X=n=>{let{value:e}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){y(a)}return e},He=(n,e,a)=>{let s=!1,o,g,v,b,R,c,D=!0,F={},V=J(t=>t),z=0,Q=!1,f=()=>{D=!1},_=()=>{D=!0},S=[],d=(0,Ee.default)(),u=ce(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)},B=t=>{if(D){let i=Date.now();i-t.lastAccessed>Le&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),_())};let Re=(t,i)=>C(void 0,null,function*(){return(yield(yield Me(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":pe},body:JSON.stringify({apiKey:t,target:U(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(S.length){p("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:be}]}))};V(`${u.eventUrl}/metrics/${o}?cluster=${g}`,{method:"POST",headers:T({"Content-Type":"application/json"},F),body:JSON.stringify(t)}).then(()=>{S=[],$=0}).catch(i=>{$++&&(S=[],$=0),p(i),d.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(K,u.eventsSyncInterval)})}else c=window.setTimeout(K,u.eventsSyncInterval)},I={},Se=t=>{p("Sending event for",t.flag),Y?d.emit("changed",new Proxy(t,{get(i,l){var m;if(D&&i.hasOwnProperty(l)&&l==="value"){let E=i.flag,r=t.value,h=S.find(A=>A.featureIdentifier===E&&A.featureValue===r);h?(B(h),h.variationIdentifier=((m=I[E])==null?void 0:m.identifier)||""):S.push({featureIdentifier:E,featureValue:String(r),variationIdentifier:I[E].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",l,"has been read with value via stream update",r)}return l==="value"?X(t):t[l]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:X(t)})},Z=function(){return Y?new Proxy({},{get(t,i){var m,E,r;let l=t[i];if(D&&t.hasOwnProperty(i)){let h=t[i],A=S.find(ne=>ne.featureIdentifier===i&&h===ne.featureValue);A?(A.variationIdentifier=((m=I[i])==null?void 0:m.identifier)||"",B(A)):S.push({featureIdentifier:i,featureValue:h,variationIdentifier:((E=I[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",h,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return l}}):{}},O=Z();Re(n,u).then(t=>C(void 0,null,function*(){if(s)return;R=t;let i=(0,me.default)(t);if(F={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":pe},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(E){}c=window.setTimeout(K,u.eventsSyncInterval),o=i.environment,g=i.clusterIdentifier;let l=!!Object.keys(I).length;if((yield k())||p("Fetch all flags ok",O),!s){if(u.streamEnabled?(p("Streaming mode enabled"),Ie()):u.pollingEnabled?(p("Polling mode enabled"),ye()):p("Streaming and polling mode disabled"),!l){f();let E=T({},O);_(),d.emit("ready",E)}Q=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let k=()=>C(void 0,null,function*(){try{let t=yield V(`${u.baseUrl}/client/env/${o}/target/${e.identifier}/evaluations?cluster=${g}`,{headers:F});if(t.ok){let i=yield t.json();i.forEach(w),d.emit("flags loaded",i)}else y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t)}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),t}}),ee=t=>C(void 0,null,function*(){try{let i=yield V(`${u.baseUrl}/client/env/${o}/target/${e.identifier}/evaluations/${t}?cluster=${g}`,{headers:F});if(i.ok){let l=yield i.json();w(l)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),w=t=>{f();let i=X(t);i!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=i,I[t.flag]=U(T({},t),{value:i}),Se(t)),_()};b=new P(k,u,d,O);let Ie=()=>{let t=r=>{switch(r.event){case"create":l(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):setTimeout(()=>ee(r.identifier),1e3);break;case"patch":l(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):ee(r.identifier);break;case"delete":delete O[r.identifier],d.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),l=r=>!(!r||r.length==0||!r.every(h=>i(h))),m=r=>{r.event==="patch"&&(l(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):k())},E=`${u.baseUrl}/stream?cluster=${g}`;v=new G(d,u,E,n,F,b,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&m(r)}),v.start()},ye=()=>{b.start()},q=(t,i)=>d.on(t,i),De=(t,i)=>{t?d.off(t,i):te()},Te=(t,i)=>{var r;if(!D||Y||i===void 0)return;let l=i,m=t,E=S.find(h=>h.featureIdentifier===m&&h.featureValue===l);E?(B(E),E.variationIdentifier=((r=I[m])==null?void 0:r.identifier)||""):S.push({featureIdentifier:m,featureValue:l,count:1,variationIdentifier:I[m].identifier||"",lastAccessed:Date.now()})},te=()=>{s=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&b.isPolling()&&(p("Closing Poller"),b.stop()),O=Z(),I={},clearTimeout(c)},ie=(t,i=!0)=>{t.length&&j(()=>{let l=!!Object.keys(I).length;if(t.forEach(w),!l){f();let m=T({},O);_(),d.emit("ready",m)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=M(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&j(()=>{p("loading from cache",i),ie(i,!1),d.emit("cache loaded",i)}),q("flags loaded",l=>{H(e.identifier,l),t=!1}),q("changed",l=>{t||(l.deleted?ue(e.identifier,l.flag):de(e.identifier,l))})}return{on:q,off:De,close:te,setEvaluations:ie,registerAPIRequestMiddleware:t=>{V=J(t)},refreshEvaluations:()=>{Q&&!s&&Date.now()-z>=6e4&&(k(),z=Date.now())},variation:(t,i,l=!1)=>ge(t,i,O,Te,l)}};0&&(module.exports={Event,initialize});

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

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

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

var Te=Object.defineProperty,Ce=Object.defineProperties;var De=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var Oe=Object.prototype.hasOwnProperty,Ae=Object.prototype.propertyIsEnumerable;var oe=(n,e,a)=>e in n?Te(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,T=(n,e)=>{for(var a in e||(e={}))Oe.call(e,a)&&oe(n,a,e[a]);if(re)for(var a of re(e))Ae.call(e,a)&&oe(n,a,e[a]);return n},j=(n,e)=>Ce(n,De(e));var D=(n,e,a)=>new Promise((r,s)=>{var d=R=>{try{b(a.next(R))}catch(c){s(c)}},g=R=>{try{b(a.throw(R))}catch(c){s(c)}},b=R=>R.done?r(R.value):Promise.resolve(R.value).then(d,g);b((a=a.apply(n,e)).next())});function J(n){this.message=n}J.prototype=new Error,J.prototype.name="InvalidCharacterError";var se=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(n){var e=String(n).replace(/=+$/,"");if(e.length%4==1)throw new J("'atob' failed: The string to be decoded is not correctly encoded.");for(var a,r,s=0,d=0,g="";r=e.charAt(d++);~r&&(a=s%4?64*a+r:r,s++%4)?g+=String.fromCharCode(255&a>>(-2*s&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return g};function xe(n){var e=n.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(a){return decodeURIComponent(se(a).replace(/(.)/g,function(r,s){var d=s.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(a){return se(e)}}function _(n){this.message=n}function Fe(n,e){if(typeof n!="string")throw new _("Invalid token specified");var a=(e=e||{}).header===!0?0:1;try{return JSON.parse(xe(n.split(".")[a]))}catch(r){throw new _("Invalid token specified: "+r.message)}}_.prototype=new Error,_.prototype.name="InvalidTokenError";var le=Fe;function ce(n){return{all:n=n||new Map,on:function(e,a){var r=n.get(e);r&&r.push(a)||n.set(e,[a])},off:function(e,a){var r=n.get(e);r&&r.splice(r.indexOf(a)>>>0,1)},emit:function(e,a){(n.get(e)||[]).slice().map(function(r){r(a)}),(n.get("*")||[]).slice().map(function(r){r(e,a)})}}}var M=(p=>(p.READY="ready",p.CONNECTED="connected",p.DISCONNECTED="disconnected",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))(M||{});var ke={debug:!1,baseUrl:"https://config.ff.harness.io/api/1.0",eventUrl:"https://events.ff.harness.io/api/1.0",eventsSyncInterval:6e4,pollingInterval:6e4,streamEnabled:!0,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},de=n=>{let e=T(T({},ke),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},w=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),W=(n,e=!0)=>{e?setTimeout(n,0):n()},L=(n,e)=>Math.round(Math.random()*(e-n)+n);function Y(n){return"HARNESS_FF_CACHE_"+n}function H(n,e={}){let a=Y(n),r=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(r)&&r+e.ttl<Date.now())return Ne(n),[];let s=window.localStorage.getItem(a);if(s)try{return JSON.parse(s)}catch(d){}return[]}function G(n,e){let a=Y(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function ue(n,e){let a=H(n),r=a.find(({flag:s})=>s===e.flag);r?Object.assign(r,e):a.push(e),G(n,a)}function fe(n,e){let a=H(n),r=a.findIndex(({flag:s})=>s===e);r>-1&&(a.splice(r,1),G(n,a))}function Ne(n){let e=Y(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function X(n){return function(...a){let[r,s]=n(a);return fetch(r,s)}}var ge=3e4,$=class{constructor(e,a,r,s,d,g,b){this.closed=!1;this.eventBus=e,this.configurations=a,this.url=r,this.apiKey=s,this.standardHeaders=d,this.eventCallback=b,this.fallbackPoller=g}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let y=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",y),this.eventCallback(y)}},r=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=L(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),c)},d=c=>{c&&w("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},g=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,y]of Object.entries(g))this.xhr.setRequestHeader(c,y);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}r()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(b);b+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-ge&&(w("SSE read timeout"),this.xhr.abort())},ge),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function he(n,e,a,r,s){let d=n in a,g=d?a[n]:e;return d&&r(n,g),s?{value:g,isDefaultValue:!d}:g}var F=class{constructor(e,a,r){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=r;this.maxAttempts=5}start(){if(this.isPolling()){this.logDebug("Already polling.");return}this.isRunning=!0,this.eventBus.emit("polling"),this.logDebug(`Starting poller, first poll will be in ${this.configurations.pollingInterval}ms`),this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)}poll(){this.attemptFetch().finally(()=>{this.timeoutId=setTimeout(()=>this.poll(),this.configurations.pollingInterval)})}attemptFetch(){return D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(!a){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(w("Error when polling for flag updates",a),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);let r=L(1e3,1e4);yield new Promise(s=>setTimeout(s,r))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var Ee="1.16.0",me=`Javascript ${Ee} Client`,Pe=500,Ve=globalThis.fetch,z=!!globalThis.Proxy,Q=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){w(a)}return e},ht=(n,e,a)=>{let r=!1,s,d,g,b,R,c,y=!0,x={},k=X(t=>t),Z=0,p=!1,N=()=>{y=!1},P=()=>{y=!0},I=[],u=ce(),f=de(a);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let v=(t,...i)=>{f.debug&&console.debug(`[FF-SDK] ${t}`,...i)},B=t=>{if(y){let i=Date.now();i-t.lastAccessed>Pe&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{I.length&&globalThis.localStorage&&(N(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(I),P())};let be=(t,i)=>D(void 0,null,function*(){return(yield(yield Ve(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":me},body:JSON.stringify({apiKey:t,target:j(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),K=0,U=()=>{if(I.length){v("Sending metrics...",{metrics:I,evaluations:S});let t={metricsData:I.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Ee}]}))};k(`${f.eventUrl}/metrics/${s}?cluster=${d}`,{method:"POST",headers:T({"Content-Type":"application/json"},x),body:JSON.stringify(t)}).then(()=>{I=[],K=0}).catch(i=>{K++&&(I=[],K=0),v(i),u.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(U,f.eventsSyncInterval)})}else c=window.setTimeout(U,f.eventsSyncInterval)},S={},Re=t=>{v("Sending event for",t.flag),z?u.emit("changed",new Proxy(t,{get(i,l){var m;if(y&&i.hasOwnProperty(l)&&l==="value"){let E=i.flag,o=t.value,h=I.find(A=>A.featureIdentifier===E&&A.featureValue===o);h?(B(h),h.variationIdentifier=((m=S[E])==null?void 0:m.identifier)||""):I.push({featureIdentifier:E,featureValue:String(o),variationIdentifier:S[E].identifier||"",count:1,lastAccessed:Date.now()}),v("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?Q(t):t[l]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:Q(t)})},ee=function(){return z?new Proxy({},{get(t,i){var m,E,o;let l=t[i];if(y&&t.hasOwnProperty(i)){let h=t[i],A=I.find(ae=>ae.featureIdentifier===i&&h===ae.featureValue);A?(A.variationIdentifier=((m=S[i])==null?void 0:m.identifier)||"",B(A)):I.push({featureIdentifier:i,featureValue:h,variationIdentifier:((E=S[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),v("Metrics event: Flag:",i,"has been read with value:",h,"variationIdentifier:",(o=S[i])==null?void 0:o.identifier)}return l}}):{}},C=ee();be(n,f).then(t=>D(void 0,null,function*(){if(r)return;R=t;let i=le(t);if(x={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":me},v("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,v("Picking up metrics from previous session")}catch(E){}c=window.setTimeout(U,f.eventsSyncInterval),s=i.environment,d=i.clusterIdentifier;let l=!!Object.keys(S).length;if((yield V())||v("Fetch all flags ok",C),!r){if(f.streamEnabled?(v("Streaming mode enabled"),Ie()):f.pollingEnabled?(v("Polling mode enabled"),Se()):v("Streaming and polling mode disabled"),!l){N();let E=T({},C);P(),u.emit("ready",E)}p=!0}})).catch(t=>{w("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let V=()=>D(void 0,null,function*(){try{let t=yield k(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:x});if(t.ok){let i=yield t.json();i.forEach(O),u.emit("flags loaded",i)}else w("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t)}catch(t){return w("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),t}}),te=t=>D(void 0,null,function*(){try{let i=yield k(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${t}?cluster=${d}`,{headers:x});if(i.ok){let l=yield i.json();O(l)}else w("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}catch(i){w("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}}),O=t=>{N();let i=Q(t);i!==C[t.flag]&&(v("Flag variation has changed for ",t.identifier),C[t.flag]=i,S[t.flag]=j(T({},t),{value:i}),Re(t)),P()};b=new F(V,f,u);let Ie=()=>{let t=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(h=>{O(h)}):setTimeout(()=>te(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(h=>{O(h)}):te(o.identifier);break;case"delete":delete C[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),v("Evaluation deleted",{message:o,storage:C});break}},i=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),l=o=>!(!o||o.length==0||!o.every(h=>i(h))),m=o=>{o.event==="patch"&&(l(o.evaluations)?o.evaluations.forEach(h=>{O(h)}):V())},E=`${f.baseUrl}/stream?cluster=${d}`;g=new $(u,f,E,n,x,b,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&m(o)}),g.start()},Se=()=>{b.start()},q=(t,i)=>u.on(t,i),we=(t,i)=>{t?u.off(t,i):ie()},ye=(t,i)=>{var o;if(!y||z||i===void 0)return;let l=i,m=t,E=I.find(h=>h.featureIdentifier===m&&h.featureValue===l);E?(B(E),E.variationIdentifier=((o=S[m])==null?void 0:o.identifier)||""):I.push({featureIdentifier:m,featureValue:l,count:1,variationIdentifier:S[m].identifier||"",lastAccessed:Date.now()})},ie=()=>{r=!0,f.streamEnabled&&(v("Closing event stream"),typeof(g==null?void 0:g.close)=="function"&&g.close(),u.all.clear()),f.pollingEnabled&&b.isPolling()&&(v("Closing Poller"),b.stop()),C=ee(),S={},clearTimeout(c)},ne=(t,i=!0)=>{t.length&&W(()=>{let l=!!Object.keys(S).length;if(t.forEach(O),!l){N();let m=T({},C);P(),u.emit("ready",m)}},i)};if(f.cache&&"localStorage"in window){let t=!0,i=H(e.identifier,typeof f.cache=="boolean"?{}:f.cache);i!=null&&i.length&&W(()=>{v("loading from cache",i),ne(i,!1),u.emit("cache loaded",i)}),q("flags loaded",l=>{G(e.identifier,l),t=!1}),q("changed",l=>{t||(l.deleted?fe(e.identifier,l.flag):ue(e.identifier,l))})}return{on:q,off:we,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:t=>{k=X(t)},refreshEvaluations:()=>{p&&!r&&Date.now()-Z>=6e4&&(V(),Z=Date.now())},variation:(t,i,l=!1)=>he(t,i,C,ye,l)}};export{M as Event,ht as initialize};
var Te=Object.defineProperty,Ce=Object.defineProperties;var De=Object.getOwnPropertyDescriptors;var re=Object.getOwnPropertySymbols;var Oe=Object.prototype.hasOwnProperty,Ae=Object.prototype.propertyIsEnumerable;var oe=(n,e,a)=>e in n?Te(n,e,{enumerable:!0,configurable:!0,writable:!0,value:a}):n[e]=a,T=(n,e)=>{for(var a in e||(e={}))Oe.call(e,a)&&oe(n,a,e[a]);if(re)for(var a of re(e))Ae.call(e,a)&&oe(n,a,e[a]);return n},q=(n,e)=>Ce(n,De(e));var D=(n,e,a)=>new Promise((r,s)=>{var d=R=>{try{b(a.next(R))}catch(c){s(c)}},h=R=>{try{b(a.throw(R))}catch(c){s(c)}},b=R=>R.done?r(R.value):Promise.resolve(R.value).then(d,h);b((a=a.apply(n,e)).next())});function j(n){this.message=n}j.prototype=new Error,j.prototype.name="InvalidCharacterError";var se=typeof window!="undefined"&&window.atob&&window.atob.bind(window)||function(n){var e=String(n).replace(/=+$/,"");if(e.length%4==1)throw new j("'atob' failed: The string to be decoded is not correctly encoded.");for(var a,r,s=0,d=0,h="";r=e.charAt(d++);~r&&(a=s%4?64*a+r:r,s++%4)?h+=String.fromCharCode(255&a>>(-2*s&6)):0)r="ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=".indexOf(r);return h};function xe(n){var e=n.replace(/-/g,"+").replace(/_/g,"/");switch(e.length%4){case 0:break;case 2:e+="==";break;case 3:e+="=";break;default:throw"Illegal base64url string!"}try{return function(a){return decodeURIComponent(se(a).replace(/(.)/g,function(r,s){var d=s.charCodeAt(0).toString(16).toUpperCase();return d.length<2&&(d="0"+d),"%"+d}))}(e)}catch(a){return se(e)}}function V(n){this.message=n}function Fe(n,e){if(typeof n!="string")throw new V("Invalid token specified");var a=(e=e||{}).header===!0?0:1;try{return JSON.parse(xe(n.split(".")[a]))}catch(r){throw new V("Invalid token specified: "+r.message)}}V.prototype=new Error,V.prototype.name="InvalidTokenError";var le=Fe;function ce(n){return{all:n=n||new Map,on:function(e,a){var r=n.get(e);r&&r.push(a)||n.set(e,[a])},off:function(e,a){var r=n.get(e);r&&r.splice(r.indexOf(a)>>>0,1)},emit:function(e,a){(n.get(e)||[]).slice().map(function(r){r(a)}),(n.get("*")||[]).slice().map(function(r){r(e,a)})}}}var _=(g=>(g.READY="ready",g.CONNECTED="connected",g.DISCONNECTED="disconnected",g.POLLING="polling",g.POLLING_STOPPED="polling stopped",g.POLLING_CHANGED="polling changed",g.FLAGS_LOADED="flags loaded",g.CACHE_LOADED="cache loaded",g.CHANGED="changed",g.ERROR="error",g.ERROR_METRICS="metrics error",g.ERROR_AUTH="auth error",g.ERROR_FETCH_FLAGS="fetch flags error",g.ERROR_FETCH_FLAG="fetch flag error",g.ERROR_STREAM="stream error",g))(_||{});var Ne={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,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},de=n=>{let e=T(T({},Ne),n);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},w=(n,...e)=>console.error(`[FF-SDK] ${n}`,...e),J=(n,e=!0)=>{e?setTimeout(n,0):n()},M=(n,e)=>Math.round(Math.random()*(e-n)+n);function W(n){return"HARNESS_FF_CACHE_"+n}function L(n,e={}){let a=W(n),r=parseInt(window.localStorage.getItem(a+".ts"));if(e!=null&&e.ttl&&!isNaN(r)&&r+e.ttl<Date.now())return ke(n),[];let s=window.localStorage.getItem(a);if(s)try{return JSON.parse(s)}catch(d){}return[]}function H(n,e){let a=W(n);window.localStorage.setItem(a,JSON.stringify(e)),window.localStorage.setItem(a+".ts",Date.now().toString())}function ue(n,e){let a=L(n),r=a.find(({flag:s})=>s===e.flag);r?Object.assign(r,e):a.push(e),H(n,a)}function fe(n,e){let a=L(n),r=a.findIndex(({flag:s})=>s===e);r>-1&&(a.splice(r,1),H(n,a))}function ke(n){let e=W(n);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function Y(n){return function(...a){let[r,s]=n(a);return fetch(r,s)}}var ge=3e4,G=class{constructor(e,a,r,s,d,h,b){this.closed=!1;this.eventBus=e,this.configurations=a,this.url=r,this.apiKey=s,this.standardHeaders=d,this.eventCallback=b,this.fallbackPoller=h}start(){let e=c=>{c.toString().split(/\r?\n/).forEach(a)},a=c=>{if(c.startsWith("data:")){let y=JSON.parse(c.substring(5));this.logDebug("Received event from stream: ",y),this.eventCallback(y)}},r=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},s=()=>{clearInterval(this.readTimeoutCheckerId);let c=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+c+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),c)},d=c=>{c&&w("Stream has issue",c),this.fallBackToPolling(),this.eventBus.emit("stream error",c),this.eventBus.emit("error",c),s()},h=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[c,y]of Object.entries(h))this.xhr.setRequestHeader(c,y);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{d("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||d(null)},this.xhr.ontimeout=()=>{d("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){d(`HTTP code ${this.xhr.status}`);return}r()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let c=this.xhr.responseText.slice(b);b+=c.length,this.logDebug("SSE GOT: "+c),e(c)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-ge&&(w("SSE read timeout"),this.xhr.abort())},ge),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...a)}};function he(n,e,a,r,s){let d=n in a,h=d?a[n]:e;return d&&r(n,h),s?{value:h,isDefaultValue:!d}:h}var F=class{constructor(e,a,r,s){this.fetchFlagsFn=e;this.configurations=a;this.eventBus=r;this.storage=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 D(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let a=yield this.fetchFlagsFn();if(!a){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `),this.eventBus.emit("polling changed",this.storage);return}if(w("Error when polling for flag updates",a),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);let r=M(1e3,1e4);yield new Promise(s=>setTimeout(s,r))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...a){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...a)}};var Ee="1.16.0",me=`Javascript ${Ee} Client`,Pe=500,Ve=globalThis.fetch,X=!!globalThis.Proxy,z=n=>{let{value:e}=n;try{switch(n.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(a){w(a)}return e},ht=(n,e,a)=>{let r=!1,s,d,h,b,R,c,y=!0,x={},N=Y(t=>t),Q=0,Z=!1,g=()=>{y=!1},k=()=>{y=!0},I=[],u=ce(),f=de(a);f.eventsSyncInterval<6e4&&(f.eventsSyncInterval=6e4),f.pollingInterval<6e4&&(f.pollingInterval=6e4);let v=(t,...i)=>{f.debug&&console.debug(`[FF-SDK] ${t}`,...i)},B=t=>{if(y){let i=Date.now();i-t.lastAccessed>Pe&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{I.length&&globalThis.localStorage&&(g(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(I),k())};let be=(t,i)=>D(void 0,null,function*(){return(yield(yield Ve(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":me},body:JSON.stringify({apiKey:t,target:q(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),$=0,K=()=>{if(I.length){v("Sending metrics...",{metrics:I,evaluations:S});let t={metricsData:I.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:Ee}]}))};N(`${f.eventUrl}/metrics/${s}?cluster=${d}`,{method:"POST",headers:T({"Content-Type":"application/json"},x),body:JSON.stringify(t)}).then(()=>{I=[],$=0}).catch(i=>{$++&&(I=[],$=0),v(i),u.emit("metrics error",i)}).finally(()=>{c=window.setTimeout(K,f.eventsSyncInterval)})}else c=window.setTimeout(K,f.eventsSyncInterval)},S={},Re=t=>{v("Sending event for",t.flag),X?u.emit("changed",new Proxy(t,{get(i,l){var m;if(y&&i.hasOwnProperty(l)&&l==="value"){let E=i.flag,o=t.value,p=I.find(A=>A.featureIdentifier===E&&A.featureValue===o);p?(B(p),p.variationIdentifier=((m=S[E])==null?void 0:m.identifier)||""):I.push({featureIdentifier:E,featureValue:String(o),variationIdentifier:S[E].identifier||"",count:1,lastAccessed:Date.now()}),v("Metrics event: Flag",l,"has been read with value via stream update",o)}return l==="value"?z(t):t[l]}})):u.emit("changed",{deleted:t.deleted,flag:t.flag,value:z(t)})},ee=function(){return X?new Proxy({},{get(t,i){var m,E,o;let l=t[i];if(y&&t.hasOwnProperty(i)){let p=t[i],A=I.find(ae=>ae.featureIdentifier===i&&p===ae.featureValue);A?(A.variationIdentifier=((m=S[i])==null?void 0:m.identifier)||"",B(A)):I.push({featureIdentifier:i,featureValue:p,variationIdentifier:((E=S[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),v("Metrics event: Flag:",i,"has been read with value:",p,"variationIdentifier:",(o=S[i])==null?void 0:o.identifier)}return l}}):{}},C=ee();be(n,f).then(t=>D(void 0,null,function*(){if(r)return;R=t;let i=le(t);if(x={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":me},v("Authenticated",i),globalThis.localStorage&&globalThis.localStorage.HARNESS_FF_METRICS)try{delete globalThis.localStorage.HARNESS_FF_METRICS,v("Picking up metrics from previous session")}catch(E){}c=window.setTimeout(K,f.eventsSyncInterval),s=i.environment,d=i.clusterIdentifier;let l=!!Object.keys(S).length;if((yield P())||v("Fetch all flags ok",C),!r){if(f.streamEnabled?(v("Streaming mode enabled"),Ie()):f.pollingEnabled?(v("Polling mode enabled"),Se()):v("Streaming and polling mode disabled"),!l){g();let E=T({},C);k(),u.emit("ready",E)}Z=!0}})).catch(t=>{w("Authentication error: ",t),u.emit("auth error",t),u.emit("error",t)});let P=()=>D(void 0,null,function*(){try{let t=yield N(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations?cluster=${d}`,{headers:x});if(t.ok){let i=yield t.json();i.forEach(O),u.emit("flags loaded",i)}else w("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t)}catch(t){return w("Features fetch operation error: ",t),u.emit("fetch flags error",t),u.emit("error",t),t}}),te=t=>D(void 0,null,function*(){try{let i=yield N(`${f.baseUrl}/client/env/${s}/target/${e.identifier}/evaluations/${t}?cluster=${d}`,{headers:x});if(i.ok){let l=yield i.json();O(l)}else w("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}catch(i){w("Feature fetch operation error: ",i),u.emit("fetch flag error",i),u.emit("error",i)}}),O=t=>{g();let i=z(t);i!==C[t.flag]&&(v("Flag variation has changed for ",t.identifier),C[t.flag]=i,S[t.flag]=q(T({},t),{value:i}),Re(t)),k()};b=new F(P,f,u,C);let Ie=()=>{let t=o=>{switch(o.event){case"create":l(o.evaluations)?o.evaluations.forEach(p=>{O(p)}):setTimeout(()=>te(o.identifier),1e3);break;case"patch":l(o.evaluations)?o.evaluations.forEach(p=>{O(p)}):te(o.identifier);break;case"delete":delete C[o.identifier],u.emit("changed",{flag:o.identifier,value:void 0,deleted:!0}),v("Evaluation deleted",{message:o,storage:C});break}},i=o=>!(!o||!o.flag||!o.identifier||!o.kind||!o.value),l=o=>!(!o||o.length==0||!o.every(p=>i(p))),m=o=>{o.event==="patch"&&(l(o.evaluations)?o.evaluations.forEach(p=>{O(p)}):P())},E=`${f.baseUrl}/stream?cluster=${d}`;h=new G(u,f,E,n,x,b,o=>{o.domain==="flag"?t(o):o.domain==="target-segment"&&m(o)}),h.start()},Se=()=>{b.start()},U=(t,i)=>u.on(t,i),we=(t,i)=>{t?u.off(t,i):ie()},ye=(t,i)=>{var o;if(!y||X||i===void 0)return;let l=i,m=t,E=I.find(p=>p.featureIdentifier===m&&p.featureValue===l);E?(B(E),E.variationIdentifier=((o=S[m])==null?void 0:o.identifier)||""):I.push({featureIdentifier:m,featureValue:l,count:1,variationIdentifier:S[m].identifier||"",lastAccessed:Date.now()})},ie=()=>{r=!0,f.streamEnabled&&(v("Closing event stream"),typeof(h==null?void 0:h.close)=="function"&&h.close(),u.all.clear()),f.pollingEnabled&&b.isPolling()&&(v("Closing Poller"),b.stop()),C=ee(),S={},clearTimeout(c)},ne=(t,i=!0)=>{t.length&&J(()=>{let l=!!Object.keys(S).length;if(t.forEach(O),!l){g();let m=T({},C);k(),u.emit("ready",m)}},i)};if(f.cache&&"localStorage"in window){let t=!0,i=L(e.identifier,typeof f.cache=="boolean"?{}:f.cache);i!=null&&i.length&&J(()=>{v("loading from cache",i),ne(i,!1),u.emit("cache loaded",i)}),U("flags loaded",l=>{H(e.identifier,l),t=!1}),U("changed",l=>{t||(l.deleted?fe(e.identifier,l.flag):ue(e.identifier,l))})}return{on:U,off:we,close:ie,setEvaluations:ne,registerAPIRequestMiddleware:t=>{N=Y(t)},refreshEvaluations:()=>{Z&&!r&&Date.now()-Q>=6e4&&(P(),Q=Date.now())},variation:(t,i,l=!1)=>he(t,i,C,ye,l)}};export{_ as Event,ht as initialize};

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

var Re=Object.defineProperty,Se=Object.defineProperties;var Ie=Object.getOwnPropertyDescriptors;var ne=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var ae=(a,e,n)=>e in a?Re(a,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[e]=n,T=(a,e)=>{for(var n in e||(e={}))ye.call(e,n)&&ae(a,n,e[n]);if(ne)for(var n of ne(e))De.call(e,n)&&ae(a,n,e[n]);return a},U=(a,e)=>Se(a,Ie(e));var w=(a,e,n)=>new Promise((l,c)=>{var f=R=>{try{b(n.next(R))}catch(s){c(s)}},v=R=>{try{b(n.throw(R))}catch(s){c(s)}},b=R=>R.done?l(R.value):Promise.resolve(R.value).then(f,v);b((n=n.apply(a,e)).next())});import we from"jwt-decode";import Ce from"mitt";var _=(h=>(h.READY="ready",h.CONNECTED="connected",h.DISCONNECTED="disconnected",h.POLLING="polling",h.POLLING_STOPPED="polling stopped",h.FLAGS_LOADED="flags loaded",h.CACHE_LOADED="cache loaded",h.CHANGED="changed",h.ERROR="error",h.ERROR_METRICS="metrics error",h.ERROR_AUTH="auth error",h.ERROR_FETCH_FLAGS="fetch flags error",h.ERROR_FETCH_FLAG="fetch flag error",h.ERROR_STREAM="stream error",h))(_||{});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,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},re=a=>{let e=T(T({},Te),a);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(a,...e)=>console.error(`[FF-SDK] ${a}`,...e),j=(a,e=!0)=>{e?setTimeout(a,0):a()},M=(a,e)=>Math.round(Math.random()*(e-a)+a);function W(a){return"HARNESS_FF_CACHE_"+a}function L(a,e={}){let n=W(a),l=parseInt(window.localStorage.getItem(n+".ts"));if(e!=null&&e.ttl&&!isNaN(l)&&l+e.ttl<Date.now())return Oe(a),[];let c=window.localStorage.getItem(n);if(c)try{return JSON.parse(c)}catch(f){}return[]}function H(a,e){let n=W(a);window.localStorage.setItem(n,JSON.stringify(e)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(a,e){let n=L(a),l=n.find(({flag:c})=>c===e.flag);l?Object.assign(l,e):n.push(e),H(a,n)}function se(a,e){let n=L(a),l=n.findIndex(({flag:c})=>c===e);l>-1&&(n.splice(l,1),H(a,n))}function Oe(a){let e=W(a);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function J(a){return function(...n){let[l,c]=a(n);return fetch(l,c)}}var le=3e4,G=class{constructor(e,n,l,c,f,v,b){this.closed=!1;this.eventBus=e,this.configurations=n,this.url=l,this.apiKey=c,this.standardHeaders=f,this.eventCallback=b,this.fallbackPoller=v}start(){let e=s=>{s.toString().split(/\r?\n/).forEach(n)},n=s=>{if(s.startsWith("data:")){let D=JSON.parse(s.substring(5));this.logDebug("Received event from stream: ",D),this.eventCallback(D)}},l=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},c=()=>{clearInterval(this.readTimeoutCheckerId);let s=M(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+s+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),s)},f=s=>{s&&y("Stream has issue",s),this.fallBackToPolling(),this.eventBus.emit("stream error",s),this.eventBus.emit("error",s),c()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[s,D]of Object.entries(v))this.xhr.setRequestHeader(s,D);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{f("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||f(null)},this.xhr.ontimeout=()=>{f("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){f(`HTTP code ${this.xhr.status}`);return}l()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let s=this.xhr.responseText.slice(b);b+=s.length,this.logDebug("SSE GOT: "+s),e(s)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-le&&(y("SSE read timeout"),this.xhr.abort())},le),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...n)}};function ce(a,e,n,l,c){let f=a in n,v=f?n[a]:e;return f&&l(a,v),c?{value:v,isDefaultValue:!f}:v}var x=class{constructor(e,n,l){this.fetchFlagsFn=e;this.configurations=n;this.eventBus=l;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){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `);return}if(y("Error when polling for flag updates",n),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);let l=M(1e3,1e4);yield new Promise(c=>setTimeout(c,l))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...n)}};var ge="1.16.0",fe=`Javascript ${ge} Client`,Ae=500,Fe=globalThis.fetch,Y=!!globalThis.Proxy,X=a=>{let{value:e}=a;try{switch(a.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(n){y(n)}return e},st=(a,e,n)=>{let l=!1,c,f,v,b,R,s,D=!0,F={},N=J(t=>t),z=0,h=!1,P=()=>{D=!1},V=()=>{D=!0},S=[],d=Ce(),u=re(n);u.eventsSyncInterval<6e4&&(u.eventsSyncInterval=6e4),u.pollingInterval<6e4&&(u.pollingInterval=6e4);let p=(t,...i)=>{u.debug&&console.debug(`[FF-SDK] ${t}`,...i)},$=t=>{if(D){let i=Date.now();i-t.lastAccessed>Ae&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(P(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),V())};let he=(t,i)=>w(void 0,null,function*(){return(yield(yield Fe(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":fe},body:JSON.stringify({apiKey:t,target:U(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,K=()=>{if(S.length){p("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:ge}]}))};N(`${u.eventUrl}/metrics/${c}?cluster=${f}`,{method:"POST",headers:T({"Content-Type":"application/json"},F),body:JSON.stringify(t)}).then(()=>{S=[],B=0}).catch(i=>{B++&&(S=[],B=0),p(i),d.emit("metrics error",i)}).finally(()=>{s=window.setTimeout(K,u.eventsSyncInterval)})}else s=window.setTimeout(K,u.eventsSyncInterval)},I={},ve=t=>{p("Sending event for",t.flag),Y?d.emit("changed",new Proxy(t,{get(i,o){var m;if(D&&i.hasOwnProperty(o)&&o==="value"){let E=i.flag,r=t.value,g=S.find(A=>A.featureIdentifier===E&&A.featureValue===r);g?($(g),g.variationIdentifier=((m=I[E])==null?void 0:m.identifier)||""):S.push({featureIdentifier:E,featureValue:String(r),variationIdentifier:I[E].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?X(t):t[o]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:X(t)})},Q=function(){return Y?new Proxy({},{get(t,i){var m,E,r;let o=t[i];if(D&&t.hasOwnProperty(i)){let g=t[i],A=S.find(ie=>ie.featureIdentifier===i&&g===ie.featureValue);A?(A.variationIdentifier=((m=I[i])==null?void 0:m.identifier)||"",$(A)):S.push({featureIdentifier:i,featureValue:g,variationIdentifier:((E=I[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",g,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return o}}):{}},O=Q();he(a,u).then(t=>w(void 0,null,function*(){if(l)return;R=t;let i=we(t);if(F={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":fe},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(E){}s=window.setTimeout(K,u.eventsSyncInterval),c=i.environment,f=i.clusterIdentifier;let o=!!Object.keys(I).length;if((yield k())||p("Fetch all flags ok",O),!l){if(u.streamEnabled?(p("Streaming mode enabled"),pe()):u.pollingEnabled?(p("Polling mode enabled"),me()):p("Streaming and polling mode disabled"),!o){P();let E=T({},O);V(),d.emit("ready",E)}h=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let k=()=>w(void 0,null,function*(){try{let t=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations?cluster=${f}`,{headers:F});if(t.ok){let i=yield t.json();i.forEach(C),d.emit("flags loaded",i)}else y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t)}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),t}}),Z=t=>w(void 0,null,function*(){try{let i=yield N(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations/${t}?cluster=${f}`,{headers:F});if(i.ok){let o=yield i.json();C(o)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),C=t=>{P();let i=X(t);i!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=i,I[t.flag]=U(T({},t),{value:i}),ve(t)),V()};b=new x(k,u,d);let pe=()=>{let t=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):Z(r.identifier);break;case"delete":delete O[r.identifier],d.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(g=>i(g))),m=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(g=>{C(g)}):k())},E=`${u.baseUrl}/stream?cluster=${f}`;v=new G(d,u,E,a,F,b,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&m(r)}),v.start()},me=()=>{b.start()},q=(t,i)=>d.on(t,i),Ee=(t,i)=>{t?d.off(t,i):ee()},be=(t,i)=>{var r;if(!D||Y||i===void 0)return;let o=i,m=t,E=S.find(g=>g.featureIdentifier===m&&g.featureValue===o);E?($(E),E.variationIdentifier=((r=I[m])==null?void 0:r.identifier)||""):S.push({featureIdentifier:m,featureValue:o,count:1,variationIdentifier:I[m].identifier||"",lastAccessed:Date.now()})},ee=()=>{l=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&b.isPolling()&&(p("Closing Poller"),b.stop()),O=Q(),I={},clearTimeout(s)},te=(t,i=!0)=>{t.length&&j(()=>{let o=!!Object.keys(I).length;if(t.forEach(C),!o){P();let m=T({},O);V(),d.emit("ready",m)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=L(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&j(()=>{p("loading from cache",i),te(i,!1),d.emit("cache loaded",i)}),q("flags loaded",o=>{H(e.identifier,o),t=!1}),q("changed",o=>{t||(o.deleted?se(e.identifier,o.flag):oe(e.identifier,o))})}return{on:q,off:Ee,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{N=J(t)},refreshEvaluations:()=>{h&&!l&&Date.now()-z>=6e4&&(k(),z=Date.now())},variation:(t,i,o=!1)=>ce(t,i,O,be,o)}};export{_ as Event,st as initialize};
var Re=Object.defineProperty,Se=Object.defineProperties;var Ie=Object.getOwnPropertyDescriptors;var ne=Object.getOwnPropertySymbols;var ye=Object.prototype.hasOwnProperty,De=Object.prototype.propertyIsEnumerable;var ae=(a,e,n)=>e in a?Re(a,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):a[e]=n,T=(a,e)=>{for(var n in e||(e={}))ye.call(e,n)&&ae(a,n,e[n]);if(ne)for(var n of ne(e))De.call(e,n)&&ae(a,n,e[n]);return a},q=(a,e)=>Se(a,Ie(e));var C=(a,e,n)=>new Promise((l,c)=>{var g=R=>{try{b(n.next(R))}catch(s){c(s)}},v=R=>{try{b(n.throw(R))}catch(s){c(s)}},b=R=>R.done?l(R.value):Promise.resolve(R.value).then(g,v);b((n=n.apply(a,e)).next())});import Ce from"jwt-decode";import we from"mitt";var _=(f=>(f.READY="ready",f.CONNECTED="connected",f.DISCONNECTED="disconnected",f.POLLING="polling",f.POLLING_STOPPED="polling stopped",f.POLLING_CHANGED="polling changed",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))(_||{});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,allAttributesPrivate:!1,privateAttributeNames:[],cache:!1},re=a=>{let e=T(T({},Te),a);return e.pollingEnabled===void 0&&(e.pollingEnabled=e.streamEnabled),e},y=(a,...e)=>console.error(`[FF-SDK] ${a}`,...e),U=(a,e=!0)=>{e?setTimeout(a,0):a()},k=(a,e)=>Math.round(Math.random()*(e-a)+a);function j(a){return"HARNESS_FF_CACHE_"+a}function L(a,e={}){let n=j(a),l=parseInt(window.localStorage.getItem(n+".ts"));if(e!=null&&e.ttl&&!isNaN(l)&&l+e.ttl<Date.now())return Oe(a),[];let c=window.localStorage.getItem(n);if(c)try{return JSON.parse(c)}catch(g){}return[]}function M(a,e){let n=j(a);window.localStorage.setItem(n,JSON.stringify(e)),window.localStorage.setItem(n+".ts",Date.now().toString())}function oe(a,e){let n=L(a),l=n.find(({flag:c})=>c===e.flag);l?Object.assign(l,e):n.push(e),M(a,n)}function se(a,e){let n=L(a),l=n.findIndex(({flag:c})=>c===e);l>-1&&(n.splice(l,1),M(a,n))}function Oe(a){let e=j(a);window.localStorage.removeItem(e),window.localStorage.removeItem(e+".ts")}function W(a){return function(...n){let[l,c]=a(n);return fetch(l,c)}}var le=3e4,H=class{constructor(e,n,l,c,g,v,b){this.closed=!1;this.eventBus=e,this.configurations=n,this.url=l,this.apiKey=c,this.standardHeaders=g,this.eventCallback=b,this.fallbackPoller=v}start(){let e=s=>{s.toString().split(/\r?\n/).forEach(n)},n=s=>{if(s.startsWith("data:")){let D=JSON.parse(s.substring(5));this.logDebug("Received event from stream: ",D),this.eventCallback(D)}},l=()=>{this.logDebug("Stream connected"),this.eventBus.emit("connected")},c=()=>{clearInterval(this.readTimeoutCheckerId);let s=k(1e3,1e4);this.logDebug("Stream disconnected, will reconnect in "+s+"ms"),this.eventBus.emit("disconnected"),setTimeout(()=>this.start(),s)},g=s=>{s&&y("Stream has issue",s),this.fallBackToPolling(),this.eventBus.emit("stream error",s),this.eventBus.emit("error",s),c()},v=T({"Cache-Control":"no-cache",Accept:"text/event-stream","API-Key":this.apiKey},this.standardHeaders);this.logDebug("SSE HTTP start request",this.url),this.xhr=new XMLHttpRequest,this.xhr.open("GET",this.url);for(let[s,D]of Object.entries(v))this.xhr.setRequestHeader(s,D);this.xhr.timeout=24*60*60*1e3,this.xhr.onerror=()=>{g("XMLHttpRequest error on SSE stream")},this.xhr.onabort=()=>{this.logDebug("SSE aborted"),this.closed||g(null)},this.xhr.ontimeout=()=>{g("SSE timeout")},this.xhr.onload=()=>{if(this.xhr.status>=400&&this.xhr.status<=599){g(`HTTP code ${this.xhr.status}`);return}l()};let b=0,R=Date.now();this.xhr.onprogress=()=>{this.stopFallBackPolling(),R=Date.now();let s=this.xhr.responseText.slice(b);b+=s.length,this.logDebug("SSE GOT: "+s),e(s)},this.readTimeoutCheckerId=setInterval(()=>{R<Date.now()-le&&(y("SSE read timeout"),this.xhr.abort())},le),this.xhr.send()}close(){this.closed=!0,this.xhr&&this.xhr.abort(),clearInterval(this.readTimeoutCheckerId),this.stopFallBackPolling()}fallBackToPolling(){!this.fallbackPoller.isPolling()&&this.configurations.pollingEnabled&&(this.logDebug("Falling back to polling mode while stream recovers"),this.fallbackPoller.start())}stopFallBackPolling(){this.fallbackPoller.isPolling()&&(this.logDebug("Stopping fallback polling mode"),this.fallbackPoller.stop())}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Streaming: ${e}`,...n)}};function ce(a,e,n,l,c){let g=a in n,v=g?n[a]:e;return g&&l(a,v),c?{value:v,isDefaultValue:!g}:v}var N=class{constructor(e,n,l,c){this.fetchFlagsFn=e;this.configurations=n;this.eventBus=l;this.storage=c;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 C(this,null,function*(){for(let e=1;e<=this.maxAttempts;e++){let n=yield this.fetchFlagsFn();if(!n){this.logDebug(`Successfully polled for flag updates, next poll in ${this.configurations.pollingInterval}ms. `),this.eventBus.emit("polling changed",this.storage);return}if(y("Error when polling for flag updates",n),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);let l=k(1e3,1e4);yield new Promise(c=>setTimeout(c,l))}})}stop(){this.timeoutId&&(clearTimeout(this.timeoutId),this.timeoutId=void 0,this.isRunning=!1,this.eventBus.emit("polling stopped"),this.logDebug("Polling stopped"))}isPolling(){return this.isRunning}logDebug(e,...n){this.configurations.debug&&console.debug(`[FF-SDK] Poller: ${e}`,...n)}};var ge="1.16.0",fe=`Javascript ${ge} Client`,Ae=500,Fe=globalThis.fetch,J=!!globalThis.Proxy,Y=a=>{let{value:e}=a;try{switch(a.kind.toLowerCase()){case"int":case"number":e=Number(e);break;case"boolean":e=e.toString().toLowerCase()==="true";break;case"json":e=JSON.parse(e);break}}catch(n){y(n)}return e},st=(a,e,n)=>{let l=!1,c,g,v,b,R,s,D=!0,F={},x=W(t=>t),X=0,z=!1,f=()=>{D=!1},P=()=>{D=!0},S=[],d=we(),u=re(n);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(D){let i=Date.now();i-t.lastAccessed>Ae&&(t.count++,t.lastAccessed=i)}};globalThis.onbeforeunload=()=>{S.length&&globalThis.localStorage&&(f(),globalThis.localStorage.HARNESS_FF_METRICS=JSON.stringify(S),P())};let he=(t,i)=>C(void 0,null,function*(){return(yield(yield Fe(`${i.baseUrl}/client/auth`,{method:"POST",headers:{"Content-Type":"application/json","Harness-SDK-Info":fe},body:JSON.stringify({apiKey:t,target:q(T({},e),{identifier:String(e.identifier)})})})).json()).authToken}),B=0,$=()=>{if(S.length){p("Sending metrics...",{metrics:S,evaluations:I});let t={metricsData:S.map(i=>({timestamp:Date.now(),count:i.count,metricsType:"FFMETRICS",attributes:[{key:"featureIdentifier",value:i.featureIdentifier},{key:"featureName",value:i.featureIdentifier},{key:"variationIdentifier",value:i.variationIdentifier},{key:"target",value:e.identifier},{key:"SDK_NAME",value:"JavaScript"},{key:"SDK_LANGUAGE",value:"JavaScript"},{key:"SDK_TYPE",value:"client"},{key:"SDK_VERSION",value:ge}]}))};x(`${u.eventUrl}/metrics/${c}?cluster=${g}`,{method:"POST",headers:T({"Content-Type":"application/json"},F),body:JSON.stringify(t)}).then(()=>{S=[],B=0}).catch(i=>{B++&&(S=[],B=0),p(i),d.emit("metrics error",i)}).finally(()=>{s=window.setTimeout($,u.eventsSyncInterval)})}else s=window.setTimeout($,u.eventsSyncInterval)},I={},ve=t=>{p("Sending event for",t.flag),J?d.emit("changed",new Proxy(t,{get(i,o){var m;if(D&&i.hasOwnProperty(o)&&o==="value"){let E=i.flag,r=t.value,h=S.find(A=>A.featureIdentifier===E&&A.featureValue===r);h?(G(h),h.variationIdentifier=((m=I[E])==null?void 0:m.identifier)||""):S.push({featureIdentifier:E,featureValue:String(r),variationIdentifier:I[E].identifier||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag",o,"has been read with value via stream update",r)}return o==="value"?Y(t):t[o]}})):d.emit("changed",{deleted:t.deleted,flag:t.flag,value:Y(t)})},Q=function(){return J?new Proxy({},{get(t,i){var m,E,r;let o=t[i];if(D&&t.hasOwnProperty(i)){let h=t[i],A=S.find(ie=>ie.featureIdentifier===i&&h===ie.featureValue);A?(A.variationIdentifier=((m=I[i])==null?void 0:m.identifier)||"",G(A)):S.push({featureIdentifier:i,featureValue:h,variationIdentifier:((E=I[i])==null?void 0:E.identifier)||"",count:1,lastAccessed:Date.now()}),p("Metrics event: Flag:",i,"has been read with value:",h,"variationIdentifier:",(r=I[i])==null?void 0:r.identifier)}return o}}):{}},O=Q();he(a,u).then(t=>C(void 0,null,function*(){if(l)return;R=t;let i=Ce(t);if(F={Authorization:`Bearer ${R}`,"Harness-AccountID":i.accountID,"Harness-EnvironmentID":i.environmentIdentifier,"Harness-SDK-Info":fe},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(E){}s=window.setTimeout($,u.eventsSyncInterval),c=i.environment,g=i.clusterIdentifier;let o=!!Object.keys(I).length;if((yield V())||p("Fetch all flags ok",O),!l){if(u.streamEnabled?(p("Streaming mode enabled"),pe()):u.pollingEnabled?(p("Polling mode enabled"),me()):p("Streaming and polling mode disabled"),!o){f();let E=T({},O);P(),d.emit("ready",E)}z=!0}})).catch(t=>{y("Authentication error: ",t),d.emit("auth error",t),d.emit("error",t)});let V=()=>C(void 0,null,function*(){try{let t=yield x(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations?cluster=${g}`,{headers:F});if(t.ok){let i=yield t.json();i.forEach(w),d.emit("flags loaded",i)}else y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t)}catch(t){return y("Features fetch operation error: ",t),d.emit("fetch flags error",t),d.emit("error",t),t}}),Z=t=>C(void 0,null,function*(){try{let i=yield x(`${u.baseUrl}/client/env/${c}/target/${e.identifier}/evaluations/${t}?cluster=${g}`,{headers:F});if(i.ok){let o=yield i.json();w(o)}else y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}catch(i){y("Feature fetch operation error: ",i),d.emit("fetch flag error",i),d.emit("error",i)}}),w=t=>{f();let i=Y(t);i!==O[t.flag]&&(p("Flag variation has changed for ",t.identifier),O[t.flag]=i,I[t.flag]=q(T({},t),{value:i}),ve(t)),P()};b=new N(V,u,d,O);let pe=()=>{let t=r=>{switch(r.event){case"create":o(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):setTimeout(()=>Z(r.identifier),1e3);break;case"patch":o(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):Z(r.identifier);break;case"delete":delete O[r.identifier],d.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(h=>i(h))),m=r=>{r.event==="patch"&&(o(r.evaluations)?r.evaluations.forEach(h=>{w(h)}):V())},E=`${u.baseUrl}/stream?cluster=${g}`;v=new H(d,u,E,a,F,b,r=>{r.domain==="flag"?t(r):r.domain==="target-segment"&&m(r)}),v.start()},me=()=>{b.start()},K=(t,i)=>d.on(t,i),Ee=(t,i)=>{t?d.off(t,i):ee()},be=(t,i)=>{var r;if(!D||J||i===void 0)return;let o=i,m=t,E=S.find(h=>h.featureIdentifier===m&&h.featureValue===o);E?(G(E),E.variationIdentifier=((r=I[m])==null?void 0:r.identifier)||""):S.push({featureIdentifier:m,featureValue:o,count:1,variationIdentifier:I[m].identifier||"",lastAccessed:Date.now()})},ee=()=>{l=!0,u.streamEnabled&&(p("Closing event stream"),typeof(v==null?void 0:v.close)=="function"&&v.close(),d.all.clear()),u.pollingEnabled&&b.isPolling()&&(p("Closing Poller"),b.stop()),O=Q(),I={},clearTimeout(s)},te=(t,i=!0)=>{t.length&&U(()=>{let o=!!Object.keys(I).length;if(t.forEach(w),!o){f();let m=T({},O);P(),d.emit("ready",m)}},i)};if(u.cache&&"localStorage"in window){let t=!0,i=L(e.identifier,typeof u.cache=="boolean"?{}:u.cache);i!=null&&i.length&&U(()=>{p("loading from cache",i),te(i,!1),d.emit("cache loaded",i)}),K("flags loaded",o=>{M(e.identifier,o),t=!1}),K("changed",o=>{t||(o.deleted?se(e.identifier,o.flag):oe(e.identifier,o))})}return{on:K,off:Ee,close:ee,setEvaluations:te,registerAPIRequestMiddleware:t=>{x=W(t)},refreshEvaluations:()=>{z&&!l&&Date.now()-X>=6e4&&(V(),X=Date.now())},variation:(t,i,o=!1)=>ce(t,i,O,be,o)}};export{_ as Event,st as initialize};

@@ -20,2 +20,3 @@ export interface Target {

POLLING_STOPPED = "polling stopped",
POLLING_CHANGED = "polling changed",
FLAGS_LOADED = "flags loaded",

@@ -22,0 +23,0 @@ CACHE_LOADED = "cache loaded",

{
"name": "@harnessio/ff-javascript-client-sdk",
"version": "1.17.1",
"version": "1.18.0-rc.1",
"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