@gradual-so/sdk 0.8.0 → 0.8.2

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/dist/index.cjs CHANGED
@@ -1,3 +1,3 @@
1
- 'use strict';function b(n){let t=0;for(let e=0;e<n.length;e++){let a=n.charCodeAt(e);t=(t<<5)-t+a,t|=0;}return Math.abs(t)}function f(n,t,e){let a=t[e.bucketContextKind]?.[e.bucketAttributeKey],o=e.seed??"",i=`${n}:${o}:${String(a??"anonymous")}`;return b(i)%1e5}function p(n,t,e){let a=0,o;for(let r of n.variations)if(a+=r.weight,t<a){o=r;break}if(o||(o=n.variations.at(-1)),!o)return;let i=e[o.variationKey];if(i)return {variation:i,variationKey:o.variationKey,matchedWeight:o.weight,bucketValue:t}}function E(n,t){let{contextKind:e,attributeKey:a,operator:o,value:i}=n,r=t[e]?.[a];switch(o){case "equals":return r===i;case "not_equals":return r!==i;case "contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?r.includes(i):false;case "not_contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?!r.includes(i):true;case "starts_with":return typeof r=="string"&&typeof i=="string"?r.startsWith(i):false;case "ends_with":return typeof r=="string"&&typeof i=="string"?r.endsWith(i):false;case "greater_than":return typeof r=="number"&&typeof i=="number"?r>i:false;case "less_than":return typeof r=="number"&&typeof i=="number"?r<i:false;case "greater_than_or_equal":return typeof r=="number"&&typeof i=="number"?r>=i:false;case "less_than_or_equal":return typeof r=="number"&&typeof i=="number"?r<=i:false;case "in":return Array.isArray(i)?i.includes(r):false;case "not_in":return Array.isArray(i)?!i.includes(r):true;case "exists":return r!=null;case "not_exists":return r==null;default:return false}}function y(n,t){return n.every(e=>E(e,t))}function S(n,t){return y(n.conditions,t)}function R(n,t,e){switch(n.type){case "individual":return n.contextKind&&n.attributeKey&&n.attributeValue!==void 0?t[n.contextKind]?.[n.attributeKey]===n.attributeValue:false;case "rule":return n.conditions?y(n.conditions,t):false;case "segment":if(n.segmentKey){let a=e[n.segmentKey];if(a)return S(a,t)}return false;default:return false}}function x(n,t,e,a){if(n.rollout){let o=f(t,e,n.rollout);return p(n.rollout,o,a)}if(n.variationKey){let o=a[n.variationKey];if(o)return {variation:o,variationKey:n.variationKey,matchedWeight:1e5,bucketValue:0}}}function K(n,t){if(n.defaultRollout){let e=f(n.key,t,n.defaultRollout);return p(n.defaultRollout,e,n.variations)}if(n.defaultVariationKey){let e=n.variations[n.defaultVariationKey];if(e)return {variation:e,variationKey:n.defaultVariationKey,matchedWeight:1e5,bucketValue:0}}}function T(n){return {type:"rule_match",ruleId:n.id??"",ruleName:n.name}}function c(n){return {type:"percentage_rollout",percentage:n.matchedWeight/1e3,bucket:n.bucketValue}}function v(n,t,e){if(!n.enabled)return {value:n.variations[n.offVariationKey]?.value,variationKey:n.offVariationKey,reasons:[{type:"off"}]};let a=[...n.targets].sort((i,r)=>i.sortOrder-r.sortOrder);for(let i of a)if(R(i,t,e)){let r=x(i,n.key,t,n.variations);if(r){let s=[T(i)];return i.rollout&&s.push(c(r)),{value:r.variation.value,variationKey:r.variationKey,reasons:s,matchedTargetName:i.name}}}let o=K(n,t);if(o){let i=[];return n.defaultRollout&&i.push(c(o)),i.push({type:"default"}),{value:o.variation.value,variationKey:o.variationKey,reasons:i}}return {value:void 0,variationKey:void 0,reasons:[{type:"default"}]}}var w="0.8.0",k=globalThis,l=k.document,d=class{events=[];timer=null;options;onVisibilityChange=null;constructor(t){this.options=t,this.timer=setInterval(()=>this.flush(),this.options.flushIntervalMs),l?.addEventListener&&(this.onVisibilityChange=()=>{l.visibilityState==="hidden"&&this.flushBeacon();},l.addEventListener("visibilitychange",this.onVisibilityChange));}push(t){this.events.push(t),this.events.length>=this.options.maxBatchSize&&this.flush();}buildPayload(t){return {meta:{...this.options.meta,sdkVersion:w},events:t}}flush(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e)}).catch(()=>{});}flushBeacon(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e),keepalive:true}).catch(()=>{});}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.onVisibilityChange&&l?.removeEventListener&&l.removeEventListener("visibilitychange",this.onVisibilityChange),this.flush();}};var C="https://worker.gradual.so/api/v1";function O(){try{let n=globalThis,t=n.navigator;if(t&&t.product==="ReactNative")return "react-native";let e=n.window;if(e&&typeof e.document<"u")return "browser";if(n.process?.versions?.node)return "node";if(typeof globalThis<"u")return "edge"}catch{}return "unknown"}var I=O(),g=globalThis.process,V=typeof g?.hrtime?.bigint=="function";function m(){return V?g.hrtime.bigint():typeof performance<"u"?performance.now():Date.now()}function _(n){let t=m();return typeof n=="bigint"&&typeof t=="bigint"?Number((t-n)/1000n):Math.round((t-n)*1e3)}var h=class{apiKey;environment;baseUrl;initPromise;snapshot=null;identifiedContext={};updateListeners=new Set;eventBuffer=null;eventsEnabled;eventsFlushIntervalMs;eventsMaxBatchSize;sync;constructor(t){this.apiKey=t.apiKey,this.environment=t.environment,this.baseUrl=t.baseUrl??C,this.eventsEnabled=t.events?.enabled??true,this.eventsFlushIntervalMs=t.events?.flushIntervalMs??3e4,this.eventsMaxBatchSize=t.events?.maxBatchSize??100,this.initPromise=this.init(),this.sync={isEnabled:this.isEnabledSync.bind(this),get:this.getSync.bind(this),evaluate:this.evaluateSync.bind(this),track:this.trackSync.bind(this)};let e=t.polling?.enabled??true,a=t.polling?.intervalMs??1e4;e&&this.initPromise.then(()=>{setInterval(async()=>{try{let o=this.snapshot?.version;if(await this.refresh(),this.snapshot&&this.snapshot.version!==o)for(let i of this.updateListeners)i();}catch(o){console.warn("Gradual: Polling refresh failed",o);}},a);});}async init(){let t=await fetch(`${this.baseUrl}/sdk/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:this.apiKey})});if(!t.ok){let o=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to initialize - ${o.error??t.statusText}`)}let e=await t.json();if(!e.valid)throw new Error(`Gradual: Invalid API key - ${e.error??"Unknown error"}`);let a=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!a.ok){let o=await a.json().catch(()=>({}));throw new Error(`Gradual: Failed to fetch snapshot - ${o.error??a.statusText}`)}this.snapshot=await a.json(),this.eventsEnabled&&this.snapshot.meta&&(this.eventBuffer=new d({baseUrl:this.baseUrl,apiKey:this.apiKey,meta:{projectId:this.snapshot.meta.projectId,organizationId:this.snapshot.meta.organizationId,environmentId:this.snapshot.meta.environmentId,sdkPlatform:I},flushIntervalMs:this.eventsFlushIntervalMs,maxBatchSize:this.eventsMaxBatchSize}));}ensureReady(){if(!this.snapshot)throw new Error("Gradual: SDK not ready. Use await ready() or async methods.");return this.snapshot}mergeContext(t){let e={},a=new Set([...Object.keys(this.identifiedContext),...Object.keys(t?.context??{})]);for(let o of a)e[o]={...this.identifiedContext[o],...t?.context?.[o]};return e}evaluateRaw(t,e){let a=this.ensureReady();if(!a.flags)return {output:null,snapshot:a,durationUs:0};let o=a.flags[t];if(!o)return {output:null,snapshot:a,durationUs:0};let i=m(),r;try{r=v(o,e,a.segments??{});}catch(s){let u=s instanceof Error?s.message:String(s);r={value:void 0,variationKey:void 0,reasons:[{type:"error",detail:u}],errorDetail:u};}return {output:r,snapshot:a,durationUs:_(i)}}buildResult(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");return {key:t,value:e.value,variationKey:e.variationKey,reasons:e.reasons,ruleId:o?.ruleId,version:a,evaluatedAt:new Date().toISOString()}}evaluateAndTrack(t,e){let{output:a,snapshot:o,durationUs:i}=this.evaluateRaw(t,e);if(!a){this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],context:e,flagConfigVersion:o.version});return}return this.trackEvent({flagKey:t,variationKey:a.variationKey,value:a.value,reasons:a.reasons,context:e,matchedTargetName:a.matchedTargetName,flagConfigVersion:o.version,errorDetail:a.errorDetail,evaluationDurationUs:i}),a.value}trackEvent(t){if(!this.eventBuffer)return;let{context:e}=t,a=Object.keys(e),o={};for(let r of a)o[r]=Object.keys(e[r]??{});let i=a.length===0||a.every(r=>Object.keys(e[r]??{}).length===0);this.eventBuffer.push({flagKey:t.flagKey,variationKey:t.variationKey,value:t.value,reasons:t.reasons,evaluatedAt:t.evaluatedAt,ruleId:t.ruleId,contextKinds:a,contextKeys:o,timestamp:Date.now(),matchedTargetName:t.matchedTargetName,flagConfigVersion:t.flagConfigVersion,errorDetail:t.errorDetail,evaluationDurationUs:t.evaluationDurationUs,isAnonymous:i});}async ready(){await this.initPromise;}isReady(){return this.snapshot!==null}async isEnabled(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}async get(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}async evaluate(t,e){await this.initPromise;let a=this.mergeContext(e),{output:o,snapshot:i,durationUs:r}=this.evaluateRaw(t,a);if(!o){let u={key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()};return this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:u.reasons,evaluatedAt:u.evaluatedAt,context:a,flagConfigVersion:i.version}),u}let s=this.buildResult(t,o,i.version);return this.trackEvent({flagKey:t,variationKey:o.variationKey,value:o.value,reasons:o.reasons,evaluatedAt:s.evaluatedAt,ruleId:s.ruleId,context:a,matchedTargetName:o.matchedTargetName,flagConfigVersion:i.version,errorDetail:o.errorDetail,evaluationDurationUs:r}),s}isEnabledSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}getSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}evaluateSync(t,e){let a=this.mergeContext(e),{output:o,snapshot:i}=this.evaluateRaw(t,a);return o?this.buildResult(t,o,i.version):{key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()}}trackSync(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");this.trackEvent({flagKey:t,variationKey:e.variationKey,value:e.value,reasons:e.reasons,evaluatedAt:e.evaluatedAt,ruleId:e.ruleId,context:this.mergeContext({context:a}),matchedTargetName:o?.ruleName,flagConfigVersion:e.version});}identify(t){this.identifiedContext={...t};}reset(){this.identifiedContext={};}async refresh(){let t=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!t.ok){let e=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to refresh - ${e.error??t.statusText}`)}this.snapshot=await t.json();}getSnapshot(){return this.snapshot}onUpdate(t){return this.updateListeners.add(t),()=>this.updateListeners.delete(t)}close(){this.eventBuffer&&(this.eventBuffer.destroy(),this.eventBuffer=null);}};function A(n){return new h(n)}
1
+ 'use strict';function b(n){let t=0;for(let e=0;e<n.length;e++){let a=n.charCodeAt(e);t=(t<<5)-t+a,t|=0;}return Math.abs(t)}function f(n,t,e){let a=t[e.bucketContextKind]?.[e.bucketAttributeKey],o=e.seed??"",i=`${n}:${o}:${String(a??"anonymous")}`;return b(i)%1e5}function p(n,t,e){let a=0,o;for(let r of n.variations)if(a+=r.weight,t<a){o=r;break}if(o||(o=n.variations.at(-1)),!o)return;let i=e[o.variationKey];if(i)return {variation:i,variationKey:o.variationKey,matchedWeight:o.weight,bucketValue:t}}function E(n,t){let{contextKind:e,attributeKey:a,operator:o,value:i}=n,r=t[e]?.[a];switch(o){case "equals":return r===i;case "not_equals":return r!==i;case "contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?r.includes(i):false;case "not_contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?!r.includes(i):true;case "starts_with":return typeof r=="string"&&typeof i=="string"?r.startsWith(i):false;case "ends_with":return typeof r=="string"&&typeof i=="string"?r.endsWith(i):false;case "greater_than":return typeof r=="number"&&typeof i=="number"?r>i:false;case "less_than":return typeof r=="number"&&typeof i=="number"?r<i:false;case "greater_than_or_equal":return typeof r=="number"&&typeof i=="number"?r>=i:false;case "less_than_or_equal":return typeof r=="number"&&typeof i=="number"?r<=i:false;case "in":return Array.isArray(i)?i.includes(r):false;case "not_in":return Array.isArray(i)?!i.includes(r):true;case "exists":return r!=null;case "not_exists":return r==null;default:return false}}function y(n,t){return n.every(e=>E(e,t))}function S(n,t){return y(n.conditions,t)}function R(n,t,e){switch(n.type){case "individual":return n.contextKind&&n.attributeKey&&n.attributeValue!==void 0?t[n.contextKind]?.[n.attributeKey]===n.attributeValue:false;case "rule":return n.conditions?y(n.conditions,t):false;case "segment":if(n.segmentKey){let a=e[n.segmentKey];if(a)return S(a,t)}return false;default:return false}}function x(n,t,e,a){if(n.rollout){let o=f(t,e,n.rollout);return p(n.rollout,o,a)}if(n.variationKey){let o=a[n.variationKey];if(o)return {variation:o,variationKey:n.variationKey,matchedWeight:1e5,bucketValue:0}}}function K(n,t){if(n.defaultRollout){let e=f(n.key,t,n.defaultRollout);return p(n.defaultRollout,e,n.variations)}if(n.defaultVariationKey){let e=n.variations[n.defaultVariationKey];if(e)return {variation:e,variationKey:n.defaultVariationKey,matchedWeight:1e5,bucketValue:0}}}function T(n){return {type:"rule_match",ruleId:n.id??"",ruleName:n.name}}function c(n){return {type:"percentage_rollout",percentage:n.matchedWeight/1e3,bucket:n.bucketValue}}function v(n,t,e){if(!n.enabled)return {value:n.variations[n.offVariationKey]?.value,variationKey:n.offVariationKey,reasons:[{type:"off"}]};let a=[...n.targets].sort((i,r)=>i.sortOrder-r.sortOrder);for(let i of a)if(R(i,t,e)){let r=x(i,n.key,t,n.variations);if(r){let s=[T(i)];return i.rollout&&s.push(c(r)),{value:r.variation.value,variationKey:r.variationKey,reasons:s,matchedTargetName:i.name}}}let o=K(n,t);if(o){let i=[];return n.defaultRollout&&i.push(c(o)),i.push({type:"default"}),{value:o.variation.value,variationKey:o.variationKey,reasons:i}}return {value:void 0,variationKey:void 0,reasons:[{type:"default"}]}}var w="0.8.2",k=globalThis,l=k.document,d=class{events=[];timer=null;options;onVisibilityChange=null;constructor(t){this.options=t,this.timer=setInterval(()=>this.flush(),this.options.flushIntervalMs),l?.addEventListener&&(this.onVisibilityChange=()=>{l.visibilityState==="hidden"&&this.flushBeacon();},l.addEventListener("visibilitychange",this.onVisibilityChange));}push(t){this.events.push(t),this.events.length>=this.options.maxBatchSize&&this.flush();}buildPayload(t){return {meta:{...this.options.meta,sdkVersion:w},events:t}}flush(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e)}).catch(()=>{});}flushBeacon(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e),keepalive:true}).catch(()=>{});}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.onVisibilityChange&&l?.removeEventListener&&l.removeEventListener("visibilitychange",this.onVisibilityChange),this.flush();}};var C="https://worker.gradual.so/api/v1";function O(){try{let n=globalThis,t=n.navigator;if(t&&t.product==="ReactNative")return "react-native";let e=n.window;if(e&&typeof e.document<"u")return "browser";if(n.process?.versions?.node)return "node";if(typeof globalThis<"u")return "edge"}catch{}return "unknown"}var I=O(),g=globalThis.process,V=typeof g?.hrtime?.bigint=="function";function m(){return V?g.hrtime.bigint():typeof performance<"u"?performance.now():Date.now()}function _(n){let t=m();return typeof n=="bigint"&&typeof t=="bigint"?Number((t-n)/1000n):Math.round((t-n)*1e3)}var h=class{apiKey;environment;baseUrl;initPromise;snapshot=null;identifiedContext={};updateListeners=new Set;eventBuffer=null;eventsEnabled;eventsFlushIntervalMs;eventsMaxBatchSize;sync;constructor(t){this.apiKey=t.apiKey,this.environment=t.environment,this.baseUrl=t.baseUrl??C,this.eventsEnabled=t.events?.enabled??true,this.eventsFlushIntervalMs=t.events?.flushIntervalMs??3e4,this.eventsMaxBatchSize=t.events?.maxBatchSize??100,this.initPromise=this.init(),this.sync={isEnabled:this.isEnabledSync.bind(this),get:this.getSync.bind(this),evaluate:this.evaluateSync.bind(this),track:this.trackSync.bind(this)};let e=t.polling?.enabled??true,a=t.polling?.intervalMs??1e4;e&&this.initPromise.then(()=>{setInterval(async()=>{try{let o=this.snapshot?.version;if(await this.refresh(),this.snapshot&&this.snapshot.version!==o)for(let i of this.updateListeners)i();}catch(o){console.warn("Gradual: Polling refresh failed",o);}},a);});}async init(){let t=await fetch(`${this.baseUrl}/sdk/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:this.apiKey})});if(!t.ok){let o=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to initialize - ${o.error??t.statusText}`)}let e=await t.json();if(!e.valid)throw new Error(`Gradual: Invalid API key - ${e.error??"Unknown error"}`);let a=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!a.ok){let o=await a.json().catch(()=>({}));throw new Error(`Gradual: Failed to fetch snapshot - ${o.error??a.statusText}`)}this.snapshot=await a.json(),this.eventsEnabled&&this.snapshot.meta&&(this.eventBuffer=new d({baseUrl:this.baseUrl,apiKey:this.apiKey,meta:{projectId:this.snapshot.meta.projectId,organizationId:this.snapshot.meta.organizationId,environmentId:this.snapshot.meta.environmentId,sdkPlatform:I},flushIntervalMs:this.eventsFlushIntervalMs,maxBatchSize:this.eventsMaxBatchSize}));}ensureReady(){if(!this.snapshot)throw new Error("Gradual: SDK not ready. Use await ready() or async methods.");return this.snapshot}mergeContext(t){let e={},a=new Set([...Object.keys(this.identifiedContext),...Object.keys(t?.context??{})]);for(let o of a)e[o]={...this.identifiedContext[o],...t?.context?.[o]};return e}evaluateRaw(t,e){let a=this.ensureReady();if(!a.flags)return {output:null,snapshot:a,durationUs:0};let o=a.flags[t];if(!o)return {output:null,snapshot:a,durationUs:0};let i=m(),r;try{r=v(o,e,a.segments??{});}catch(s){let u=s instanceof Error?s.message:String(s);r={value:void 0,variationKey:void 0,reasons:[{type:"error",detail:u}],errorDetail:u};}return {output:r,snapshot:a,durationUs:_(i)}}buildResult(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");return {key:t,value:e.value,variationKey:e.variationKey,reasons:e.reasons,ruleId:o?.ruleId,version:a,evaluatedAt:new Date().toISOString()}}evaluateAndTrack(t,e){let{output:a,snapshot:o,durationUs:i}=this.evaluateRaw(t,e);if(!a){this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],context:e,flagConfigVersion:o.version});return}return this.trackEvent({flagKey:t,variationKey:a.variationKey,value:a.value,reasons:a.reasons,context:e,matchedTargetName:a.matchedTargetName,flagConfigVersion:o.version,errorDetail:a.errorDetail,evaluationDurationUs:i}),a.value}trackEvent(t){if(!this.eventBuffer)return;let{context:e}=t,a=Object.keys(e),o={};for(let r of a)o[r]=Object.keys(e[r]??{});let i=a.length===0||a.every(r=>Object.keys(e[r]??{}).length===0);this.eventBuffer.push({flagKey:t.flagKey,variationKey:t.variationKey,value:t.value,reasons:t.reasons,evaluatedAt:t.evaluatedAt,ruleId:t.ruleId,contextKinds:a,contextKeys:o,timestamp:Date.now(),matchedTargetName:t.matchedTargetName,flagConfigVersion:t.flagConfigVersion,errorDetail:t.errorDetail,evaluationDurationUs:t.evaluationDurationUs,isAnonymous:i});}async ready(){await this.initPromise;}isReady(){return this.snapshot!==null}async isEnabled(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}async get(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}async evaluate(t,e){await this.initPromise;let a=this.mergeContext(e),{output:o,snapshot:i,durationUs:r}=this.evaluateRaw(t,a);if(!o){let u={key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()};return this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:u.reasons,evaluatedAt:u.evaluatedAt,context:a,flagConfigVersion:i.version}),u}let s=this.buildResult(t,o,i.version);return this.trackEvent({flagKey:t,variationKey:o.variationKey,value:o.value,reasons:o.reasons,evaluatedAt:s.evaluatedAt,ruleId:s.ruleId,context:a,matchedTargetName:o.matchedTargetName,flagConfigVersion:i.version,errorDetail:o.errorDetail,evaluationDurationUs:r}),s}isEnabledSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}getSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}evaluateSync(t,e){let a=this.mergeContext(e),{output:o,snapshot:i}=this.evaluateRaw(t,a);return o?this.buildResult(t,o,i.version):{key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()}}trackSync(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");this.trackEvent({flagKey:t,variationKey:e.variationKey,value:e.value,reasons:e.reasons,evaluatedAt:e.evaluatedAt,ruleId:e.ruleId,context:this.mergeContext({context:a}),matchedTargetName:o?.ruleName,flagConfigVersion:e.version});}identify(t){this.identifiedContext={...t};}reset(){this.identifiedContext={};}async refresh(){let t=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!t.ok){let e=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to refresh - ${e.error??t.statusText}`)}this.snapshot=await t.json();}getSnapshot(){return this.snapshot}onUpdate(t){return this.updateListeners.add(t),()=>this.updateListeners.delete(t)}close(){this.eventBuffer&&(this.eventBuffer.destroy(),this.eventBuffer=null);}};function A(n){return new h(n)}
2
2
  exports.createGradual=A;exports.evaluateFlag=v;//# sourceMappingURL=index.cjs.map
