@teracrafts/flagkit 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +443 -0
- package/dist/index.d.mts +2048 -0
- package/dist/index.d.ts +2048 -0
- package/dist/index.global.js +3 -0
- package/dist/index.global.js.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +73 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var De=(n=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(n,{get:(e,t)=>(typeof require<"u"?require:e)[t]}):n)(function(n){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+n+'" is not supported')});function I(n,e,t){return {flagKey:n,value:e,enabled:false,reason:t,version:0,timestamp:new Date}}var Ue={ttl:3e5,maxSize:1e3},k=class{cache=new Map;config;logger;constructor(e){this.config={...Ue,...e},this.logger=e?.logger;}get(e){let t=this.cache.get(e);return t?Date.now()>t.expiresAt?(this.cache.delete(e),this.logger?.debug(`Cache miss (expired): ${e}`),null):(this.logger?.debug(`Cache hit: ${e}`),t.flag):null}getEntry(e){let t=this.cache.get(e);return t||null}isStale(e){let t=this.cache.get(e);return t?Date.now()>t.expiresAt:false}getStale(e){return this.cache.get(e)?.flag??null}set(e,t,r){this.cache.size>=this.config.maxSize&&!this.cache.has(e)&&this.evictOldest();let i=Date.now(),s={flag:t,fetchedAt:i,expiresAt:i+(r??this.config.ttl)};this.cache.set(e,s),this.logger?.debug(`Cache set: ${e}`,{ttl:r??this.config.ttl});}setMany(e,t){for(let r of e)this.set(r.key,r,t);}delete(e){let t=this.cache.delete(e);return t&&this.logger?.debug(`Cache delete: ${e}`),t}clear(){let e=this.cache.size;this.cache.clear(),this.logger?.debug(`Cache cleared: ${e} entries removed`);}getAllKeys(){return Array.from(this.cache.keys())}getAllValid(){let e=Date.now(),t=[];for(let[r,i]of this.cache.entries())e<=i.expiresAt?t.push(i.flag):this.cache.delete(r);return t}getAll(){return Array.from(this.cache.values()).map(e=>e.flag)}has(e){return this.cache.has(e)}getStats(){let e=Date.now(),t=0,r=0;for(let i of this.cache.values())e<=i.expiresAt?t++:r++;return {size:this.cache.size,validCount:t,staleCount:r,maxSize:this.config.maxSize}}evictOldest(){let e=null,t=1/0;for(let[r,i]of this.cache.entries())i.fetchedAt<t&&(t=i.fetchedAt,e=r);e&&(this.cache.delete(e),this.logger?.debug(`Cache evicted oldest: ${e}`));}export(){let e={};for(let[t,r]of this.cache.entries())e[t]=r;return e}import(e){for(let[t,r]of Object.entries(e))Date.now()<=r.expiresAt&&this.cache.set(t,r);this.logger?.debug(`Cache imported: ${this.cache.size} entries`);}};function H(n,e){if(!(!n&&!e))return n?e?{...n,...e,custom:{...n.custom,...e.custom},privateAttributes:[...n.privateAttributes??[],...e.privateAttributes??[]]}:n:e??void 0}function pe(n){let{privateAttributes:e,...t}=n,r={...t};if(e&&e.length>0)for(let i of e)if(i.startsWith("custom.")&&r.custom){let s=i.slice(7);delete r.custom[s];}else i in r&&delete r[i];return r}var D=class{globalContext=null;logger;constructor(e){this.logger=e;}setContext(e){this.globalContext=e,this.logger?.debug("Global context set",{userId:e.userId,anonymous:e.anonymous});}getContext(){return this.globalContext}clearContext(){this.globalContext=null,this.logger?.debug("Global context cleared");}identify(e,t){this.globalContext={...this.globalContext,...t,userId:e,anonymous:false},this.logger?.debug("User identified",{userId:e});}reset(){this.globalContext={anonymous:true},this.logger?.debug("Context reset to anonymous");}resolveContext(e){let t=H(this.globalContext,e);if(t)return pe(t)}getMergedContext(e){return H(this.globalContext,e)}isIdentified(){return !!this.globalContext?.userId&&!this.globalContext.anonymous}isAnonymous(){return !this.globalContext||this.globalContext.anonymous===true}getUserId(){return this.globalContext?.userId}};function G(){return typeof window<"u"&&typeof document<"u"?"browser":typeof process<"u"&&process.versions&&process.versions.node?"node":"unknown"}function u(){return G()==="browser"}function T(){return G()==="node"}function he(n){let e=G();if(e==="browser")return `FlagKit-JS/${n} (Browser)`;if(e==="node"){let t=typeof process<"u"?process.version:"unknown";return `FlagKit-JS/${n} (Node.js/${t})`}return `FlagKit-JS/${n} (Unknown)`}function me(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{let e=Math.random()*16|0;return (n==="x"?e:e&3|8).toString(16)})}function ve(){return new Date().toISOString()}var z={INIT_FAILED:{code:"INIT_FAILED",numericCode:1e3,message:"SDK initialization failed",recoverable:false},INIT_TIMEOUT:{code:"INIT_TIMEOUT",numericCode:1001,message:"Initialization timed out",recoverable:true},INIT_INVALID_CONFIG:{code:"INIT_INVALID_CONFIG",numericCode:1002,message:"Invalid SDK configuration",recoverable:false},INIT_MISSING_API_KEY:{code:"INIT_MISSING_API_KEY",numericCode:1003,message:"API key is required",recoverable:false},INIT_INVALID_BASE_URL:{code:"INIT_INVALID_BASE_URL",numericCode:1004,message:"Invalid base URL format",recoverable:false},INIT_ALREADY_INITIALIZED:{code:"INIT_ALREADY_INITIALIZED",numericCode:1005,message:"SDK already initialized",recoverable:false},AUTH_INVALID_KEY:{code:"AUTH_INVALID_KEY",numericCode:1100,message:"Invalid API key",recoverable:false},AUTH_EXPIRED_KEY:{code:"AUTH_EXPIRED_KEY",numericCode:1101,message:"API key has expired",recoverable:false},AUTH_REVOKED_KEY:{code:"AUTH_REVOKED_KEY",numericCode:1102,message:"API key has been revoked",recoverable:false},AUTH_INSUFFICIENT_PERMISSIONS:{code:"AUTH_INSUFFICIENT_PERMISSIONS",numericCode:1103,message:"API key lacks required permissions",recoverable:false},AUTH_RATE_LIMITED:{code:"AUTH_RATE_LIMITED",numericCode:1104,message:"Rate limit exceeded",recoverable:true},AUTH_PROJECT_MISMATCH:{code:"AUTH_PROJECT_MISMATCH",numericCode:1105,message:"API key not valid for this project",recoverable:false},AUTH_ENVIRONMENT_MISMATCH:{code:"AUTH_ENVIRONMENT_MISMATCH",numericCode:1106,message:"API key not valid for this environment",recoverable:false},AUTH_IP_RESTRICTED:{code:"AUTH_IP_RESTRICTED",numericCode:1107,message:"IP address not allowed for this API key",recoverable:false},AUTH_ORGANIZATION_REQUIRED:{code:"AUTH_ORGANIZATION_REQUIRED",numericCode:1108,message:"Organization context missing from token",recoverable:false},AUTH_SUBSCRIPTION_SUSPENDED:{code:"AUTH_SUBSCRIPTION_SUSPENDED",numericCode:1109,message:"Subscription is suspended",recoverable:false},EVAL_FLAG_NOT_FOUND:{code:"EVAL_FLAG_NOT_FOUND",numericCode:1200,message:"Flag does not exist",recoverable:false},EVAL_FLAG_DISABLED:{code:"EVAL_FLAG_DISABLED",numericCode:1201,message:"Flag is disabled",recoverable:false},EVAL_TYPE_MISMATCH:{code:"EVAL_TYPE_MISMATCH",numericCode:1202,message:"Flag value type mismatch",recoverable:false},EVAL_INVALID_CONTEXT:{code:"EVAL_INVALID_CONTEXT",numericCode:1203,message:"Invalid evaluation context",recoverable:false},EVAL_RULE_ERROR:{code:"EVAL_RULE_ERROR",numericCode:1204,message:"Error evaluating targeting rule",recoverable:true},EVAL_SEGMENT_ERROR:{code:"EVAL_SEGMENT_ERROR",numericCode:1205,message:"Error evaluating segment",recoverable:true},EVAL_DEFAULT_USED:{code:"EVAL_DEFAULT_USED",numericCode:1206,message:"Using default value",recoverable:false},EVAL_CACHED_VALUE:{code:"EVAL_CACHED_VALUE",numericCode:1207,message:"Using cached value",recoverable:false},EVAL_STALE_VALUE:{code:"EVAL_STALE_VALUE",numericCode:1208,message:"Using stale cached value",recoverable:false},NETWORK_ERROR:{code:"NETWORK_ERROR",numericCode:1300,message:"Network request failed",recoverable:true},NETWORK_TIMEOUT:{code:"NETWORK_TIMEOUT",numericCode:1301,message:"Request timed out",recoverable:true},NETWORK_DNS_ERROR:{code:"NETWORK_DNS_ERROR",numericCode:1302,message:"DNS resolution failed",recoverable:true},NETWORK_CONNECTION_REFUSED:{code:"NETWORK_CONNECTION_REFUSED",numericCode:1303,message:"Connection refused",recoverable:true},NETWORK_SSL_ERROR:{code:"NETWORK_SSL_ERROR",numericCode:1304,message:"SSL/TLS error",recoverable:false},NETWORK_OFFLINE:{code:"NETWORK_OFFLINE",numericCode:1305,message:"Device is offline",recoverable:true},NETWORK_SERVER_ERROR:{code:"NETWORK_SERVER_ERROR",numericCode:1306,message:"Server error",recoverable:true},NETWORK_INVALID_RESPONSE:{code:"NETWORK_INVALID_RESPONSE",numericCode:1307,message:"Invalid server response",recoverable:true},NETWORK_SERVICE_UNAVAILABLE:{code:"NETWORK_SERVICE_UNAVAILABLE",numericCode:1308,message:"Service unavailable",recoverable:true},CACHE_READ_ERROR:{code:"CACHE_READ_ERROR",numericCode:1400,message:"Failed to read from cache",recoverable:true},CACHE_WRITE_ERROR:{code:"CACHE_WRITE_ERROR",numericCode:1401,message:"Failed to write to cache",recoverable:true},CACHE_EXPIRED:{code:"CACHE_EXPIRED",numericCode:1402,message:"Cache has expired",recoverable:true},CACHE_CORRUPT:{code:"CACHE_CORRUPT",numericCode:1403,message:"Cache data is corrupted",recoverable:true},CACHE_STORAGE_FULL:{code:"CACHE_STORAGE_FULL",numericCode:1404,message:"Storage quota exceeded",recoverable:true},EVENT_SEND_FAILED:{code:"EVENT_SEND_FAILED",numericCode:1500,message:"Failed to send event",recoverable:true},EVENT_INVALID_TYPE:{code:"EVENT_INVALID_TYPE",numericCode:1501,message:"Invalid event type",recoverable:false},EVENT_INVALID_DATA:{code:"EVENT_INVALID_DATA",numericCode:1502,message:"Invalid event data",recoverable:false},EVENT_QUEUE_FULL:{code:"EVENT_QUEUE_FULL",numericCode:1503,message:"Event queue is full",recoverable:true},EVENT_BATCH_PARTIAL:{code:"EVENT_BATCH_PARTIAL",numericCode:1504,message:"Some events failed to send",recoverable:true},CONFIG_INVALID_OPTION:{code:"CONFIG_INVALID_OPTION",numericCode:1600,message:"Invalid configuration option",recoverable:false},CONFIG_MISSING_REQUIRED:{code:"CONFIG_MISSING_REQUIRED",numericCode:1601,message:"Missing required configuration",recoverable:false},CONFIG_TYPE_ERROR:{code:"CONFIG_TYPE_ERROR",numericCode:1602,message:"Configuration type mismatch",recoverable:false},CONFIG_DEPRECATED:{code:"CONFIG_DEPRECATED",numericCode:1603,message:"Configuration option deprecated",recoverable:false},SECURITY_ERROR:{code:"SECURITY_ERROR",numericCode:1700,message:"Security violation detected",recoverable:false},SECURITY_PII_DETECTED:{code:"SECURITY_PII_DETECTED",numericCode:1701,message:"PII detected in data without privateAttributes",recoverable:false},SECURITY_LOCAL_PORT_IN_PRODUCTION:{code:"SECURITY_LOCAL_PORT_IN_PRODUCTION",numericCode:1702,message:"localPort cannot be used in production",recoverable:false},SECURITY_KEY_ROTATION_FAILED:{code:"SECURITY_KEY_ROTATION_FAILED",numericCode:1703,message:"Key rotation failed - both primary and secondary keys rejected",recoverable:false},SECURITY_BOOTSTRAP_VERIFICATION_FAILED:{code:"SECURITY_BOOTSTRAP_VERIFICATION_FAILED",numericCode:1704,message:"Bootstrap data signature verification failed",recoverable:false},STREAMING_TOKEN_INVALID:{code:"STREAMING_TOKEN_INVALID",numericCode:1800,message:"Stream token is invalid",recoverable:true},STREAMING_TOKEN_EXPIRED:{code:"STREAMING_TOKEN_EXPIRED",numericCode:1801,message:"Stream token has expired",recoverable:true},STREAMING_SUBSCRIPTION_SUSPENDED:{code:"STREAMING_SUBSCRIPTION_SUSPENDED",numericCode:1802,message:"Organization subscription suspended",recoverable:false},STREAMING_CONNECTION_LIMIT:{code:"STREAMING_CONNECTION_LIMIT",numericCode:1803,message:"Too many concurrent streaming connections",recoverable:true},STREAMING_UNAVAILABLE:{code:"STREAMING_UNAVAILABLE",numericCode:1804,message:"Streaming service not available",recoverable:true},INTERNAL_ERROR:{code:"INTERNAL_ERROR",numericCode:1900,message:"Internal SDK error",recoverable:false},INTERNAL_STATE_ERROR:{code:"INTERNAL_STATE_ERROR",numericCode:1901,message:"Invalid internal state",recoverable:false},UNKNOWN_ERROR:{code:"UNKNOWN_ERROR",numericCode:1999,message:"Unknown error occurred",recoverable:false}},Ke=["INIT_TIMEOUT","AUTH_RATE_LIMITED","EVAL_RULE_ERROR","EVAL_SEGMENT_ERROR","NETWORK_ERROR","NETWORK_TIMEOUT","NETWORK_DNS_ERROR","NETWORK_CONNECTION_REFUSED","NETWORK_OFFLINE","NETWORK_SERVER_ERROR","NETWORK_INVALID_RESPONSE","NETWORK_SERVICE_UNAVAILABLE","CACHE_READ_ERROR","CACHE_WRITE_ERROR","CACHE_EXPIRED","CACHE_CORRUPT","CACHE_STORAGE_FULL","EVENT_SEND_FAILED","EVENT_QUEUE_FULL","EVENT_BATCH_PARTIAL","STREAMING_TOKEN_INVALID","STREAMING_TOKEN_EXPIRED","STREAMING_CONNECTION_LIMIT","STREAMING_UNAVAILABLE"];function $(n){return Ke.includes(n)}var Me=[{pattern:/\/(?:[\w.-]+\/)+[\w.-]+/g,replacement:"[PATH]"},{pattern:/[A-Za-z]:\\(?:[\w\s.-]+\\)+[\w.-]*/g,replacement:"[PATH]"},{pattern:/\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b/g,replacement:"[IP]"},{pattern:/sdk_[a-zA-Z0-9_-]{8,}/g,replacement:"sdk_[REDACTED]"},{pattern:/srv_[a-zA-Z0-9_-]{8,}/g,replacement:"srv_[REDACTED]"},{pattern:/cli_[a-zA-Z0-9_-]{8,}/g,replacement:"cli_[REDACTED]"},{pattern:/[\w.+-]+@[\w.-]+\.\w+/g,replacement:"[EMAIL]"},{pattern:/postgres:\/\/[^\s]+/gi,replacement:"[CONNECTION_STRING]"},{pattern:/mysql:\/\/[^\s]+/gi,replacement:"[CONNECTION_STRING]"},{pattern:/mongodb:\/\/[^\s]+/gi,replacement:"[CONNECTION_STRING]"},{pattern:/redis:\/\/[^\s]+/gi,replacement:"[CONNECTION_STRING]"}],q={enabled:true,preserveOriginal:false};function Ee(){return {...q}}function W(n,e){if((e??q).enabled===false)return n;let r=n;for(let{pattern:i,replacement:s}of Me){let a=new RegExp(i.source,i.flags);r=r.replace(a,s);}return r}function Y(n,e){if((e??q).enabled===false)return n;let r={};for(let[i,s]of Object.entries(n))typeof s=="string"?r[i]=W(s,e):typeof s=="object"&&s!==null&&!Array.isArray(s)?r[i]=Y(s,e):r[i]=s;return r}var f=class n extends Error{code;numericCode;statusCode;details;recoverable;retryAfter;requestId;timestamp;originalMessage;constructor(e,t,r){let i=z[e],s=t??i.message,a=r?.sanitization??Ee(),o=W(s,a);super(o,{cause:r?.cause}),this.name="FlagKitError",this.code=e,this.numericCode=i.numericCode,this.recoverable=$(e),this.statusCode=r?.statusCode,this.retryAfter=r?.retryAfter,this.requestId=r?.requestId,this.timestamp=new Date,this.details=r?.details?Y(r.details,a):void 0,a.preserveOriginal&&s!==o&&(this.originalMessage=s),Object.setPrototypeOf(this,n.prototype);}toString(){return `[${this.code}] ${this.message}`}toJSON(){let e={name:this.name,code:this.code,numericCode:this.numericCode,message:this.message,statusCode:this.statusCode,details:this.details,recoverable:this.recoverable,retryAfter:this.retryAfter,requestId:this.requestId,timestamp:this.timestamp.toISOString()};return this.originalMessage&&(e.originalMessage=this.originalMessage),e}},d=class n extends f{constructor(e,t,r){super(e,t,r),this.name="InitializationError",Object.setPrototypeOf(this,n.prototype);}},E=class n extends f{constructor(e,t,r){super(e,t,r),this.name="AuthenticationError",Object.setPrototypeOf(this,n.prototype);}},b=class n extends f{constructor(e,t,r){super(e,t,r),this.name="NetworkError",Object.setPrototypeOf(this,n.prototype);}},U=class n extends f{constructor(e,t,r){super(e,t,r),this.name="EvaluationError",Object.setPrototypeOf(this,n.prototype);}},v=class n extends f{constructor(e,t,r){super(e,t,r),this.name="SecurityError",Object.setPrototypeOf(this,n.prototype);}};function j(n,e,t){let r=e?.requestId,i=e?.message??e?.error;switch(n){case 400:return new f("EVAL_INVALID_CONTEXT",i,{statusCode:n,requestId:r});case 401:return new E("AUTH_INVALID_KEY",i,{statusCode:n,requestId:r});case 403:return new E("AUTH_INSUFFICIENT_PERMISSIONS",i,{statusCode:n,requestId:r});case 404:return new U("EVAL_FLAG_NOT_FOUND",i);case 429:return new E("AUTH_RATE_LIMITED",i,{statusCode:n,retryAfter:t,requestId:r});default:return n>=500?new b("NETWORK_SERVER_ERROR",i,{statusCode:n,retryAfter:t,requestId:r}):new f("UNKNOWN_ERROR",i,{statusCode:n,requestId:r})}}function Ve(n){return n instanceof f}function Q(n){return n instanceof f?n.recoverable:false}var ye=(r=>(r.CLOSED="CLOSED",r.OPEN="OPEN",r.HALF_OPEN="HALF_OPEN",r))(ye||{}),Be={failureThreshold:5,resetTimeout:3e4,successThreshold:1},R=class n extends Error{timeUntilReset;constructor(e){super(`Circuit breaker is open. Reset in ${e}ms`),this.name="CircuitOpenError",this.timeUntilReset=e,Object.setPrototypeOf(this,n.prototype);}},S=class{state="CLOSED";failures=0;successes=0;lastFailureTime=0;config;logger;constructor(e,t){this.config={...Be,...e},this.logger=t;}getState(){return this.checkStateTransition(),this.state}async execute(e){if(this.checkStateTransition(),this.state==="OPEN"){let t=this.config.resetTimeout-(Date.now()-this.lastFailureTime);throw new R(Math.max(0,t))}try{let t=await e();return this.onSuccess(),t}catch(t){throw this.onFailure(),t}}onSuccess(){this.state==="HALF_OPEN"?(this.successes++,this.successes>=this.config.successThreshold&&(this.transitionTo("CLOSED"),this.reset())):this.state==="CLOSED"&&(this.failures=0);}onFailure(){this.failures++,this.lastFailureTime=Date.now(),this.state==="HALF_OPEN"?(this.transitionTo("OPEN"),this.successes=0):this.state==="CLOSED"&&this.failures>=this.config.failureThreshold&&this.transitionTo("OPEN");}reset(){this.state="CLOSED",this.failures=0,this.successes=0,this.lastFailureTime=0,this.logger?.debug("Circuit breaker reset");}checkStateTransition(){this.state==="OPEN"&&Date.now()-this.lastFailureTime>=this.config.resetTimeout&&(this.transitionTo("HALF_OPEN"),this.successes=0);}transitionTo(e){let t=this.state;this.state=e,this.logger?.debug(`Circuit breaker state: ${t} -> ${e}`,{failures:this.failures,successes:this.successes});}getStats(){return {state:this.state,failures:this.failures,successes:this.successes,lastFailureTime:this.lastFailureTime}}};var He={maxAttempts:3,baseDelay:1e3,maxDelay:3e4,backoffMultiplier:2,jitter:100};function Ie(n,e){let t=e.baseDelay*Math.pow(e.backoffMultiplier,n-1),r=Math.min(t,e.maxDelay),i=Math.random()*e.jitter;return r+i}function Ge(n){return new Promise(e=>setTimeout(e,n))}async function J(n,e={},t){let r={...He,...e},{logger:i,operationName:s="operation",shouldRetry:a,onRetry:o}=t??{},c;for(let l=1;l<=r.maxAttempts;l++)try{return await n()}catch(g){if(c=g instanceof Error?g:new Error(String(g)),!(a?a(g):Q(g)))throw i?.debug(`${s} failed with non-retryable error`,{error:c.message,attempt:l}),c;if(l>=r.maxAttempts)throw i?.warn(`${s} failed after ${l} attempts`,{error:c.message}),c;let p=Ie(l,r);i?.debug(`${s} failed, retrying in ${p}ms`,{attempt:l,maxAttempts:r.maxAttempts,error:c.message,delay:p}),o?.(l,g,p),await Ge(p);}throw c??new Error("Retry failed")}function X(n){if(!n)return;let e=parseInt(n,10);if(!isNaN(e)&&e>0)return e;let t=new Date(n);if(!isNaN(t.getTime())){let r=Date.now(),i=t.getTime();if(i>r)return Math.ceil((i-r)/1e3)}}var ze=["email","phone","telephone","mobile","ssn","social_security","socialSecurity","credit_card","creditCard","card_number","cardNumber","cvv","password","passwd","secret","token","api_key","apiKey","private_key","privateKey","access_token","accessToken","refresh_token","refreshToken","auth_token","authToken","address","street","zip_code","zipCode","postal_code","postalCode","date_of_birth","dateOfBirth","dob","birth_date","birthDate","passport","driver_license","driverLicense","national_id","nationalId","bank_account","bankAccount","routing_number","routingNumber","iban","swift"];function Te(n){let e=n.toLowerCase();return ze.some(t=>e.includes(t.toLowerCase()))}function ee(n,e=""){let t=[];for(let[r,i]of Object.entries(n)){let s=e?`${e}.${r}`:r;if(Te(r)&&t.push(s),i&&typeof i=="object"&&!Array.isArray(i)){let a=ee(i,s);t.push(...a);}}return t}function C(n,e){if(!n)return {hasPII:false,fields:[],message:""};let t=ee(n);if(t.length===0)return {hasPII:false,fields:[],message:""};let r=`[FlagKit Security] Potential PII detected in ${e} data: ${t.join(", ")}. `+(e==="context"?"Consider adding these to privateAttributes.":"Consider removing sensitive data from events.");return {hasPII:true,fields:t,message:r}}function $e(n,e,t){if(!n||!t)return;let r=C(n,e);r.hasPII&&t.warn(r.message);}function Re(n){return n.startsWith("srv_")}function qe(n){return n.startsWith("sdk_")||n.startsWith("cli_")}function te(n,e){if(u()&&Re(n)){let t="[FlagKit Security] WARNING: Server keys (srv_) should not be used in browser environments. This exposes your server key in client-side code, which is a security risk. Use SDK keys (sdk_) for client-side applications instead. See: https://docs.flagkit.dev/sdk/security#api-keys";console.warn(t),e?.warn(t);}}var We={warnOnPotentialPII:false,warnOnServerKeyInBrowser:true,additionalPIIPatterns:[]};function A(n){return n.substring(0,8)}function Ye(n){return Array.from(new Uint8Array(n)).map(e=>e.toString(16).padStart(2,"0")).join("")}async function be(n,e){let t=new TextEncoder,r=t.encode(e),i=t.encode(n),s=await crypto.subtle.importKey("raw",r.buffer,{name:"HMAC",hash:"SHA-256"},false,["sign"]),a=await crypto.subtle.sign("HMAC",s,i.buffer);return Ye(a)}async function je(n,e){let r=(await import('crypto')).createHmac("sha256",e);return r.update(n),r.digest("hex")}async function _(n,e){if(u())return be(n,e);if(T())return je(n,e);if(typeof crypto<"u"&&crypto.subtle)return be(n,e);throw new Error("No cryptographic implementation available")}async function re(n,e,t){let r=t??Date.now(),i=JSON.stringify(n),s=`${r}.${i}`,a=await _(s,e);return {data:n,signature:a,timestamp:r,keyId:A(e)}}async function ne(n,e,t){let r=t??Date.now(),i=`${r}.${n}`;return {signature:await _(i,e),timestamp:r}}async function Qe(n,e,t=3e5){let r=Date.now()-n.timestamp;if(r>t||r<0||n.keyId!==A(e))return false;let i=JSON.stringify(n.data),s=`${n.timestamp}.${i}`,a=await _(s,e);return n.signature===a}function ie(){return !!(typeof process<"u"&&process.env)}function Je(n){return JSON.stringify(Z(n))}function Z(n){if(n==null)return n;if(Array.isArray(n))return n.map(Z);if(typeof n=="object"){let e={},t=Object.keys(n).sort();for(let r of t)e[r]=Z(n[r]);return e}return n}async function Ce(n,e,t){let r=t?.maxAge??864e5;if(!n.signature)return {valid:true};if(n.timestamp!==void 0){let a=Date.now()-n.timestamp;if(a<-3e5)return {valid:false,error:`Bootstrap timestamp is in the future: ${new Date(n.timestamp).toISOString()}`};if(a>r)return {valid:false,error:`Bootstrap data is expired: ${Math.floor(a/36e5)} hours old (max: ${Math.floor(r/36e5)} hours)`}}let i=Je(n.flags),s=await _(i,e);return Xe(n.signature,s)?{valid:true}:{valid:false,error:"Bootstrap signature verification failed: signature does not match"}}function Xe(n,e){if(n.length!==e.length)return false;let t=0;for(let r=0;r<n.length;r++)t|=n.charCodeAt(r)^e.charCodeAt(r);return t===0}var h="1.0.0",Ze="https://api.flagkit.dev/api/v1",se=n=>n?`http://localhost:${n}/api/v1`:Ze,N=class{config;circuitBreaker;logger;currentApiKey;keyRotationTimestamp=null;constructor(e){this.config={...e,keyRotationGracePeriod:e.keyRotationGracePeriod??3e5,enableRequestSigning:e.enableRequestSigning??true},this.currentApiKey=e.apiKey,this.logger=e.logger,this.circuitBreaker=new S(e.circuitBreaker,e.logger);}getActiveApiKey(){return this.currentApiKey}getKeyId(){return A(this.currentApiKey)}isInKeyRotation(){return this.keyRotationTimestamp?Date.now()-this.keyRotationTimestamp<(this.config.keyRotationGracePeriod??3e5):false}rotateToSecondaryKey(){return !this.config.secondaryApiKey||this.currentApiKey===this.config.secondaryApiKey?false:(this.logger?.info("Rotating to secondary API key due to authentication failure"),this.currentApiKey=this.config.secondaryApiKey,this.keyRotationTimestamp=Date.now(),true)}async handleAuthFailure(){return this.rotateToSecondaryKey()}async get(e,t){return this.request(e,{...t,method:"GET"})}async post(e,t,r){let i={};if(this.config.enableRequestSigning&&t)try{let s=JSON.stringify(t),{signature:a,timestamp:o}=await ne(s,this.currentApiKey);i["X-Signature"]=a,i["X-Timestamp"]=o.toString(),i["X-Key-Id"]=this.getKeyId();}catch(s){this.logger?.warn("Failed to sign request, proceeding without signature",{error:s instanceof Error?s.message:"Unknown error"});}return this.request(e,{...r,method:"POST",body:t,headers:{...i,...r?.headers}})}async request(e,t={}){let{method:r="GET",headers:i={},body:s,timeout:a=this.config.timeout,skipRetry:o=false,skipCircuitBreaker:c=false}=t,l=this.buildUrl(e),g=async()=>{let m=this.buildHeaders(i);return this.executeRequest(l,{method:r,headers:m,body:s,timeout:a})},y=async()=>{try{return await g()}catch(m){if(m instanceof E&&m.code==="AUTH_INVALID_KEY"&&this.config.secondaryApiKey&&await this.handleAuthFailure())return this.logger?.debug("Retrying request with secondary API key"),g();throw m}},p=c?y:()=>this.circuitBreaker.execute(y);return o?p():J(p,this.config.retry,{logger:this.logger,operationName:`${r} ${e}`,shouldRetry:m=>m instanceof R||m instanceof E?false:m instanceof b?m.recoverable:false})}async executeRequest(e,t){let{method:r,headers:i,body:s,timeout:a}=t,o=new AbortController,c=setTimeout(()=>o.abort(),a);try{this.logger?.debug(`HTTP ${r} ${e}`,{hasBody:!!s,timeout:a});let l=await fetch(e,{method:r,headers:i,body:s?JSON.stringify(s):void 0,signal:o.signal});clearTimeout(c);let g={};l.headers.forEach((B,ke)=>{g[ke.toLowerCase()]=B;});let y=g["x-request-id"],p;if((g["content-type"]??"").includes("application/json")?p=await l.json():p=await l.text(),!l.ok){let B=X(g["retry-after"]??null);throw j(l.status,p,B)}let L=this.extractUsageMetrics(g);return L&&this.config.onUsageUpdate&&this.config.onUsageUpdate(L),this.logger?.debug(`HTTP ${r} ${e} -> ${l.status}`,{requestId:y}),{status:l.status,headers:g,data:p,requestId:y,usageMetrics:L}}catch(l){throw clearTimeout(c),l instanceof Error&&l.name==="AbortError"?new b("NETWORK_TIMEOUT",`Request timed out after ${a}ms`):l instanceof TypeError?new b("NETWORK_ERROR",l.message,{cause:l}):l}}buildUrl(e){let t=this.config.baseUrl.replace(/\/+$/,""),r=e.startsWith("/")?e:`/${e}`;return `${t}${r}`}buildHeaders(e={}){return {"Content-Type":"application/json",Accept:"application/json","X-API-Key":this.currentApiKey,"User-Agent":he(h),"X-FlagKit-SDK-Version":h,"X-FlagKit-SDK-Language":"typescript",...e}}extractUsageMetrics(e){let t=e["x-api-usage-percent"],r=e["x-evaluation-usage-percent"],i=e["x-rate-limit-warning"],s=e["x-subscription-status"];if(!t&&!r&&!i&&!s)return;let a={rateLimitWarning:i==="true"};if(t){let o=parseFloat(t);isNaN(o)||(a.apiUsagePercent=o);}if(r){let o=parseFloat(r);isNaN(o)||(a.evaluationUsagePercent=o);}return s&&["active","trial","past_due","suspended","cancelled"].includes(s)&&(a.subscriptionStatus=s),a.apiUsagePercent!==void 0&&a.apiUsagePercent>=80&&this.logger?.warn(`[FlagKit] API usage at ${a.apiUsagePercent}%`),a.evaluationUsagePercent!==void 0&&a.evaluationUsagePercent>=80&&this.logger?.warn(`[FlagKit] Evaluation usage at ${a.evaluationUsagePercent}%`),a.subscriptionStatus==="suspended"&&this.logger?.error("[FlagKit] Subscription suspended - service degraded"),a}sendBeacon(e,t){if(!u()||typeof navigator>"u"||!navigator.sendBeacon)return false;let r=this.buildUrl(e),i=Date.now(),s=this.currentApiKey.slice(-8),a={data:t,signature:"",timestamp:i,apiKeyId:s},o=new Blob([JSON.stringify(a)],{type:"application/json"}),c=navigator.sendBeacon(r,o);return c?this.logger?.debug("Beacon sent successfully",{path:e,apiKeyId:s}):this.logger?.warn("Beacon failed to send",{path:e}),c}async sendSignedBeacon(e,t){if(!u()||typeof navigator>"u"||!navigator.sendBeacon)return false;let r=this.buildUrl(e);try{let i=await re(t,this.currentApiKey),s={data:i.data,signature:i.signature,timestamp:i.timestamp,apiKeyId:this.currentApiKey.slice(-8)},a=new Blob([JSON.stringify(s)],{type:"application/json"}),o=navigator.sendBeacon(r,a);return o?this.logger?.debug("Signed beacon sent successfully",{path:e,apiKeyId:s.apiKeyId}):this.logger?.warn("Signed beacon failed to send",{path:e}),o}catch(i){return this.logger?.error("Failed to sign beacon payload",{error:i instanceof Error?i.message:"Unknown error"}),this.sendBeacon(e,t)}}getCircuitState(){return this.circuitBreaker.getState()}resetCircuit(){this.circuitBreaker.reset();}};var et={interval:3e4,jitter:1e3,backoffMultiplier:2,maxInterval:3e5},K=class{config;logger;currentInterval;timerId=null;isRunning=false;consecutiveErrors=0;constructor(e){this.config={...et,...e},this.logger=e.logger,this.currentInterval=this.config.interval;}start(){this.isRunning||(this.isRunning=true,this.scheduleNext(),this.logger?.debug("Polling started",{interval:this.currentInterval}));}stop(){this.isRunning&&(this.isRunning=false,this.timerId&&(clearTimeout(this.timerId),this.timerId=null),this.logger?.debug("Polling stopped"));}isActive(){return this.isRunning}getCurrentInterval(){return this.currentInterval}onSuccess(){this.consecutiveErrors=0,this.currentInterval=this.config.interval;}onError(){this.consecutiveErrors++,this.currentInterval=Math.min(this.currentInterval*this.config.backoffMultiplier,this.config.maxInterval),this.logger?.debug("Polling backoff",{interval:this.currentInterval,consecutiveErrors:this.consecutiveErrors});}getNextDelay(){let e=Math.random()*this.config.jitter;return this.currentInterval+e}scheduleNext(){if(!this.isRunning)return;let e=this.getNextDelay();this.timerId=setTimeout(()=>this.poll(),e);}async poll(){if(this.isRunning)try{await this.config.onPoll(),this.onSuccess();}catch(e){this.onError(),this.logger?.warn("Poll failed",{error:e instanceof Error?e.message:"Unknown error"});}finally{this.scheduleNext();}}async pollNow(){this.timerId&&(clearTimeout(this.timerId),this.timerId=null),await this.poll();}reset(){this.consecutiveErrors=0,this.currentInterval=this.config.interval,this.isRunning&&(this.timerId&&clearTimeout(this.timerId),this.scheduleNext());}};var tt={reconnectInterval:3e3,maxReconnectAttempts:3,heartbeatInterval:3e4},x=class{config;logger;eventSource=null;state="disconnected";consecutiveFailures=0;reconnectTimer=null;heartbeatTimer=null;tokenRefreshTimer=null;lastHeartbeat=0;retryStreamingTimer=null;constructor(e){this.config={...tt,...e},this.logger=e.logger;}getState(){return this.state}isConnected(){return this.state==="connected"}connect(){this.state==="connected"||this.state==="connecting"||(this.setState("connecting"),this.initiateConnection());}disconnect(){this.cleanup(),this.setState("disconnected"),this.consecutiveFailures=0,this.logger?.debug("Streaming disconnected");}retryConnection(){this.state==="connected"||this.state==="connecting"||(this.consecutiveFailures=0,this.connect());}async initiateConnection(){try{let e=await this.fetchStreamToken();this.scheduleTokenRefresh(e.expiresIn*.8*1e3),this.createConnection(e.token);}catch(e){this.logger?.error("Failed to fetch stream token",{error:e instanceof Error?e.message:"Unknown error"}),this.handleConnectionFailure();}}async fetchStreamToken(){let e=`${this.config.baseUrl}/sdk/stream/token`;this.logger?.debug("Fetching stream token",{tokenUrl:e});let t=await fetch(e,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey}});if(!t.ok)throw new Error(`Failed to fetch stream token: ${t.status} ${t.statusText}`);return t.json()}scheduleTokenRefresh(e){this.clearTokenRefreshTimer(),this.tokenRefreshTimer=setTimeout(async()=>{this.tokenRefreshTimer=null;try{this.logger?.debug("Refreshing stream token");let t=await this.fetchStreamToken();this.scheduleTokenRefresh(t.expiresIn*.8*1e3),this.logger?.debug("Stream token refreshed successfully");}catch(t){this.logger?.warn("Failed to refresh stream token, reconnecting",{error:t instanceof Error?t.message:"Unknown error"}),this.cleanup(),this.connect();}},e);}clearTokenRefreshTimer(){this.tokenRefreshTimer&&(clearTimeout(this.tokenRefreshTimer),this.tokenRefreshTimer=null);}createConnection(e){try{let t=new URL(`${this.config.baseUrl}/sdk/stream`);t.searchParams.set("token",e),this.eventSource=new EventSource(t.toString()),this.eventSource.onopen=()=>{this.handleOpen();},this.eventSource.onmessage=r=>{this.handleMessage(r);},this.eventSource.onerror=r=>{this.handleError(r);},this.eventSource.addEventListener("flag_updated",r=>{this.handleFlagUpdated(r);}),this.eventSource.addEventListener("flag_deleted",r=>{this.handleFlagDeleted(r);}),this.eventSource.addEventListener("flags_reset",r=>{this.handleFlagsReset(r);}),this.eventSource.addEventListener("heartbeat",r=>{this.handleHeartbeat(r);}),this.eventSource.addEventListener("error",r=>{this.handleStreamError(r);});}catch(t){this.logger?.error("Failed to create EventSource",{error:t instanceof Error?t.message:"Unknown error"}),this.handleConnectionFailure();}}handleOpen(){this.setState("connected"),this.consecutiveFailures=0,this.lastHeartbeat=Date.now(),this.startHeartbeatMonitor(),this.logger?.info("Streaming connected");}handleMessage(e){try{let t=JSON.parse(e.data);this.dispatchEvent(t);}catch(t){this.logger?.warn("Failed to parse stream message",{error:t instanceof Error?t.message:"Unknown error"});}}handleFlagUpdated(e){try{let t=JSON.parse(e.data);this.logger?.debug("Flag updated via stream",{key:t.key}),this.config.onFlagUpdate(t);}catch(t){this.logger?.warn("Failed to parse flag_updated event",{error:t instanceof Error?t.message:"Unknown error"});}}handleFlagDeleted(e){try{let t=JSON.parse(e.data);this.logger?.debug("Flag deleted via stream",{key:t.key}),this.config.onFlagDelete(t.key);}catch(t){this.logger?.warn("Failed to parse flag_deleted event",{error:t instanceof Error?t.message:"Unknown error"});}}handleFlagsReset(e){try{let t=JSON.parse(e.data);this.logger?.debug("Flags reset via stream",{count:t.length}),this.config.onFlagsReset(t);}catch(t){this.logger?.warn("Failed to parse flags_reset event",{error:t instanceof Error?t.message:"Unknown error"});}}handleHeartbeat(e){this.lastHeartbeat=Date.now(),this.logger?.debug("Heartbeat received");}handleStreamError(e){try{if(e.data){let t=JSON.parse(e.data);switch(this.logger?.warn("SSE error event received",{code:t.code,message:t.message}),t.code){case "TOKEN_EXPIRED":this.logger?.info("Stream token expired, refreshing..."),this.cleanup(),this.connect();break;case "TOKEN_INVALID":this.logger?.error("Stream token invalid, re-authenticating..."),this.cleanup(),this.connect();break;case "SUBSCRIPTION_SUSPENDED":this.logger?.error("Subscription suspended",{message:t.message}),this.config.onSubscriptionError?.(t.message),this.cleanup(),this.setState("failed"),this.config.onFallbackToPolling();break;case "CONNECTION_LIMIT":this.logger?.warn("Connection limit reached, backing off..."),this.config.onConnectionLimitError?.(),this.handleConnectionFailure();break;case "STREAMING_UNAVAILABLE":this.logger?.warn("Streaming service unavailable, falling back to polling"),this.cleanup(),this.setState("failed"),this.config.onFallbackToPolling();break;default:this.logger?.warn("Unknown stream error code",{code:t.code}),this.handleConnectionFailure();}}}catch{this.logger?.debug("Non-JSON error event received");}}dispatchEvent(e){switch(e.type){case "flag_updated":this.config.onFlagUpdate(e.data);break;case "flag_deleted":this.config.onFlagDelete(e.data.key);break;case "flags_reset":this.config.onFlagsReset(e.data);break;case "heartbeat":this.lastHeartbeat=Date.now();break}}handleError(e){this.logger?.warn("Streaming error",{readyState:this.eventSource?.readyState}),this.eventSource?.readyState===EventSource.CLOSED&&this.handleConnectionFailure();}handleConnectionFailure(){this.cleanup(),this.consecutiveFailures++,this.consecutiveFailures>=this.config.maxReconnectAttempts?(this.setState("failed"),this.logger?.warn("Streaming failed, falling back to polling",{failures:this.consecutiveFailures}),this.config.onFallbackToPolling(),this.scheduleStreamingRetry()):(this.setState("reconnecting"),this.scheduleReconnect());}scheduleReconnect(){let e=this.getReconnectDelay();this.logger?.debug("Scheduling reconnect",{delay:e,attempt:this.consecutiveFailures}),this.reconnectTimer=setTimeout(()=>{this.reconnectTimer=null,this.connect();},e);}getReconnectDelay(){let e=this.config.reconnectInterval,t=Math.pow(2,this.consecutiveFailures-1),r=e*t;return Math.min(r,3e4)}scheduleStreamingRetry(){this.retryStreamingTimer=setTimeout(()=>{this.retryStreamingTimer=null,this.logger?.info("Retrying streaming connection"),this.retryConnection();},3e5);}startHeartbeatMonitor(){this.stopHeartbeatMonitor();let e=this.config.heartbeatInterval*1.5;this.heartbeatTimer=setInterval(()=>{let t=Date.now()-this.lastHeartbeat;t>this.config.heartbeatInterval*2&&(this.logger?.warn("Heartbeat timeout, reconnecting",{timeSinceLastHeartbeat:t}),this.handleConnectionFailure());},e);}stopHeartbeatMonitor(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null);}setState(e){this.state=e;}cleanup(){this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.reconnectTimer&&(clearTimeout(this.reconnectTimer),this.reconnectTimer=null),this.retryStreamingTimer&&(clearTimeout(this.retryStreamingTimer),this.retryStreamingTimer=null),this.clearTokenRefreshTimer(),this.stopHeartbeatMonitor();}};var Se={maxQueueSize:100,batchSize:10,flushInterval:3e4,maxRetries:3,retryDelay:1e3,retryBackoff:2,persistQueue:false,storageKey:"flagkit_events",enabledEventTypes:["*"],disabledEventTypes:[],sampleRate:1};var ae=["sdk_","srv_","cli_"];function Ae(n){return !n||typeof n!="string"?false:ae.some(e=>n.startsWith(e))}function _e(n,e){if(!n.apiKey)throw new d("INIT_MISSING_API_KEY","apiKey is required in FlagKitOptions");if(!Ae(n.apiKey))throw new d("INIT_INVALID_CONFIG",`Invalid API key format. API key must start with one of: ${ae.join(", ")}`);if(te(n.apiKey,e),n.localPort!==void 0&&ie())throw new v("SECURITY_LOCAL_PORT_IN_PRODUCTION","localPort cannot be used in production environments. This option is only for local development. See: https://docs.flagkit.dev/sdk/security#local-development");if(n.secondaryApiKey&&!Ae(n.secondaryApiKey))throw new d("INIT_INVALID_CONFIG",`Invalid secondary API key format. API key must start with one of: ${ae.join(", ")}`);if(n.pollingInterval!==void 0&&(typeof n.pollingInterval!="number"||n.pollingInterval<0))throw new d("INIT_INVALID_CONFIG","pollingInterval must be a positive number");if(n.timeout!==void 0&&(typeof n.timeout!="number"||n.timeout<0))throw new d("INIT_INVALID_CONFIG","timeout must be a positive number");if(n.retries!==void 0&&(typeof n.retries!="number"||n.retries<0))throw new d("INIT_INVALID_CONFIG","retries must be a non-negative number");if(n.cacheTTL!==void 0&&(typeof n.cacheTTL!="number"||n.cacheTTL<0))throw new d("INIT_INVALID_CONFIG","cacheTTL must be a positive number");if(n.keyRotationGracePeriod!==void 0&&(typeof n.keyRotationGracePeriod!="number"||n.keyRotationGracePeriod<0))throw new d("INIT_INVALID_CONFIG","keyRotationGracePeriod must be a positive number")}function oe(n){return typeof n=="string"&&n.length>0&&n.length<=256}function Ne(n){if(n==null)return true;if(typeof n!="object")return false;let e=n;return !(e.userId!==void 0&&typeof e.userId!="string"||e.userKey!==void 0&&typeof e.userKey!="string"||e.email!==void 0&&typeof e.email!="string"||e.name!==void 0&&typeof e.name!="string"||e.country!==void 0&&typeof e.country!="string"||e.ip!==void 0&&typeof e.ip!="string"||e.userAgent!==void 0&&typeof e.userAgent!="string"||e.anonymous!==void 0&&typeof e.anonymous!="boolean"||e.custom!==void 0&&typeof e.custom!="object"||e.privateAttributes!==void 0&&(!Array.isArray(e.privateAttributes)||!e.privateAttributes.every(t=>typeof t=="string")))}function xe(n){return typeof n=="string"&&n.length>0&&n.length<=128&&/^[a-zA-Z][a-zA-Z0-9_.-]*$/.test(n)}function we(n){if(n==null)return true;if(typeof n!="object"||Array.isArray(n))return false;try{return JSON.stringify(n),!0}catch{return false}}var M=class{queue=[];httpClient;config;logger;sessionId;sdkVersion;environmentId;flushTimer=null;isFlushing=false;unloadHandler=null;constructor(e){this.httpClient=e.httpClient,this.logger=e.logger,this.sessionId=e.sessionId,this.environmentId=e.environmentId,this.sdkVersion=e.sdkVersion,this.config={...Se,...e.config},u()&&this.setupUnloadHandler(),this.startFlushTimer();}setEnvironmentId(e){this.environmentId=e;}track(e,t){if(!xe(e)){this.logger?.warn("Invalid event type",{eventType:e});return}if(!we(t)){this.logger?.warn("Invalid event data",{eventType:e});return}if(!this.isEventTypeEnabled(e)||!this.shouldSample(e))return;let r={eventType:e,timestamp:ve(),sdkVersion:this.sdkVersion,sdkLanguage:"typescript",sessionId:this.sessionId,environmentId:this.environmentId,eventData:t};this.addToQueue(r);}async flush(){if(this.queue.length===0||this.isFlushing)return;this.isFlushing=true;let e=[...this.queue];this.queue=[];try{await this.sendEvents(e),this.logger?.debug("Events flushed",{count:e.length});}catch(t){let r=e.slice(0,this.config.maxQueueSize-this.queue.length);throw this.queue=[...r,...this.queue],this.logger?.warn("Failed to flush events",{error:t instanceof Error?t.message:"Unknown error",requeued:r.length}),t}finally{this.isFlushing=false;}}getQueuedEvents(){return [...this.queue]}clearQueue(){this.queue=[],this.logger?.debug("Event queue cleared");}getQueueSize(){return this.queue.length}stop(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.unloadHandler&&u()&&(window.removeEventListener("beforeunload",this.unloadHandler),this.unloadHandler=null);}addToQueue(e){this.queue.length>=this.config.maxQueueSize&&(this.queue.shift(),this.logger?.warn("Event queue full, dropping oldest event")),this.queue.push(e),this.logger?.debug("Event queued",{eventType:e.eventType}),this.queue.length>=this.config.batchSize&&this.flush();}async sendEvents(e){e.length!==0&&await this.httpClient.post("/sdk/events/batch",{events:e});}isEventTypeEnabled(e){return this.config.disabledEventTypes.includes(e)?false:!!(this.config.enabledEventTypes.includes("*")||this.config.enabledEventTypes.includes(e))}shouldSample(e){return this.config.sampleRate>=1?true:this.config.sampleRate<=0?false:Math.random()<this.config.sampleRate}startFlushTimer(){this.flushTimer||(this.flushTimer=setInterval(()=>{this.flush();},this.config.flushInterval));}setupUnloadHandler(){this.unloadHandler=()=>{this.queue.length>0&&this.httpClient.sendBeacon("/sdk/events/batch",{events:this.queue})&&(this.queue=[]);},window.addEventListener("beforeunload",this.unloadHandler);}};var Oe={debug:0,info:1,warn:2,error:3,none:4},w=class{prefix;minLevel;constructor(e){this.prefix=e?.prefix??"[FlagKit]",this.minLevel=e?.level??"warn";}shouldLog(e){return Oe[e]>=Oe[this.minLevel]}formatMessage(e,t){return `${new Date().toISOString()} ${this.prefix} ${e.toUpperCase()}: ${t}`}debug(e,t){if(this.shouldLog("debug")){let r=this.formatMessage("debug",e);t?console.debug(r,t):console.debug(r);}}info(e,t){if(this.shouldLog("info")){let r=this.formatMessage("info",e);t?console.info(r,t):console.info(r);}}warn(e,t){if(this.shouldLog("warn")){let r=this.formatMessage("warn",e);t?console.warn(r,t):console.warn(r);}}error(e,t){if(this.shouldLog("error")){let r=this.formatMessage("error",e);t?console.error(r,t):console.error(r);}}},le=class{debug(){}info(){}warn(){}error(){}};function ce(n){return n?.logger?n.logger:n?.debug?new w({level:"debug"}):new w({level:"warn"})}function Fe(n){if(!n||typeof n!="string")return null;let e=n.trim();if(e.length===0)return null;let r=(e.startsWith("v")||e.startsWith("V")?e.slice(1):e).match(/^(\d+)\.(\d+)\.(\d+)/);if(!r)return null;let i=parseInt(r[1],10),s=parseInt(r[2],10),a=parseInt(r[3],10);return !Number.isSafeInteger(i)||!Number.isSafeInteger(s)||!Number.isSafeInteger(a)||i<0||s<0||a<0?null:{major:i,minor:s,patch:a}}function rt(n,e){let t=Fe(n),r=Fe(e);return !t||!r?0:t.major!==r.major?t.major-r.major:t.minor!==r.minor?t.minor-r.minor:t.patch-r.patch}function O(n,e){return rt(n,e)<0}var F=class{config;cache;contextManager;httpClient;eventQueue;logger;sessionId;pollingManager=null;streamingManager=null;readyPromise=null;isReadyFlag=false;isClosedFlag=false;lastUpdateTime=null;isStreamingActive=false;constructor(e){this.logger=ce({logger:e.logger,debug:e.debug}),_e(e,this.logger),this.config={apiKey:e.apiKey,pollingInterval:e.pollingInterval??3e4,enablePolling:e.enablePolling??true,cacheEnabled:e.cacheEnabled??true,cacheTTL:e.cacheTTL??3e5,offline:e.offline??false,timeout:e.timeout??5e3,retries:e.retries??3,logger:this.logger,bootstrap:e.bootstrap??{},bootstrapVerification:{enabled:e.bootstrapVerification?.enabled??true,maxAge:e.bootstrapVerification?.maxAge??864e5,onFailure:e.bootstrapVerification?.onFailure??"warn"},persistCache:e.persistCache??false,cacheStorageKey:e.cacheStorageKey??"flagkit_cache",onReady:e.onReady,onError:e.onError,onUpdate:e.onUpdate,onUsageUpdate:e.onUsageUpdate,debug:e.debug??false,localPort:e.localPort,secondaryApiKey:e.secondaryApiKey,keyRotationGracePeriod:e.keyRotationGracePeriod??3e5,strictPIIMode:e.strictPIIMode??false,evaluationJitter:{enabled:e.evaluationJitter?.enabled??false,minMs:e.evaluationJitter?.minMs??5,maxMs:e.evaluationJitter?.maxMs??15},errorSanitization:{enabled:e.errorSanitization?.enabled??true,preserveOriginal:e.errorSanitization?.preserveOriginal??false},streaming:{enabled:e.streaming?.enabled??true,reconnectInterval:e.streaming?.reconnectInterval??3e3,maxReconnectAttempts:e.streaming?.maxReconnectAttempts??3,heartbeatInterval:e.streaming?.heartbeatInterval??3e4}},this.sessionId=me(),this.cache=new k({ttl:this.config.cacheTTL,logger:this.logger}),this.contextManager=new D(this.logger),this.httpClient=new N({baseUrl:se(this.config.localPort),apiKey:this.config.apiKey,secondaryApiKey:this.config.secondaryApiKey,keyRotationGracePeriod:this.config.keyRotationGracePeriod,timeout:this.config.timeout,retry:{maxAttempts:this.config.retries},circuitBreaker:{},logger:this.logger,enableRequestSigning:true,onUsageUpdate:e.onUsageUpdate}),this.eventQueue=new M({httpClient:this.httpClient,logger:this.logger,sessionId:this.sessionId,environmentId:"",sdkVersion:h}),this.applyBootstrap(),this.logger.info("FlagKit client created",{offline:this.config.offline});}async initialize(){return this.readyPromise?this.readyPromise:(this.readyPromise=this.doInitialize(),this.readyPromise)}async doInitialize(){if(this.config.offline){this.logger.info("Offline mode enabled, skipping initialization"),this.isReadyFlag=true,this.config.onReady?.();return}try{this.logger.debug("Initializing SDK");let t=(await this.httpClient.get("/sdk/init")).data;this.eventQueue.setEnvironmentId(t.environmentId),this.checkVersionMetadata(t),this.cache.setMany(t.flags,this.config.cacheTTL),this.lastUpdateTime=t.serverTime,this.config.streaming.enabled?this.startStreaming():this.config.enablePolling&&this.startPolling(t.pollingIntervalSeconds*1e3),this.isReadyFlag=!0,this.logger.info("SDK initialized",{flagCount:t.flags.length,environment:t.environment}),this.config.onReady?.();}catch(e){let t=e instanceof f?e:new d("INIT_FAILED",e instanceof Error?e.message:"Unknown error");throw this.logger.error("SDK initialization failed",{error:t.message}),this.config.onError?.(t),this.isReadyFlag=true,this.config.onReady?.(),t}}isReady(){return this.isReadyFlag}async waitForReady(){if(!this.isReadyFlag&&this.readyPromise)try{await this.readyPromise;}catch{}}async getBooleanValue(e,t,r){return (await this.evaluateFlag(e,t,r,"boolean")).value}async getStringValue(e,t,r){return (await this.evaluateFlag(e,t,r,"string")).value}async getNumberValue(e,t,r){return (await this.evaluateFlag(e,t,r,"number")).value}async getJsonValue(e,t,r){return (await this.evaluateFlag(e,t,r,"json")).value}async evaluate(e,t){return this.evaluateFlag(e,null,t)}getBooleanValueSync(e,t){return this.evaluateFlagSync(e,t,"boolean").value}getStringValueSync(e,t){return this.evaluateFlagSync(e,t,"string").value}getNumberValueSync(e,t){return this.evaluateFlagSync(e,t,"number").value}getJsonValueSync(e,t){return this.evaluateFlagSync(e,t,"json").value}evaluateSync(e,t=false){return this.evaluateFlagSync(e,t,void 0)}async evaluateAll(e){let t={},r=this.getAllFlagKeys();for(let i of r)t[i]=await this.evaluate(i,e);return t}getBootstrapFlags(){return this.isBootstrapConfig(this.config.bootstrap)?this.config.bootstrap.flags:this.config.bootstrap}hasFlag(e){let t=this.getBootstrapFlags();return this.cache.has(e)||e in t}getAllFlagKeys(){let e=new Set(this.cache.getAllKeys()),t=this.getBootstrapFlags(),r=Object.keys(t);for(let i of r)e.add(i);return Array.from(e)}setContext(e){if(!Ne(e)){this.logger.warn("Invalid context provided to setContext");return}if(e.custom&&!e.privateAttributes?.length){let t=C(e.custom,"context");if(t.hasPII){if(this.config.strictPIIMode)throw new v("SECURITY_PII_DETECTED",`PII detected in context without privateAttributes: ${t.fields.join(", ")}. Either add these fields to privateAttributes or remove them from the context. See: https://docs.flagkit.dev/sdk/security#pii-handling`);this.logger.warn(t.message);}}this.contextManager.setContext(e);}getContext(){return this.contextManager.getContext()}clearContext(){this.contextManager.clearContext();}identify(e,t){if(t?.custom&&!t.privateAttributes?.length){let r=C(t.custom,"context");if(r.hasPII){if(this.config.strictPIIMode)throw new v("SECURITY_PII_DETECTED",`PII detected in identify attributes without privateAttributes: ${r.fields.join(", ")}. Either add these fields to privateAttributes or remove them. See: https://docs.flagkit.dev/sdk/security#pii-handling`);this.logger.warn(r.message);}}this.contextManager.identify(e,t),this.eventQueue.track("context.identified",{userId:e});}reset(){this.contextManager.reset(),this.eventQueue.track("context.reset");}track(e,t){if(t){let r=C(t,"event");if(r.hasPII){if(this.config.strictPIIMode)throw new v("SECURITY_PII_DETECTED",`PII detected in event data: ${r.fields.join(", ")}. Remove sensitive data from events before tracking. See: https://docs.flagkit.dev/sdk/security#pii-handling`);this.logger.warn(r.message);}}this.eventQueue.track(e,t);}async flush(){await this.eventQueue.flush();}async refresh(){if(!(this.config.offline||this.isClosedFlag))try{let e=this.lastUpdateTime??new Date(Date.now()-36e5).toISOString(),t=await this.httpClient.get(`/sdk/updates?since=${encodeURIComponent(e)}`);t.data.flags.length>0&&(this.cache.setMany(t.data.flags),this.lastUpdateTime=t.data.checkedAt,this.logger.debug("Flags refreshed",{count:t.data.flags.length}),this.config.onUpdate?.(t.data.flags));}catch(e){this.logger.warn("Failed to refresh flags",{error:e instanceof Error?e.message:"Unknown error"});}}async close(){if(!this.isClosedFlag){this.isClosedFlag=true,this.logger.debug("Closing SDK"),this.streamingManager?.disconnect(),this.streamingManager=null,this.isStreamingActive=false,this.pollingManager?.stop(),this.pollingManager=null;try{await this.eventQueue.flush();}catch(e){this.logger.warn("Failed to flush events on close",{error:e instanceof Error?e.message:"Unknown error"});}this.logger.info("SDK closed");}}evaluateFlagSync(e,t,r){if(!oe(e))return this.logger.warn("Invalid flag key",{key:e}),I(e,t,"DEFAULT");let i=this.cache.get(e);if(i)return r&&i.flagType!==r?(this.logger.warn(`Flag type mismatch: expected ${r}, got ${i.flagType}`,{key:e}),I(e,t,"EVALUATION_ERROR")):{flagKey:e,value:i.value,enabled:i.enabled,reason:"CACHED",version:i.version,timestamp:new Date};let s=this.cache.getStale(e);if(s)return this.logger.debug("Using stale cached value",{key:e}),{flagKey:e,value:s.value,enabled:s.enabled,reason:"STALE_CACHE",version:s.version,timestamp:new Date};let a=this.getBootstrapFlags();return e in a?(this.logger.debug("Using bootstrap value",{key:e}),{flagKey:e,value:a[e],enabled:true,reason:"BOOTSTRAP",version:0,timestamp:new Date}):I(e,t,"DEFAULT")}async evaluateFlag(e,t,r,i){if(this.config.evaluationJitter.enabled){let{minMs:c,maxMs:l}=this.config.evaluationJitter,g=c+Math.random()*(l-c);await new Promise(y=>setTimeout(y,g));}if(!oe(e))return this.logger.warn("Invalid flag key",{key:e}),I(e,t,"DEFAULT");let s=this.cache.get(e);if(s)return i&&s.flagType!==i?(this.logger.warn(`Flag type mismatch: expected ${i}, got ${s.flagType}`,{key:e}),I(e,t,"EVALUATION_ERROR")):{flagKey:e,value:s.value,enabled:s.enabled,reason:"CACHED",version:s.version,timestamp:new Date};let a=this.cache.getStale(e);if(a)return this.logger.debug("Using stale cached value",{key:e}),{flagKey:e,value:a.value,enabled:a.enabled,reason:"STALE_CACHE",version:a.version,timestamp:new Date};let o=this.getBootstrapFlags();if(e in o){let c=o[e];return this.logger.debug("Using bootstrap value",{key:e}),I(e,c,"BOOTSTRAP")}return this.logger.debug("Flag not found, using default",{key:e}),I(e,t,"FLAG_NOT_FOUND")}isBootstrapConfig(e){return typeof e=="object"&&e!==null&&"flags"in e&&typeof e.flags=="object"}applyBootstrap(){this.applyBootstrapAsync().catch(e=>{this.logger.error("Failed to apply bootstrap",{error:e instanceof Error?e.message:"Unknown error"});});}async applyBootstrapAsync(){let e=this.config.bootstrap,t;if(this.isBootstrapConfig(e)){let r=e;if(t=r.flags,r.signature&&this.config.bootstrapVerification.enabled){let i=await Ce(r,this.config.apiKey,this.config.bootstrapVerification);if(i.valid)this.logger.debug("Bootstrap signature verified successfully");else {let s=`Bootstrap verification failed: ${i.error}`;switch(this.config.bootstrapVerification.onFailure){case "error":throw this.logger.error(s),new v("SECURITY_BOOTSTRAP_VERIFICATION_FAILED",s);case "warn":this.logger.warn(s);break;}}}}else t=e;for(let[r,i]of Object.entries(t)){let s={key:r,value:i,enabled:true,version:0,flagType:this.inferFlagType(i),lastModified:new Date().toISOString()};this.cache.set(r,s,1/0);}}inferFlagType(e){return typeof e=="boolean"?"boolean":typeof e=="string"?"string":typeof e=="number"?"number":"json"}startPolling(e){this.pollingManager||(this.pollingManager=new K({interval:Math.max(e,this.config.pollingInterval),onPoll:()=>this.refresh(),logger:this.logger}),this.pollingManager.start());}startStreaming(){if(this.streamingManager)return;let e=se(this.config.localPort);this.streamingManager=new x({baseUrl:e,apiKey:this.config.apiKey,reconnectInterval:this.config.streaming.reconnectInterval,maxReconnectAttempts:this.config.streaming.maxReconnectAttempts,heartbeatInterval:this.config.streaming.heartbeatInterval,logger:this.logger,onFlagUpdate:t=>this.handleStreamFlagUpdate(t),onFlagDelete:t=>this.handleStreamFlagDelete(t),onFlagsReset:t=>this.handleStreamFlagsReset(t),onFallbackToPolling:()=>this.handleStreamingFallback()}),this.streamingManager.connect(),this.isStreamingActive=true,this.logger.info("Streaming started for real-time flag updates");}handleStreamFlagUpdate(e){this.cache.set(e.key,e),this.logger.debug("Flag updated via streaming",{key:e.key}),this.config.onUpdate?.([e]);}handleStreamFlagDelete(e){this.cache.delete(e),this.logger.debug("Flag deleted via streaming",{key:e});}handleStreamFlagsReset(e){this.cache.clear(),this.cache.setMany(e,this.config.cacheTTL),this.logger.debug("Flags reset via streaming",{count:e.length}),this.config.onUpdate?.(e);}handleStreamingFallback(){this.isStreamingActive=false,this.logger.warn("Streaming failed, falling back to polling"),this.config.enablePolling&&!this.pollingManager&&this.startPolling(this.config.pollingInterval);}isStreaming(){return this.isStreamingActive&&this.streamingManager?.isConnected()===true}checkVersionMetadata(e){let t=e.metadata;t&&(t.deprecationWarning&&this.logger.warn(`[FlagKit] Deprecation Warning: ${t.deprecationWarning}`),t.sdkVersionMin&&O(h,t.sdkVersionMin)&&this.logger.error(`[FlagKit] SDK version ${h} is below minimum required version ${t.sdkVersionMin}. Some features may not work correctly. Please upgrade the SDK.`),t.sdkVersionRecommended&&O(h,t.sdkVersionRecommended)&&this.logger.warn(`[FlagKit] SDK version ${h} is below recommended version ${t.sdkVersionRecommended}. Consider upgrading for the best experience.`),t.sdkVersionLatest&&O(h,t.sdkVersionLatest)&&(!t.sdkVersionRecommended||!O(h,t.sdkVersionRecommended))&&this.logger.info(`[FlagKit] SDK version ${h} - a newer version ${t.sdkVersionLatest} is available.`));}};var P=class n{static instance=null;static initPromise=null;static async initialize(e){if(n.instance)throw new d("INIT_ALREADY_INITIALIZED","FlagKit is already initialized. Call FlagKit.reset() first to reinitialize.");if(n.initPromise)return n.initPromise;n.initPromise=n.doInitialize(e);try{return await n.initPromise}finally{n.initPromise=null;}}static getInstance(){if(!n.instance)throw new Error("FlagKit is not initialized. Call FlagKit.initialize() first.");return n.instance}static isInitialized(){return n.instance!==null}static async reset(){n.instance&&(await n.instance.close(),n.instance=null),n.initPromise=null;}static async doInitialize(e){let t=new F(e);try{await t.initialize();}catch{}return n.instance=t,t}};var ge=class{prefix;available=null;constructor(e="flagkit_"){this.prefix=e;}get(e){if(!this.isAvailable())return null;try{return localStorage.getItem(this.prefixKey(e))}catch{return null}}set(e,t){if(this.isAvailable())try{localStorage.setItem(this.prefixKey(e),t);}catch{}}remove(e){if(this.isAvailable())try{localStorage.removeItem(this.prefixKey(e));}catch{}}clear(){if(this.isAvailable())try{let e=[];for(let t=0;t<localStorage.length;t++){let r=localStorage.key(t);r?.startsWith(this.prefix)&&e.push(r);}for(let t of e)localStorage.removeItem(t);}catch{}}isAvailable(){if(this.available!==null)return this.available;if(!u())return this.available=false,false;try{let e="__flagkit_test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),this.available=!0,!0}catch{return this.available=false,false}}prefixKey(e){return `${this.prefix}${e}`}};var ue=class{store=new Map;get(e){return this.store.get(e)??null}set(e,t){this.store.set(e,t);}remove(e){this.store.delete(e);}clear(){this.store.clear();}isAvailable(){return true}};var de=1,Pe=12,V=16,Le="FlagKit-v1-cache",fe=class{storage;apiKey;logger;derivedKey=null;keyDerivationPromise=null;cryptoAvailable=null;constructor(e){this.storage=e.storage,this.apiKey=e.apiKey,this.logger=e.logger,this.keyDerivationPromise=this.deriveKey().catch(t=>{this.logger?.warn("Failed to derive encryption key, storage will be unencrypted",{error:t instanceof Error?t.message:"Unknown error"});});}isCryptoAvailable(){if(this.cryptoAvailable!==null)return this.cryptoAvailable;if(u())this.cryptoAvailable=typeof crypto<"u"&&crypto.subtle!==void 0;else if(T())try{De("crypto"),this.cryptoAvailable=!0;}catch{this.cryptoAvailable=false;}else this.cryptoAvailable=typeof crypto<"u"&&crypto.subtle!==void 0;return this.cryptoAvailable}async deriveKey(){if(!this.isCryptoAvailable()){this.logger?.debug("Crypto not available, skipping key derivation");return}try{u()||typeof crypto<"u"&&crypto.subtle?await this.deriveKeyWebCrypto():T()&&await this.deriveKeyNode();}catch(e){this.logger?.warn("Key derivation failed",{error:e instanceof Error?e.message:"Unknown error"});}}async deriveKeyWebCrypto(){let e=new TextEncoder,t=await crypto.subtle.importKey("raw",e.encode(this.apiKey),"PBKDF2",false,["deriveKey"]);this.derivedKey=await crypto.subtle.deriveKey({name:"PBKDF2",salt:e.encode(Le),iterations:1e5,hash:"SHA-256"},t,{name:"AES-GCM",length:256},false,["encrypt","decrypt"]);}async deriveKeyNode(){let e=await import('crypto');this.derivedKey=e.pbkdf2Sync(this.apiKey,Le,1e5,32,"sha256");}async ensureKeyReady(){return this.keyDerivationPromise&&await this.keyDerivationPromise,this.derivedKey!==null}async encrypt(e){if(!await this.ensureKeyReady())return null;try{return u()||typeof crypto<"u"&&crypto.subtle?this.encryptWebCrypto(e):T()?this.encryptNode(e):null}catch(t){return this.logger?.warn("Encryption failed",{error:t instanceof Error?t.message:"Unknown error"}),null}}async encryptWebCrypto(e){let t=new TextEncoder,r=crypto.getRandomValues(new Uint8Array(Pe)),i=t.encode(e),s=await crypto.subtle.encrypt({name:"AES-GCM",iv:r.buffer,tagLength:V*8},this.derivedKey,i.buffer),a=new Uint8Array(s),o=a.slice(0,-V),c=a.slice(-V),l={iv:this.arrayToBase64(r),data:this.arrayToBase64(o),tag:this.arrayToBase64(c),version:de};return JSON.stringify(l)}async encryptNode(e){let t=await import('crypto'),r=t.randomBytes(Pe),i=t.createCipheriv("aes-256-gcm",this.derivedKey,r),s=Buffer.concat([i.update(e,"utf8"),i.final()]),a=i.getAuthTag(),o={iv:r.toString("base64"),data:s.toString("base64"),tag:a.toString("base64"),version:de};return JSON.stringify(o)}async decrypt(e){if(!await this.ensureKeyReady())return null;try{let t=JSON.parse(e);return t.version!==de?(this.logger?.warn("Unsupported encryption version",{version:t.version}),null):u()||typeof crypto<"u"&&crypto.subtle?await this.decryptWebCrypto(t):T()?await this.decryptNode(t):null}catch(t){return this.logger?.warn("Decryption failed",{error:t instanceof Error?t.message:"Unknown error"}),null}}async decryptWebCrypto(e){let t=new TextDecoder,r=this.base64ToArray(e.iv),i=this.base64ToArray(e.data),s=this.base64ToArray(e.tag),a=new Uint8Array(i.length+s.length);a.set(i,0),a.set(s,i.length);let o=await crypto.subtle.decrypt({name:"AES-GCM",iv:r.buffer,tagLength:V*8},this.derivedKey,a.buffer);return t.decode(o)}async decryptNode(e){let t=await import('crypto'),r=Buffer.from(e.iv,"base64"),i=Buffer.from(e.data,"base64"),s=Buffer.from(e.tag,"base64"),a=t.createDecipheriv("aes-256-gcm",this.derivedKey,r);return a.setAuthTag(s),Buffer.concat([a.update(i),a.final()]).toString("utf8")}arrayToBase64(e){if(typeof Buffer<"u")return Buffer.from(e).toString("base64");let t="";for(let r=0;r<e.length;r++)t+=String.fromCharCode(e[r]);return btoa(t)}base64ToArray(e){if(typeof Buffer<"u")return new Uint8Array(Buffer.from(e,"base64"));let t=atob(e),r=new Uint8Array(t.length);for(let i=0;i<t.length;i++)r[i]=t.charCodeAt(i);return r}get(e){let t=this.storage.get(e);if(!t)return null;try{let r=JSON.parse(t);if(r.version&&r.iv&&r.data&&r.tag)return null}catch{return t}return null}isEncryptedFormat(e){try{let t=JSON.parse(e);return typeof t=="object"&&t!==null&&"iv"in t&&"data"in t&&"tag"in t&&"version"in t}catch{return false}}async getAsync(e){let t=this.storage.get(e);return t?this.isEncryptedFormat(t)?this.decrypt(t):t:null}set(e,t){this.storage.set(e,t);}async setAsync(e,t){let r=await this.encrypt(t);r?this.storage.set(e,r):this.storage.set(e,t);}remove(e){this.storage.remove(e);}clear(){this.storage.clear();}isAvailable(){return this.storage.isAvailable()}isEncryptionAvailable(){return this.derivedKey!==null}};var ar=P;
|
|
2
|
+
exports.AuthenticationError=E;exports.CircuitBreaker=S;exports.CircuitOpenError=R;exports.CircuitState=ye;exports.ConsoleLogger=w;exports.DEFAULT_SECURITY_CONFIG=We;exports.EncryptedStorage=fe;exports.ErrorCodes=z;exports.EvaluationError=U;exports.FlagKit=P;exports.FlagKitClient=F;exports.FlagKitError=f;exports.HttpClient=N;exports.InitializationError=d;exports.LocalStorage=ge;exports.MemoryStorage=ue;exports.NetworkError=b;exports.NoopLogger=le;exports.SDK_VERSION=h;exports.SecurityError=v;exports.StreamingManager=x;exports.calculateBackoff=Ie;exports.checkForPotentialPII=C;exports.createErrorFromResponse=j;exports.createLogger=ce;exports.createRequestSignature=ne;exports.default=ar;exports.detectPotentialPII=ee;exports.generateHMACSHA256=_;exports.getKeyId=A;exports.isClientKey=qe;exports.isFlagKitError=Ve;exports.isPotentialPIIField=Te;exports.isProductionEnvironment=ie;exports.isRetryableCode=$;exports.isRetryableError=Q;exports.isServerKey=Re;exports.parseRetryAfter=X;exports.signPayload=re;exports.verifySignedPayload=Qe;exports.warnIfPotentialPII=$e;exports.warnIfServerKeyInBrowser=te;exports.withRetry=J;//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|