3
3
  //# sourceMappingURL=index.cjs.map
package/dist/index.js CHANGED
@@ -1,3 +1,3 @@
1
- function b(n){let t=0;for(let e=0;e<n.length;e++){let a=n.charCodeAt(e);t=(t<<5)-t+a,t|=0;}return Math.abs(t)}function f(n,t,e){let a=t[e.bucketContextKind]?.[e.bucketAttributeKey],o=e.seed??"",i=`${n}:${o}:${String(a??"anonymous")}`;return b(i)%1e5}function p(n,t,e){let a=0,o;for(let r of n.variations)if(a+=r.weight,t<a){o=r;break}if(o||(o=n.variations.at(-1)),!o)return;let i=e[o.variationKey];if(i)return {variation:i,variationKey:o.variationKey,matchedWeight:o.weight,bucketValue:t}}function E(n,t){let{contextKind:e,attributeKey:a,operator:o,value:i}=n,r=t[e]?.[a];switch(o){case "equals":return r===i;case "not_equals":return r!==i;case "contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?r.includes(i):false;case "not_contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?!r.includes(i):true;case "starts_with":return typeof r=="string"&&typeof i=="string"?r.startsWith(i):false;case "ends_with":return typeof r=="string"&&typeof i=="string"?r.endsWith(i):false;case "greater_than":return typeof r=="number"&&typeof i=="number"?r>i:false;case "less_than":return typeof r=="number"&&typeof i=="number"?r<i:false;case "greater_than_or_equal":return typeof r=="number"&&typeof i=="number"?r>=i:false;case "less_than_or_equal":return typeof r=="number"&&typeof i=="number"?r<=i:false;case "in":return Array.isArray(i)?i.includes(r):false;case "not_in":return Array.isArray(i)?!i.includes(r):true;case "exists":return r!=null;case "not_exists":return r==null;default:return false}}function y(n,t){return n.every(e=>E(e,t))}function S(n,t){return y(n.conditions,t)}function R(n,t,e){switch(n.type){case "individual":return n.contextKind&&n.attributeKey&&n.attributeValue!==void 0?t[n.contextKind]?.[n.attributeKey]===n.attributeValue:false;case "rule":return n.conditions?y(n.conditions,t):false;case "segment":if(n.segmentKey){let a=e[n.segmentKey];if(a)return S(a,t)}return false;default:return false}}function x(n,t,e,a){if(n.rollout){let o=f(t,e,n.rollout);return p(n.rollout,o,a)}if(n.variationKey){let o=a[n.variationKey];if(o)return {variation:o,variationKey:n.variationKey,matchedWeight:1e5,bucketValue:0}}}function K(n,t){if(n.defaultRollout){let e=f(n.key,t,n.defaultRollout);return p(n.defaultRollout,e,n.variations)}if(n.defaultVariationKey){let e=n.variations[n.defaultVariationKey];if(e)return {variation:e,variationKey:n.defaultVariationKey,matchedWeight:1e5,bucketValue:0}}}function T(n){return {type:"rule_match",ruleId:n.id??"",ruleName:n.name}}function c(n){return {type:"percentage_rollout",percentage:n.matchedWeight/1e3,bucket:n.bucketValue}}function v(n,t,e){if(!n.enabled)return {value:n.variations[n.offVariationKey]?.value,variationKey:n.offVariationKey,reasons:[{type:"off"}]};let a=[...n.targets].sort((i,r)=>i.sortOrder-r.sortOrder);for(let i of a)if(R(i,t,e)){let r=x(i,n.key,t,n.variations);if(r){let s=[T(i)];return i.rollout&&s.push(c(r)),{value:r.variation.value,variationKey:r.variationKey,reasons:s,matchedTargetName:i.name}}}let o=K(n,t);if(o){let i=[];return n.defaultRollout&&i.push(c(o)),i.push({type:"default"}),{value:o.variation.value,variationKey:o.variationKey,reasons:i}}return {value:void 0,variationKey:void 0,reasons:[{type:"default"}]}}var w="0.8.0",k=globalThis,l=k.document,d=class{events=[];timer=null;options;onVisibilityChange=null;constructor(t){this.options=t,this.timer=setInterval(()=>this.flush(),this.options.flushIntervalMs),l?.addEventListener&&(this.onVisibilityChange=()=>{l.visibilityState==="hidden"&&this.flushBeacon();},l.addEventListener("visibilitychange",this.onVisibilityChange));}push(t){this.events.push(t),this.events.length>=this.options.maxBatchSize&&this.flush();}buildPayload(t){return {meta:{...this.options.meta,sdkVersion:w},events:t}}flush(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e)}).catch(()=>{});}flushBeacon(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e),keepalive:true}).catch(()=>{});}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.onVisibilityChange&&l?.removeEventListener&&l.removeEventListener("visibilitychange",this.onVisibilityChange),this.flush();}};var C="https://worker.gradual.so/api/v1";function O(){try{let n=globalThis,t=n.navigator;if(t&&t.product==="ReactNative")return "react-native";let e=n.window;if(e&&typeof e.document<"u")return "browser";if(n.process?.versions?.node)return "node";if(typeof globalThis<"u")return "edge"}catch{}return "unknown"}var I=O(),g=globalThis.process,V=typeof g?.hrtime?.bigint=="function";function m(){return V?g.hrtime.bigint():typeof performance<"u"?performance.now():Date.now()}function _(n){let t=m();return typeof n=="bigint"&&typeof t=="bigint"?Number((t-n)/1000n):Math.round((t-n)*1e3)}var h=class{apiKey;environment;baseUrl;initPromise;snapshot=null;identifiedContext={};updateListeners=new Set;eventBuffer=null;eventsEnabled;eventsFlushIntervalMs;eventsMaxBatchSize;sync;constructor(t){this.apiKey=t.apiKey,this.environment=t.environment,this.baseUrl=t.baseUrl??C,this.eventsEnabled=t.events?.enabled??true,this.eventsFlushIntervalMs=t.events?.flushIntervalMs??3e4,this.eventsMaxBatchSize=t.events?.maxBatchSize??100,this.initPromise=this.init(),this.sync={isEnabled:this.isEnabledSync.bind(this),get:this.getSync.bind(this),evaluate:this.evaluateSync.bind(this),track:this.trackSync.bind(this)};let e=t.polling?.enabled??true,a=t.polling?.intervalMs??1e4;e&&this.initPromise.then(()=>{setInterval(async()=>{try{let o=this.snapshot?.version;if(await this.refresh(),this.snapshot&&this.snapshot.version!==o)for(let i of this.updateListeners)i();}catch(o){console.warn("Gradual: Polling refresh failed",o);}},a);});}async init(){let t=await fetch(`${this.baseUrl}/sdk/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:this.apiKey})});if(!t.ok){let o=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to initialize - ${o.error??t.statusText}`)}let e=await t.json();if(!e.valid)throw new Error(`Gradual: Invalid API key - ${e.error??"Unknown error"}`);let a=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!a.ok){let o=await a.json().catch(()=>({}));throw new Error(`Gradual: Failed to fetch snapshot - ${o.error??a.statusText}`)}this.snapshot=await a.json(),this.eventsEnabled&&this.snapshot.meta&&(this.eventBuffer=new d({baseUrl:this.baseUrl,apiKey:this.apiKey,meta:{projectId:this.snapshot.meta.projectId,organizationId:this.snapshot.meta.organizationId,environmentId:this.snapshot.meta.environmentId,sdkPlatform:I},flushIntervalMs:this.eventsFlushIntervalMs,maxBatchSize:this.eventsMaxBatchSize}));}ensureReady(){if(!this.snapshot)throw new Error("Gradual: SDK not ready. Use await ready() or async methods.");return this.snapshot}mergeContext(t){let e={},a=new Set([...Object.keys(this.identifiedContext),...Object.keys(t?.context??{})]);for(let o of a)e[o]={...this.identifiedContext[o],...t?.context?.[o]};return e}evaluateRaw(t,e){let a=this.ensureReady();if(!a.flags)return {output:null,snapshot:a,durationUs:0};let o=a.flags[t];if(!o)return {output:null,snapshot:a,durationUs:0};let i=m(),r;try{r=v(o,e,a.segments??{});}catch(s){let u=s instanceof Error?s.message:String(s);r={value:void 0,variationKey:void 0,reasons:[{type:"error",detail:u}],errorDetail:u};}return {output:r,snapshot:a,durationUs:_(i)}}buildResult(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");return {key:t,value:e.value,variationKey:e.variationKey,reasons:e.reasons,ruleId:o?.ruleId,version:a,evaluatedAt:new Date().toISOString()}}evaluateAndTrack(t,e){let{output:a,snapshot:o,durationUs:i}=this.evaluateRaw(t,e);if(!a){this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],context:e,flagConfigVersion:o.version});return}return this.trackEvent({flagKey:t,variationKey:a.variationKey,value:a.value,reasons:a.reasons,context:e,matchedTargetName:a.matchedTargetName,flagConfigVersion:o.version,errorDetail:a.errorDetail,evaluationDurationUs:i}),a.value}trackEvent(t){if(!this.eventBuffer)return;let{context:e}=t,a=Object.keys(e),o={};for(let r of a)o[r]=Object.keys(e[r]??{});let i=a.length===0||a.every(r=>Object.keys(e[r]??{}).length===0);this.eventBuffer.push({flagKey:t.flagKey,variationKey:t.variationKey,value:t.value,reasons:t.reasons,evaluatedAt:t.evaluatedAt,ruleId:t.ruleId,contextKinds:a,contextKeys:o,timestamp:Date.now(),matchedTargetName:t.matchedTargetName,flagConfigVersion:t.flagConfigVersion,errorDetail:t.errorDetail,evaluationDurationUs:t.evaluationDurationUs,isAnonymous:i});}async ready(){await this.initPromise;}isReady(){return this.snapshot!==null}async isEnabled(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}async get(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}async evaluate(t,e){await this.initPromise;let a=this.mergeContext(e),{output:o,snapshot:i,durationUs:r}=this.evaluateRaw(t,a);if(!o){let u={key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()};return this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:u.reasons,evaluatedAt:u.evaluatedAt,context:a,flagConfigVersion:i.version}),u}let s=this.buildResult(t,o,i.version);return this.trackEvent({flagKey:t,variationKey:o.variationKey,value:o.value,reasons:o.reasons,evaluatedAt:s.evaluatedAt,ruleId:s.ruleId,context:a,matchedTargetName:o.matchedTargetName,flagConfigVersion:i.version,errorDetail:o.errorDetail,evaluationDurationUs:r}),s}isEnabledSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}getSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}evaluateSync(t,e){let a=this.mergeContext(e),{output:o,snapshot:i}=this.evaluateRaw(t,a);return o?this.buildResult(t,o,i.version):{key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()}}trackSync(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");this.trackEvent({flagKey:t,variationKey:e.variationKey,value:e.value,reasons:e.reasons,evaluatedAt:e.evaluatedAt,ruleId:e.ruleId,context:this.mergeContext({context:a}),matchedTargetName:o?.ruleName,flagConfigVersion:e.version});}identify(t){this.identifiedContext={...t};}reset(){this.identifiedContext={};}async refresh(){let t=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!t.ok){let e=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to refresh - ${e.error??t.statusText}`)}this.snapshot=await t.json();}getSnapshot(){return this.snapshot}onUpdate(t){return this.updateListeners.add(t),()=>this.updateListeners.delete(t)}close(){this.eventBuffer&&(this.eventBuffer.destroy(),this.eventBuffer=null);}};function A(n){return new h(n)}
1
+ function b(n){let t=0;for(let e=0;e<n.length;e++){let a=n.charCodeAt(e);t=(t<<5)-t+a,t|=0;}return Math.abs(t)}function f(n,t,e){let a=t[e.bucketContextKind]?.[e.bucketAttributeKey],o=e.seed??"",i=`${n}:${o}:${String(a??"anonymous")}`;return b(i)%1e5}function p(n,t,e){let a=0,o;for(let r of n.variations)if(a+=r.weight,t<a){o=r;break}if(o||(o=n.variations.at(-1)),!o)return;let i=e[o.variationKey];if(i)return {variation:i,variationKey:o.variationKey,matchedWeight:o.weight,bucketValue:t}}function E(n,t){let{contextKind:e,attributeKey:a,operator:o,value:i}=n,r=t[e]?.[a];switch(o){case "equals":return r===i;case "not_equals":return r!==i;case "contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?r.includes(i):false;case "not_contains":return typeof r=="string"&&typeof i=="string"||Array.isArray(r)?!r.includes(i):true;case "starts_with":return typeof r=="string"&&typeof i=="string"?r.startsWith(i):false;case "ends_with":return typeof r=="string"&&typeof i=="string"?r.endsWith(i):false;case "greater_than":return typeof r=="number"&&typeof i=="number"?r>i:false;case "less_than":return typeof r=="number"&&typeof i=="number"?r<i:false;case "greater_than_or_equal":return typeof r=="number"&&typeof i=="number"?r>=i:false;case "less_than_or_equal":return typeof r=="number"&&typeof i=="number"?r<=i:false;case "in":return Array.isArray(i)?i.includes(r):false;case "not_in":return Array.isArray(i)?!i.includes(r):true;case "exists":return r!=null;case "not_exists":return r==null;default:return false}}function y(n,t){return n.every(e=>E(e,t))}function S(n,t){return y(n.conditions,t)}function R(n,t,e){switch(n.type){case "individual":return n.contextKind&&n.attributeKey&&n.attributeValue!==void 0?t[n.contextKind]?.[n.attributeKey]===n.attributeValue:false;case "rule":return n.conditions?y(n.conditions,t):false;case "segment":if(n.segmentKey){let a=e[n.segmentKey];if(a)return S(a,t)}return false;default:return false}}function x(n,t,e,a){if(n.rollout){let o=f(t,e,n.rollout);return p(n.rollout,o,a)}if(n.variationKey){let o=a[n.variationKey];if(o)return {variation:o,variationKey:n.variationKey,matchedWeight:1e5,bucketValue:0}}}function K(n,t){if(n.defaultRollout){let e=f(n.key,t,n.defaultRollout);return p(n.defaultRollout,e,n.variations)}if(n.defaultVariationKey){let e=n.variations[n.defaultVariationKey];if(e)return {variation:e,variationKey:n.defaultVariationKey,matchedWeight:1e5,bucketValue:0}}}function T(n){return {type:"rule_match",ruleId:n.id??"",ruleName:n.name}}function c(n){return {type:"percentage_rollout",percentage:n.matchedWeight/1e3,bucket:n.bucketValue}}function v(n,t,e){if(!n.enabled)return {value:n.variations[n.offVariationKey]?.value,variationKey:n.offVariationKey,reasons:[{type:"off"}]};let a=[...n.targets].sort((i,r)=>i.sortOrder-r.sortOrder);for(let i of a)if(R(i,t,e)){let r=x(i,n.key,t,n.variations);if(r){let s=[T(i)];return i.rollout&&s.push(c(r)),{value:r.variation.value,variationKey:r.variationKey,reasons:s,matchedTargetName:i.name}}}let o=K(n,t);if(o){let i=[];return n.defaultRollout&&i.push(c(o)),i.push({type:"default"}),{value:o.variation.value,variationKey:o.variationKey,reasons:i}}return {value:void 0,variationKey:void 0,reasons:[{type:"default"}]}}var w="0.8.2",k=globalThis,l=k.document,d=class{events=[];timer=null;options;onVisibilityChange=null;constructor(t){this.options=t,this.timer=setInterval(()=>this.flush(),this.options.flushIntervalMs),l?.addEventListener&&(this.onVisibilityChange=()=>{l.visibilityState==="hidden"&&this.flushBeacon();},l.addEventListener("visibilitychange",this.onVisibilityChange));}push(t){this.events.push(t),this.events.length>=this.options.maxBatchSize&&this.flush();}buildPayload(t){return {meta:{...this.options.meta,sdkVersion:w},events:t}}flush(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e)}).catch(()=>{});}flushBeacon(){if(this.events.length===0)return;let t=this.events.splice(0,this.options.maxBatchSize),e=this.buildPayload(t);fetch(`${this.options.baseUrl}/sdk/evaluations`,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this.options.apiKey}`},body:JSON.stringify(e),keepalive:true}).catch(()=>{});}destroy(){this.timer&&(clearInterval(this.timer),this.timer=null),this.onVisibilityChange&&l?.removeEventListener&&l.removeEventListener("visibilitychange",this.onVisibilityChange),this.flush();}};var C="https://worker.gradual.so/api/v1";function O(){try{let n=globalThis,t=n.navigator;if(t&&t.product==="ReactNative")return "react-native";let e=n.window;if(e&&typeof e.document<"u")return "browser";if(n.process?.versions?.node)return "node";if(typeof globalThis<"u")return "edge"}catch{}return "unknown"}var I=O(),g=globalThis.process,V=typeof g?.hrtime?.bigint=="function";function m(){return V?g.hrtime.bigint():typeof performance<"u"?performance.now():Date.now()}function _(n){let t=m();return typeof n=="bigint"&&typeof t=="bigint"?Number((t-n)/1000n):Math.round((t-n)*1e3)}var h=class{apiKey;environment;baseUrl;initPromise;snapshot=null;identifiedContext={};updateListeners=new Set;eventBuffer=null;eventsEnabled;eventsFlushIntervalMs;eventsMaxBatchSize;sync;constructor(t){this.apiKey=t.apiKey,this.environment=t.environment,this.baseUrl=t.baseUrl??C,this.eventsEnabled=t.events?.enabled??true,this.eventsFlushIntervalMs=t.events?.flushIntervalMs??3e4,this.eventsMaxBatchSize=t.events?.maxBatchSize??100,this.initPromise=this.init(),this.sync={isEnabled:this.isEnabledSync.bind(this),get:this.getSync.bind(this),evaluate:this.evaluateSync.bind(this),track:this.trackSync.bind(this)};let e=t.polling?.enabled??true,a=t.polling?.intervalMs??1e4;e&&this.initPromise.then(()=>{setInterval(async()=>{try{let o=this.snapshot?.version;if(await this.refresh(),this.snapshot&&this.snapshot.version!==o)for(let i of this.updateListeners)i();}catch(o){console.warn("Gradual: Polling refresh failed",o);}},a);});}async init(){let t=await fetch(`${this.baseUrl}/sdk/init`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({apiKey:this.apiKey})});if(!t.ok){let o=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to initialize - ${o.error??t.statusText}`)}let e=await t.json();if(!e.valid)throw new Error(`Gradual: Invalid API key - ${e.error??"Unknown error"}`);let a=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!a.ok){let o=await a.json().catch(()=>({}));throw new Error(`Gradual: Failed to fetch snapshot - ${o.error??a.statusText}`)}this.snapshot=await a.json(),this.eventsEnabled&&this.snapshot.meta&&(this.eventBuffer=new d({baseUrl:this.baseUrl,apiKey:this.apiKey,meta:{projectId:this.snapshot.meta.projectId,organizationId:this.snapshot.meta.organizationId,environmentId:this.snapshot.meta.environmentId,sdkPlatform:I},flushIntervalMs:this.eventsFlushIntervalMs,maxBatchSize:this.eventsMaxBatchSize}));}ensureReady(){if(!this.snapshot)throw new Error("Gradual: SDK not ready. Use await ready() or async methods.");return this.snapshot}mergeContext(t){let e={},a=new Set([...Object.keys(this.identifiedContext),...Object.keys(t?.context??{})]);for(let o of a)e[o]={...this.identifiedContext[o],...t?.context?.[o]};return e}evaluateRaw(t,e){let a=this.ensureReady();if(!a.flags)return {output:null,snapshot:a,durationUs:0};let o=a.flags[t];if(!o)return {output:null,snapshot:a,durationUs:0};let i=m(),r;try{r=v(o,e,a.segments??{});}catch(s){let u=s instanceof Error?s.message:String(s);r={value:void 0,variationKey:void 0,reasons:[{type:"error",detail:u}],errorDetail:u};}return {output:r,snapshot:a,durationUs:_(i)}}buildResult(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");return {key:t,value:e.value,variationKey:e.variationKey,reasons:e.reasons,ruleId:o?.ruleId,version:a,evaluatedAt:new Date().toISOString()}}evaluateAndTrack(t,e){let{output:a,snapshot:o,durationUs:i}=this.evaluateRaw(t,e);if(!a){this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],context:e,flagConfigVersion:o.version});return}return this.trackEvent({flagKey:t,variationKey:a.variationKey,value:a.value,reasons:a.reasons,context:e,matchedTargetName:a.matchedTargetName,flagConfigVersion:o.version,errorDetail:a.errorDetail,evaluationDurationUs:i}),a.value}trackEvent(t){if(!this.eventBuffer)return;let{context:e}=t,a=Object.keys(e),o={};for(let r of a)o[r]=Object.keys(e[r]??{});let i=a.length===0||a.every(r=>Object.keys(e[r]??{}).length===0);this.eventBuffer.push({flagKey:t.flagKey,variationKey:t.variationKey,value:t.value,reasons:t.reasons,evaluatedAt:t.evaluatedAt,ruleId:t.ruleId,contextKinds:a,contextKeys:o,timestamp:Date.now(),matchedTargetName:t.matchedTargetName,flagConfigVersion:t.flagConfigVersion,errorDetail:t.errorDetail,evaluationDurationUs:t.evaluationDurationUs,isAnonymous:i});}async ready(){await this.initPromise;}isReady(){return this.snapshot!==null}async isEnabled(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}async get(t,e){await this.initPromise;let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}async evaluate(t,e){await this.initPromise;let a=this.mergeContext(e),{output:o,snapshot:i,durationUs:r}=this.evaluateRaw(t,a);if(!o){let u={key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()};return this.trackEvent({flagKey:t,variationKey:void 0,value:void 0,reasons:u.reasons,evaluatedAt:u.evaluatedAt,context:a,flagConfigVersion:i.version}),u}let s=this.buildResult(t,o,i.version);return this.trackEvent({flagKey:t,variationKey:o.variationKey,value:o.value,reasons:o.reasons,evaluatedAt:s.evaluatedAt,ruleId:s.ruleId,context:a,matchedTargetName:o.matchedTargetName,flagConfigVersion:i.version,errorDetail:o.errorDetail,evaluationDurationUs:r}),s}isEnabledSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return typeof a=="boolean"?a:false}getSync(t,e){let a=this.evaluateAndTrack(t,this.mergeContext(e));return a??e.fallback}evaluateSync(t,e){let a=this.mergeContext(e),{output:o,snapshot:i}=this.evaluateRaw(t,a);return o?this.buildResult(t,o,i.version):{key:t,value:void 0,variationKey:void 0,reasons:[{type:"error",detail:"FLAG_NOT_FOUND"}],version:i.version,evaluatedAt:new Date().toISOString()}}trackSync(t,e,a){let o=e.reasons.find(i=>i.type==="rule_match");this.trackEvent({flagKey:t,variationKey:e.variationKey,value:e.value,reasons:e.reasons,evaluatedAt:e.evaluatedAt,ruleId:e.ruleId,context:this.mergeContext({context:a}),matchedTargetName:o?.ruleName,flagConfigVersion:e.version});}identify(t){this.identifiedContext={...t};}reset(){this.identifiedContext={};}async refresh(){let t=await fetch(`${this.baseUrl}/sdk/snapshot?environment=${encodeURIComponent(this.environment)}`,{headers:{Authorization:`Bearer ${this.apiKey}`}});if(!t.ok){let e=await t.json().catch(()=>({}));throw new Error(`Gradual: Failed to refresh - ${e.error??t.statusText}`)}this.snapshot=await t.json();}getSnapshot(){return this.snapshot}onUpdate(t){return this.updateListeners.add(t),()=>this.updateListeners.delete(t)}close(){this.eventBuffer&&(this.eventBuffer.destroy(),this.eventBuffer=null);}};function A(n){return new h(n)}
2
2
  export{A as createGradual,v as evaluateFlag};//# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@gradual-so/sdk",
3
- "version": "0.8.0",
3
+ "version": "0.8.2",
4
4
  "description": "Gradual feature flag SDK for TypeScript and JavaScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",