@splitlab/js-client 0.1.0 → 0.1.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 +1 -1
- package/dist/index.js +1 -1
- package/dist/splitlab.min.js +1 -1
- package/package.json +4 -4
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var p=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var D=(n,e)=>{for(var t in e)p(n,t,{get:e[t],enumerable:!0})},z=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of A(e))!L.call(n,s)&&s!==t&&p(n,s,{get:()=>e[s],enumerable:!(i=O(e,s))||i.enumerable});return n};var M=n=>z(p({},"__esModule",{value:!0}),n);var $={};D($,{SplitLabClient:()=>y,hashToFloat:()=>w,murmurhash3:()=>g});module.exports=M($);function g(n,e=0){let t=e>>>0,i=n.length,s=i>>2,a=3432918353,r=461845907;for(let u=0;u<s;u++){let c=n.charCodeAt(u*4)&255|(n.charCodeAt(u*4+1)&255)<<8|(n.charCodeAt(u*4+2)&255)<<16|(n.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,a),c=c<<15|c>>>17,c=Math.imul(c,r),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=s*4,l=0;switch(i&3){case 3:l^=(n.charCodeAt(o+2)&255)<<16;case 2:l^=(n.charCodeAt(o+1)&255)<<8;case 1:l^=n.charCodeAt(o)&255,l=Math.imul(l,a),l=l<<15|l>>>17,l=Math.imul(l,r),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function w(n,e){return g(n,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",B=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],F=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function K(n){if(!n)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,s=null;if(/Safari/.test(n)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(n)){let o=n.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of B){let u=n.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of F){let u=n.match(o);if(u){i=l,s=u[1]?.replace(/_/g,".")||null;break}}let r="desktop";return/Mobi|Android.*Mobile|iPhone/.test(n)?r="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(n)&&(r="tablet"),{browser:e,browser_version:t,os:i,os_version:s,device_type:r}}function T(){if(!h)return null;let n=globalThis,e=n.navigator,t=n.location,i=n.document,s=n.screen,a=K(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:a.browser,browser_version:a.browser_version,os:a.os,os_version:a.os_version,device_type:a.device_type,screen_width:s?.width??null,screen_height:s?.height??null,viewport_width:n.innerWidth??null,viewport_height:n.innerHeight??null,language:e?.language??null,timezone:N()}}function N(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var j=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],C="__ot_utm";function x(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(C);if(i)return JSON.parse(i)}catch{}let n=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of j){let s=n.get(i);s&&(e[i]=s,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(C,JSON.stringify(e))}catch{}return e}var _="__ot_sid",m="__ot_sts";function E(n){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(_),s=Number(e.getItem(m)||"0");if(i&&t-s<n)return e.setItem(m,String(t)),i;let a=f();return e.setItem(_,a),e.setItem(m,String(t)),a}catch{return f()}}var R="__ot_did";function P(){if(!h)return f();try{let n=globalThis.localStorage;if(!n)return f();let e=n.getItem(R);if(e)return e;let t=f();return n.setItem(R,t),t}catch{return f()}}var I="__ot_ref";function U(){if(!h)return null;try{let n=globalThis.sessionStorage,e=n?.getItem(I);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return n?.setItem(I,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let n=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${n}-${e}`}var b=typeof globalThis<"u"&&typeof globalThis.document<"u",y=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??b,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=x()),this.config.captureContext&&(this.initialReferrer=U()),this.deviceId=P()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),b&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&b&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=T();if(i){for(let[s,a]of Object.entries(i))a!==null&&a!==""&&a!==void 0&&(t[s]=a);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,s]of Object.entries(this.utmParams))s&&(t[i]=s);this.config.trackSessions&&(t.session_id=E(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,s]of Object.entries(this.config.superProperties))s!==void 0&&(t[i]=s);if(e)for(let[i,s]of Object.entries(e))s!==void 0&&(t[i]=s);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,s=t.pushState.bind(t);t.pushState=(...o)=>{s(...o),this.onUrlChange(i),i=e.location?.href};let a=t.replaceState.bind(t);t.replaceState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",r),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=s,t.replaceState=a,e.removeEventListener("popstate",r)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},s={},a=this.config.attributes;for(let r of e.experiments){if(r.targeting_rules&&!this.evaluateRules(r.targeting_rules,a)){i[r.key]=null;continue}let o=g(r.key+":"+t);if(o%1e4/100>=r.traffic_percentage){i[r.key]=null;continue}let u=r.variants.reduce((v,k)=>v+k.weight,0),c=o%u,S=0,d=null;for(let v of r.variants)if(S+=v.weight,c<S){d=v.key;break}d||(d=r.variants[r.variants.length-1].key),i[r.key]=d}for(let r of e.flags){if(r.rules&&!this.evaluateRules(r.rules,a)){s[r.key]=!1;continue}let l=g(r.key+":"+t)%100;s[r.key]=l<r.rollout_percentage}return{experiments:i,flags:s}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=a=>{let r=t[a.attribute];if(r==null)return!1;switch(a.operator){case"is":return String(r)===String(a.value);case"is_not":return String(r)!==String(a.value);case"contains":return String(r).toLowerCase().includes(String(a.value).toLowerCase());case"not_contains":return!String(r).toLowerCase().includes(String(a.value).toLowerCase());case"gt":return Number(r)>Number(a.value);case"lt":return Number(r)<Number(a.value);case"gte":return Number(r)>=Number(a.value);case"lte":return Number(r)<=Number(a.value);case"in":return Array.isArray(a.value)&&a.value.map(String).includes(String(r));case"not_in":return Array.isArray(a.value)&&!a.value.map(String).includes(String(r));default:return!1}},s=a=>a.conditions.every(i);return e.match==="any"?e.groups.some(s):e.groups.every(s)}async fetchConfig(){let e={"Content-Type":"application/json","X-API-Key":this.config.apiKey};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let a=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${a}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let s=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,s))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,s){let a=s?this.config.ingestUrl:this.config.baseUrl,r=await fetch(`${a}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`SplitLab API error ${r.status}: ${o}`)}return r.json()}};0&&(module.exports={SplitLabClient,hashToFloat,murmurhash3});
|
|
1
|
+
"use strict";var p=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var D=(n,e)=>{for(var t in e)p(n,t,{get:e[t],enumerable:!0})},z=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of A(e))!L.call(n,s)&&s!==t&&p(n,s,{get:()=>e[s],enumerable:!(i=O(e,s))||i.enumerable});return n};var M=n=>z(p({},"__esModule",{value:!0}),n);var j={};D(j,{SplitLabClient:()=>y,hashToFloat:()=>w,murmurhash3:()=>g});module.exports=M(j);function g(n,e=0){let t=e>>>0,i=n.length,s=i>>2,a=3432918353,r=461845907;for(let u=0;u<s;u++){let c=n.charCodeAt(u*4)&255|(n.charCodeAt(u*4+1)&255)<<8|(n.charCodeAt(u*4+2)&255)<<16|(n.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,a),c=c<<15|c>>>17,c=Math.imul(c,r),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=s*4,l=0;switch(i&3){case 3:l^=(n.charCodeAt(o+2)&255)<<16;case 2:l^=(n.charCodeAt(o+1)&255)<<8;case 1:l^=n.charCodeAt(o)&255,l=Math.imul(l,a),l=l<<15|l>>>17,l=Math.imul(l,r),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function w(n,e){return g(n,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",B=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],F=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function N(n){if(!n)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,s=null;if(/Safari/.test(n)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(n)){let o=n.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of B){let u=n.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of F){let u=n.match(o);if(u){i=l,s=u[1]?.replace(/_/g,".")||null;break}}let r="desktop";return/Mobi|Android.*Mobile|iPhone/.test(n)?r="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(n)&&(r="tablet"),{browser:e,browser_version:t,os:i,os_version:s,device_type:r}}function T(){if(!h)return null;let n=globalThis,e=n.navigator,t=n.location,i=n.document,s=n.screen,a=N(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:a.browser,browser_version:a.browser_version,os:a.os,os_version:a.os_version,device_type:a.device_type,screen_width:s?.width??null,screen_height:s?.height??null,viewport_width:n.innerWidth??null,viewport_height:n.innerHeight??null,language:e?.language??null,timezone:$()}}function $(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var K=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],C="__ot_utm";function x(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(C);if(i)return JSON.parse(i)}catch{}let n=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of K){let s=n.get(i);s&&(e[i]=s,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(C,JSON.stringify(e))}catch{}return e}var _="__ot_sid",m="__ot_sts";function E(n){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(_),s=Number(e.getItem(m)||"0");if(i&&t-s<n)return e.setItem(m,String(t)),i;let a=f();return e.setItem(_,a),e.setItem(m,String(t)),a}catch{return f()}}var R="__ot_did";function P(){if(!h)return f();try{let n=globalThis.localStorage;if(!n)return f();let e=n.getItem(R);if(e)return e;let t=f();return n.setItem(R,t),t}catch{return f()}}var I="__ot_ref";function U(){if(!h)return null;try{let n=globalThis.sessionStorage,e=n?.getItem(I);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return n?.setItem(I,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let n=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${n}-${e}`}var b=typeof globalThis<"u"&&typeof globalThis.document<"u",y=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??b,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=x()),this.config.captureContext&&(this.initialReferrer=U()),this.deviceId=P()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),b&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&b&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=T();if(i){for(let[s,a]of Object.entries(i))a!==null&&a!==""&&a!==void 0&&(t[s]=a);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,s]of Object.entries(this.utmParams))s&&(t[i]=s);this.config.trackSessions&&(t.session_id=E(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,s]of Object.entries(this.config.superProperties))s!==void 0&&(t[i]=s);if(e)for(let[i,s]of Object.entries(e))s!==void 0&&(t[i]=s);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,s=t.pushState.bind(t);t.pushState=(...o)=>{s(...o),this.onUrlChange(i),i=e.location?.href};let a=t.replaceState.bind(t);t.replaceState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",r),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=s,t.replaceState=a,e.removeEventListener("popstate",r)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},s={},a=this.config.attributes;for(let r of e.experiments){if(r.targeting_rules&&!this.evaluateRules(r.targeting_rules,a)){i[r.key]=null;continue}let o=g(r.key+":"+t);if(o%1e4/100>=r.traffic_percentage){i[r.key]=null;continue}let u=r.variants.reduce((v,k)=>v+k.weight,0),c=o%u,S=0,d=null;for(let v of r.variants)if(S+=v.weight,c<S){d=v.key;break}d||(d=r.variants[r.variants.length-1].key),i[r.key]=d}for(let r of e.flags){if(r.rules&&!this.evaluateRules(r.rules,a)){s[r.key]=!1;continue}let l=g(r.key+":"+t)%100;s[r.key]=l<r.rollout_percentage}return{experiments:i,flags:s}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=a=>{let r=t[a.attribute];if(r==null)return!1;switch(a.operator){case"is":return String(r)===String(a.value);case"is_not":return String(r)!==String(a.value);case"contains":return String(r).toLowerCase().includes(String(a.value).toLowerCase());case"not_contains":return!String(r).toLowerCase().includes(String(a.value).toLowerCase());case"gt":return Number(r)>Number(a.value);case"lt":return Number(r)<Number(a.value);case"gte":return Number(r)>=Number(a.value);case"lte":return Number(r)<=Number(a.value);case"in":return Array.isArray(a.value)&&a.value.map(String).includes(String(r));case"not_in":return Array.isArray(a.value)&&!a.value.map(String).includes(String(r));default:return!1}},s=a=>a.conditions.every(i);return e.match==="any"?e.groups.some(s):e.groups.every(s)}async fetchConfig(){let e={};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config?key=${encodeURIComponent(this.config.apiKey)}`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let a=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${a}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let s=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,s))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,s){let a=s?this.config.ingestUrl:this.config.baseUrl,r=await fetch(`${a}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`SplitLab API error ${r.status}: ${o}`)}return r.json()}};0&&(module.exports={SplitLabClient,hashToFloat,murmurhash3});
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
function g(s,e=0){let t=e>>>0,i=s.length,a=i>>2,r=3432918353,n=461845907;for(let u=0;u<a;u++){let c=s.charCodeAt(u*4)&255|(s.charCodeAt(u*4+1)&255)<<8|(s.charCodeAt(u*4+2)&255)<<16|(s.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,r),c=c<<15|c>>>17,c=Math.imul(c,n),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=a*4,l=0;switch(i&3){case 3:l^=(s.charCodeAt(o+2)&255)<<16;case 2:l^=(s.charCodeAt(o+1)&255)<<8;case 1:l^=s.charCodeAt(o)&255,l=Math.imul(l,r),l=l<<15|l>>>17,l=Math.imul(l,n),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function U(s,e){return g(s,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",k=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],O=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function A(s){if(!s)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,a=null;if(/Safari/.test(s)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(s)){let o=s.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of k){let u=s.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of O){let u=s.match(o);if(u){i=l,a=u[1]?.replace(/_/g,".")||null;break}}let n="desktop";return/Mobi|Android.*Mobile|iPhone/.test(s)?n="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(s)&&(n="tablet"),{browser:e,browser_version:t,os:i,os_version:a,device_type:n}}function _(){if(!h)return null;let s=globalThis,e=s.navigator,t=s.location,i=s.document,a=s.screen,r=A(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:r.browser,browser_version:r.browser_version,os:r.os,os_version:r.os_version,device_type:r.device_type,screen_width:a?.width??null,screen_height:a?.height??null,viewport_width:s.innerWidth??null,viewport_height:s.innerHeight??null,language:e?.language??null,timezone:L()}}function L(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var D=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],y="__ot_utm";function R(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(y);if(i)return JSON.parse(i)}catch{}let s=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of D){let a=s.get(i);a&&(e[i]=a,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(y,JSON.stringify(e))}catch{}return e}var S="__ot_sid",p="__ot_sts";function I(s){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(S),a=Number(e.getItem(p)||"0");if(i&&t-a<s)return e.setItem(p,String(t)),i;let r=f();return e.setItem(S,r),e.setItem(p,String(t)),r}catch{return f()}}var w="__ot_did";function T(){if(!h)return f();try{let s=globalThis.localStorage;if(!s)return f();let e=s.getItem(w);if(e)return e;let t=f();return s.setItem(w,t),t}catch{return f()}}var C="__ot_ref";function x(){if(!h)return null;try{let s=globalThis.sessionStorage,e=s?.getItem(C);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return s?.setItem(C,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let s=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${s}-${e}`}var m=typeof globalThis<"u"&&typeof globalThis.document<"u",E=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??m,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=R()),this.config.captureContext&&(this.initialReferrer=x()),this.deviceId=T()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),m&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&m&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=_();if(i){for(let[a,r]of Object.entries(i))r!==null&&r!==""&&r!==void 0&&(t[a]=r);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,a]of Object.entries(this.utmParams))a&&(t[i]=a);this.config.trackSessions&&(t.session_id=I(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,a]of Object.entries(this.config.superProperties))a!==void 0&&(t[i]=a);if(e)for(let[i,a]of Object.entries(e))a!==void 0&&(t[i]=a);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,a=t.pushState.bind(t);t.pushState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=t.replaceState.bind(t);t.replaceState=(...o)=>{r(...o),this.onUrlChange(i),i=e.location?.href};let n=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",n),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=a,t.replaceState=r,e.removeEventListener("popstate",n)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},a={},r=this.config.attributes;for(let n of e.experiments){if(n.targeting_rules&&!this.evaluateRules(n.targeting_rules,r)){i[n.key]=null;continue}let o=g(n.key+":"+t);if(o%1e4/100>=n.traffic_percentage){i[n.key]=null;continue}let u=n.variants.reduce((v,P)=>v+P.weight,0),c=o%u,b=0,d=null;for(let v of n.variants)if(b+=v.weight,c<b){d=v.key;break}d||(d=n.variants[n.variants.length-1].key),i[n.key]=d}for(let n of e.flags){if(n.rules&&!this.evaluateRules(n.rules,r)){a[n.key]=!1;continue}let l=g(n.key+":"+t)%100;a[n.key]=l<n.rollout_percentage}return{experiments:i,flags:a}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=r=>{let n=t[r.attribute];if(n==null)return!1;switch(r.operator){case"is":return String(n)===String(r.value);case"is_not":return String(n)!==String(r.value);case"contains":return String(n).toLowerCase().includes(String(r.value).toLowerCase());case"not_contains":return!String(n).toLowerCase().includes(String(r.value).toLowerCase());case"gt":return Number(n)>Number(r.value);case"lt":return Number(n)<Number(r.value);case"gte":return Number(n)>=Number(r.value);case"lte":return Number(n)<=Number(r.value);case"in":return Array.isArray(r.value)&&r.value.map(String).includes(String(n));case"not_in":return Array.isArray(r.value)&&!r.value.map(String).includes(String(n));default:return!1}},a=r=>r.conditions.every(i);return e.match==="any"?e.groups.some(a):e.groups.every(a)}async fetchConfig(){let e={"Content-Type":"application/json","X-API-Key":this.config.apiKey};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let r=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${r}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let a=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,a))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,a){let r=a?this.config.ingestUrl:this.config.baseUrl,n=await fetch(`${r}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`SplitLab API error ${n.status}: ${o}`)}return n.json()}};export{E as SplitLabClient,U as hashToFloat,g as murmurhash3};
|
|
1
|
+
function g(s,e=0){let t=e>>>0,i=s.length,a=i>>2,r=3432918353,n=461845907;for(let u=0;u<a;u++){let c=s.charCodeAt(u*4)&255|(s.charCodeAt(u*4+1)&255)<<8|(s.charCodeAt(u*4+2)&255)<<16|(s.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,r),c=c<<15|c>>>17,c=Math.imul(c,n),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=a*4,l=0;switch(i&3){case 3:l^=(s.charCodeAt(o+2)&255)<<16;case 2:l^=(s.charCodeAt(o+1)&255)<<8;case 1:l^=s.charCodeAt(o)&255,l=Math.imul(l,r),l=l<<15|l>>>17,l=Math.imul(l,n),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function U(s,e){return g(s,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",k=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],O=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function A(s){if(!s)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,a=null;if(/Safari/.test(s)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(s)){let o=s.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of k){let u=s.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of O){let u=s.match(o);if(u){i=l,a=u[1]?.replace(/_/g,".")||null;break}}let n="desktop";return/Mobi|Android.*Mobile|iPhone/.test(s)?n="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(s)&&(n="tablet"),{browser:e,browser_version:t,os:i,os_version:a,device_type:n}}function _(){if(!h)return null;let s=globalThis,e=s.navigator,t=s.location,i=s.document,a=s.screen,r=A(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:r.browser,browser_version:r.browser_version,os:r.os,os_version:r.os_version,device_type:r.device_type,screen_width:a?.width??null,screen_height:a?.height??null,viewport_width:s.innerWidth??null,viewport_height:s.innerHeight??null,language:e?.language??null,timezone:L()}}function L(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var D=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],y="__ot_utm";function R(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(y);if(i)return JSON.parse(i)}catch{}let s=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of D){let a=s.get(i);a&&(e[i]=a,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(y,JSON.stringify(e))}catch{}return e}var S="__ot_sid",p="__ot_sts";function I(s){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(S),a=Number(e.getItem(p)||"0");if(i&&t-a<s)return e.setItem(p,String(t)),i;let r=f();return e.setItem(S,r),e.setItem(p,String(t)),r}catch{return f()}}var w="__ot_did";function T(){if(!h)return f();try{let s=globalThis.localStorage;if(!s)return f();let e=s.getItem(w);if(e)return e;let t=f();return s.setItem(w,t),t}catch{return f()}}var C="__ot_ref";function x(){if(!h)return null;try{let s=globalThis.sessionStorage,e=s?.getItem(C);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return s?.setItem(C,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let s=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${s}-${e}`}var m=typeof globalThis<"u"&&typeof globalThis.document<"u",E=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??m,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=R()),this.config.captureContext&&(this.initialReferrer=x()),this.deviceId=T()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),m&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&m&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=_();if(i){for(let[a,r]of Object.entries(i))r!==null&&r!==""&&r!==void 0&&(t[a]=r);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,a]of Object.entries(this.utmParams))a&&(t[i]=a);this.config.trackSessions&&(t.session_id=I(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,a]of Object.entries(this.config.superProperties))a!==void 0&&(t[i]=a);if(e)for(let[i,a]of Object.entries(e))a!==void 0&&(t[i]=a);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,a=t.pushState.bind(t);t.pushState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=t.replaceState.bind(t);t.replaceState=(...o)=>{r(...o),this.onUrlChange(i),i=e.location?.href};let n=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",n),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=a,t.replaceState=r,e.removeEventListener("popstate",n)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},a={},r=this.config.attributes;for(let n of e.experiments){if(n.targeting_rules&&!this.evaluateRules(n.targeting_rules,r)){i[n.key]=null;continue}let o=g(n.key+":"+t);if(o%1e4/100>=n.traffic_percentage){i[n.key]=null;continue}let u=n.variants.reduce((v,P)=>v+P.weight,0),c=o%u,b=0,d=null;for(let v of n.variants)if(b+=v.weight,c<b){d=v.key;break}d||(d=n.variants[n.variants.length-1].key),i[n.key]=d}for(let n of e.flags){if(n.rules&&!this.evaluateRules(n.rules,r)){a[n.key]=!1;continue}let l=g(n.key+":"+t)%100;a[n.key]=l<n.rollout_percentage}return{experiments:i,flags:a}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=r=>{let n=t[r.attribute];if(n==null)return!1;switch(r.operator){case"is":return String(n)===String(r.value);case"is_not":return String(n)!==String(r.value);case"contains":return String(n).toLowerCase().includes(String(r.value).toLowerCase());case"not_contains":return!String(n).toLowerCase().includes(String(r.value).toLowerCase());case"gt":return Number(n)>Number(r.value);case"lt":return Number(n)<Number(r.value);case"gte":return Number(n)>=Number(r.value);case"lte":return Number(n)<=Number(r.value);case"in":return Array.isArray(r.value)&&r.value.map(String).includes(String(n));case"not_in":return Array.isArray(r.value)&&!r.value.map(String).includes(String(n));default:return!1}},a=r=>r.conditions.every(i);return e.match==="any"?e.groups.some(a):e.groups.every(a)}async fetchConfig(){let e={};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config?key=${encodeURIComponent(this.config.apiKey)}`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let r=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${r}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let a=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,a))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,a){let r=a?this.config.ingestUrl:this.config.baseUrl,n=await fetch(`${r}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!n.ok){let o=await n.text().catch(()=>"");throw new Error(`SplitLab API error ${n.status}: ${o}`)}return n.json()}};export{E as SplitLabClient,U as hashToFloat,g as murmurhash3};
|
package/dist/splitlab.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var SplitLab=(()=>{var p=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var D=(n,e)=>{for(var t in e)p(n,t,{get:e[t],enumerable:!0})},z=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of A(e))!L.call(n,s)&&s!==t&&p(n,s,{get:()=>e[s],enumerable:!(i=O(e,s))||i.enumerable});return n};var M=n=>z(p({},"__esModule",{value:!0}),n);var $={};D($,{SplitLabClient:()=>y,hashToFloat:()=>w,murmurhash3:()=>g});function g(n,e=0){let t=e>>>0,i=n.length,s=i>>2,a=3432918353,r=461845907;for(let u=0;u<s;u++){let c=n.charCodeAt(u*4)&255|(n.charCodeAt(u*4+1)&255)<<8|(n.charCodeAt(u*4+2)&255)<<16|(n.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,a),c=c<<15|c>>>17,c=Math.imul(c,r),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=s*4,l=0;switch(i&3){case 3:l^=(n.charCodeAt(o+2)&255)<<16;case 2:l^=(n.charCodeAt(o+1)&255)<<8;case 1:l^=n.charCodeAt(o)&255,l=Math.imul(l,a),l=l<<15|l>>>17,l=Math.imul(l,r),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function w(n,e){return g(n,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",B=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],F=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function K(n){if(!n)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,s=null;if(/Safari/.test(n)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(n)){let o=n.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of B){let u=n.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of F){let u=n.match(o);if(u){i=l,s=u[1]?.replace(/_/g,".")||null;break}}let r="desktop";return/Mobi|Android.*Mobile|iPhone/.test(n)?r="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(n)&&(r="tablet"),{browser:e,browser_version:t,os:i,os_version:s,device_type:r}}function T(){if(!h)return null;let n=globalThis,e=n.navigator,t=n.location,i=n.document,s=n.screen,a=K(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:a.browser,browser_version:a.browser_version,os:a.os,os_version:a.os_version,device_type:a.device_type,screen_width:s?.width??null,screen_height:s?.height??null,viewport_width:n.innerWidth??null,viewport_height:n.innerHeight??null,language:e?.language??null,timezone:N()}}function N(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var j=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],C="__ot_utm";function x(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(C);if(i)return JSON.parse(i)}catch{}let n=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of j){let s=n.get(i);s&&(e[i]=s,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(C,JSON.stringify(e))}catch{}return e}var _="__ot_sid",m="__ot_sts";function E(n){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(_),s=Number(e.getItem(m)||"0");if(i&&t-s<n)return e.setItem(m,String(t)),i;let a=f();return e.setItem(_,a),e.setItem(m,String(t)),a}catch{return f()}}var R="__ot_did";function P(){if(!h)return f();try{let n=globalThis.localStorage;if(!n)return f();let e=n.getItem(R);if(e)return e;let t=f();return n.setItem(R,t),t}catch{return f()}}var I="__ot_ref";function U(){if(!h)return null;try{let n=globalThis.sessionStorage,e=n?.getItem(I);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return n?.setItem(I,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let n=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${n}-${e}`}var b=typeof globalThis<"u"&&typeof globalThis.document<"u",y=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??b,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=x()),this.config.captureContext&&(this.initialReferrer=U()),this.deviceId=P()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),b&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&b&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=T();if(i){for(let[s,a]of Object.entries(i))a!==null&&a!==""&&a!==void 0&&(t[s]=a);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,s]of Object.entries(this.utmParams))s&&(t[i]=s);this.config.trackSessions&&(t.session_id=E(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,s]of Object.entries(this.config.superProperties))s!==void 0&&(t[i]=s);if(e)for(let[i,s]of Object.entries(e))s!==void 0&&(t[i]=s);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,s=t.pushState.bind(t);t.pushState=(...o)=>{s(...o),this.onUrlChange(i),i=e.location?.href};let a=t.replaceState.bind(t);t.replaceState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",r),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=s,t.replaceState=a,e.removeEventListener("popstate",r)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},s={},a=this.config.attributes;for(let r of e.experiments){if(r.targeting_rules&&!this.evaluateRules(r.targeting_rules,a)){i[r.key]=null;continue}let o=g(r.key+":"+t);if(o%1e4/100>=r.traffic_percentage){i[r.key]=null;continue}let u=r.variants.reduce((v,k)=>v+k.weight,0),c=o%u,S=0,d=null;for(let v of r.variants)if(S+=v.weight,c<S){d=v.key;break}d||(d=r.variants[r.variants.length-1].key),i[r.key]=d}for(let r of e.flags){if(r.rules&&!this.evaluateRules(r.rules,a)){s[r.key]=!1;continue}let l=g(r.key+":"+t)%100;s[r.key]=l<r.rollout_percentage}return{experiments:i,flags:s}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=a=>{let r=t[a.attribute];if(r==null)return!1;switch(a.operator){case"is":return String(r)===String(a.value);case"is_not":return String(r)!==String(a.value);case"contains":return String(r).toLowerCase().includes(String(a.value).toLowerCase());case"not_contains":return!String(r).toLowerCase().includes(String(a.value).toLowerCase());case"gt":return Number(r)>Number(a.value);case"lt":return Number(r)<Number(a.value);case"gte":return Number(r)>=Number(a.value);case"lte":return Number(r)<=Number(a.value);case"in":return Array.isArray(a.value)&&a.value.map(String).includes(String(r));case"not_in":return Array.isArray(a.value)&&!a.value.map(String).includes(String(r));default:return!1}},s=a=>a.conditions.every(i);return e.match==="any"?e.groups.some(s):e.groups.every(s)}async fetchConfig(){let e={"Content-Type":"application/json","X-API-Key":this.config.apiKey};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let a=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${a}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let s=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,s))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,s){let a=s?this.config.ingestUrl:this.config.baseUrl,r=await fetch(`${a}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`SplitLab API error ${r.status}: ${o}`)}return r.json()}};return M($);})();
|
|
1
|
+
"use strict";var SplitLab=(()=>{var p=Object.defineProperty;var O=Object.getOwnPropertyDescriptor;var A=Object.getOwnPropertyNames;var L=Object.prototype.hasOwnProperty;var D=(n,e)=>{for(var t in e)p(n,t,{get:e[t],enumerable:!0})},z=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of A(e))!L.call(n,s)&&s!==t&&p(n,s,{get:()=>e[s],enumerable:!(i=O(e,s))||i.enumerable});return n};var M=n=>z(p({},"__esModule",{value:!0}),n);var j={};D(j,{SplitLabClient:()=>y,hashToFloat:()=>w,murmurhash3:()=>g});function g(n,e=0){let t=e>>>0,i=n.length,s=i>>2,a=3432918353,r=461845907;for(let u=0;u<s;u++){let c=n.charCodeAt(u*4)&255|(n.charCodeAt(u*4+1)&255)<<8|(n.charCodeAt(u*4+2)&255)<<16|(n.charCodeAt(u*4+3)&255)<<24;c=Math.imul(c,a),c=c<<15|c>>>17,c=Math.imul(c,r),t^=c,t=t<<13|t>>>19,t=Math.imul(t,5)+3864292196}let o=s*4,l=0;switch(i&3){case 3:l^=(n.charCodeAt(o+2)&255)<<16;case 2:l^=(n.charCodeAt(o+1)&255)<<8;case 1:l^=n.charCodeAt(o)&255,l=Math.imul(l,a),l=l<<15|l>>>17,l=Math.imul(l,r),t^=l}return t^=i,t^=t>>>16,t=Math.imul(t,2246822507),t^=t>>>13,t=Math.imul(t,3266489909),t^=t>>>16,t>>>0}function w(n,e){return g(n,e)/4294967295}var h=typeof globalThis<"u"&&typeof globalThis.document<"u",B=[[/Edg(?:e|A|iOS)?\/(\S+)/,"Edge"],[/OPR\/(\S+)/,"Opera"],[/SamsungBrowser\/(\S+)/,"Samsung Internet"],[/UCBrowser\/(\S+)/,"UC Browser"],[/Firefox\/(\S+)/,"Firefox"],[/CriOS\/(\S+)/,"Chrome"],[/FxiOS\/(\S+)/,"Firefox"],[/Chrome\/(\S+)/,"Chrome"],[/Safari\/(\S+)/,"Safari"]],F=[[/Windows NT (\d+\.\d+)/,"Windows"],[/Mac OS X ([\d_]+)/,"macOS"],[/Android ([\d.]+)/,"Android"],[/iPhone OS ([\d_]+)/,"iOS"],[/iPad.*OS ([\d_]+)/,"iPadOS"],[/CrOS/,"ChromeOS"],[/Linux/,"Linux"]];function N(n){if(!n)return{browser:null,browser_version:null,os:null,os_version:null,device_type:null};let e=null,t=null,i=null,s=null;if(/Safari/.test(n)&&!/Chrome|CriOS|Chromium|Edg|OPR|SamsungBrowser|UCBrowser/.test(n)){let o=n.match(/Version\/(\S+)/);e="Safari",t=o?o[1]:null}else for(let[o,l]of B){let u=n.match(o);if(u){e=l,t=u[1]||null;break}}for(let[o,l]of F){let u=n.match(o);if(u){i=l,s=u[1]?.replace(/_/g,".")||null;break}}let r="desktop";return/Mobi|Android.*Mobile|iPhone/.test(n)?r="mobile":/iPad|Android(?!.*Mobile)|Tablet/.test(n)&&(r="tablet"),{browser:e,browser_version:t,os:i,os_version:s,device_type:r}}function T(){if(!h)return null;let n=globalThis,e=n.navigator,t=n.location,i=n.document,s=n.screen,a=N(e?.userAgent);return{pathname:t?.pathname??null,hostname:t?.hostname??null,referrer:i?.referrer||null,search_params:t?.search||null,page_title:i?.title||null,hash:t?.hash||null,user_agent:e?.userAgent??null,browser:a.browser,browser_version:a.browser_version,os:a.os,os_version:a.os_version,device_type:a.device_type,screen_width:s?.width??null,screen_height:s?.height??null,viewport_width:n.innerWidth??null,viewport_height:n.innerHeight??null,language:e?.language??null,timezone:$()}}function $(){try{return Intl.DateTimeFormat().resolvedOptions().timeZone}catch{return null}}var K=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],C="__ot_utm";function x(){if(!h)return{};try{let i=globalThis.sessionStorage?.getItem(C);if(i)return JSON.parse(i)}catch{}let n=new URLSearchParams(globalThis.location?.search||""),e={},t=!1;for(let i of K){let s=n.get(i);s&&(e[i]=s,t=!0)}if(t)try{globalThis.sessionStorage?.setItem(C,JSON.stringify(e))}catch{}return e}var _="__ot_sid",m="__ot_sts";function E(n){if(!h)return f();let e=globalThis.sessionStorage;if(!e)return f();try{let t=Date.now(),i=e.getItem(_),s=Number(e.getItem(m)||"0");if(i&&t-s<n)return e.setItem(m,String(t)),i;let a=f();return e.setItem(_,a),e.setItem(m,String(t)),a}catch{return f()}}var R="__ot_did";function P(){if(!h)return f();try{let n=globalThis.localStorage;if(!n)return f();let e=n.getItem(R);if(e)return e;let t=f();return n.setItem(R,t),t}catch{return f()}}var I="__ot_ref";function U(){if(!h)return null;try{let n=globalThis.sessionStorage,e=n?.getItem(I);if(e!==null)return e||null;let t=globalThis.document?.referrer||"";return n?.setItem(I,t),t||null}catch{return globalThis.document?.referrer||null}}function f(){let n=Date.now().toString(36),e=Math.random().toString(36).substring(2,10);return`${n}-${e}`}var b=typeof globalThis<"u"&&typeof globalThis.document<"u",y=class{constructor(e){this.evalResult=null;this.serverConfig=null;this.eventQueue=[];this.flushTimer=null;this.configRefreshTimer=null;this.initialized=!1;this.beforeUnloadHandler=null;this.lastEtag=null;this.eventSource=null;this.deviceId=null;this.utmParams={};this.initialReferrer=null;this.pageviewCleanup=null;this.config={apiKey:e.apiKey,baseUrl:e.baseUrl.replace(/\/$/,""),ingestUrl:(e.ingestUrl||e.baseUrl).replace(/\/$/,""),distinctId:e.distinctId??null,attributes:e.attributes||{},autoFlushInterval:e.autoFlushInterval??3e4,autoFlushSize:e.autoFlushSize??20,enableLocalEvaluation:e.enableLocalEvaluation??!0,configRefreshInterval:e.configRefreshInterval??3e4,realtimeUpdates:e.realtimeUpdates??!1,onConfigUpdate:e.onConfigUpdate??null,captureContext:e.captureContext??b,captureUtm:e.captureUtm??!0,trackSessions:e.trackSessions??!0,sessionTimeout:e.sessionTimeout??30*6e4,persistDeviceId:e.persistDeviceId??!0,trackPageviews:e.trackPageviews??!1,superProperties:e.superProperties??{}},this.config.captureUtm&&(this.utmParams=x()),this.config.captureContext&&(this.initialReferrer=U()),this.deviceId=P()}get effectiveDistinctId(){return this.config.distinctId||this.deviceId}get bucketingId(){return this.deviceId}async initialize(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t}=await this.fetchConfig();this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId)}catch(e){this.serverConfig||(console.warn("SplitLab: config fetch failed, using safe defaults",e),this.serverConfig={experiments:[],flags:[]},this.evalResult={experiments:{},flags:{}})}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}this.flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this.config.autoFlushInterval),this.config.enableLocalEvaluation&&(this.configRefreshTimer=setInterval(()=>{this.refresh().catch(()=>{})},this.config.configRefreshInterval)),this.config.realtimeUpdates&&this.config.enableLocalEvaluation&&this.connectConfigStream(),b&&(this.beforeUnloadHandler=()=>{this.flushSync()},globalThis.addEventListener("beforeunload",this.beforeUnloadHandler)),this.config.trackPageviews&&b&&this.setupPageviewTracking(),this.initialized=!0}getVariant(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.experiments[e]??null}isFeatureEnabled(e){if(!this.initialized||!this.evalResult)throw new Error("SplitLabClient not initialized. Call initialize() first.");return this.evalResult.flags[e]??!1}async track(e,t){let i=this.enrichProperties(t);this.eventQueue.push({distinct_id:this.effectiveDistinctId,event_name:e,properties:i,timestamp:new Date().toISOString()}),this.eventQueue.length>=this.config.autoFlushSize&&await this.flush()}async trackPageview(e){await this.track("$pageview",e)}setSuperProperties(e){Object.assign(this.config.superProperties,e)}unsetSuperProperty(e){delete this.config.superProperties[e]}async flush(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];try{await this.request("POST","/ingest/batch",{events:e},!0)}catch{this.eventQueue=e.concat(this.eventQueue)}}async identify(e,t){let i=this.effectiveDistinctId;this.config.distinctId=e,i!==e&&await this.track("$identify",{...t,previous_distinct_id:i}),this.config.enableLocalEvaluation||(this.evalResult=null,this.initialized=!1,await this.initialize())}async refresh(){if(this.config.enableLocalEvaluation)try{let{config:e,etag:t,notModified:i}=await this.fetchConfig();if(i)return;this.serverConfig=e,this.lastEtag=t,this.evalResult=this.localEvaluate(this.serverConfig,this.bucketingId),this.config.onConfigUpdate&&this.config.onConfigUpdate()}catch{}else{let e={distinct_id:this.effectiveDistinctId};Object.keys(this.config.attributes).length>0&&(e.attributes=this.config.attributes);let t=await this.request("POST","/api/sdk/evaluate",e);this.evalResult={experiments:t.experiments,flags:t.flags}}}getDistinctId(){return this.effectiveDistinctId}getDeviceId(){return this.deviceId}setAttributes(e){this.config.attributes={...this.config.attributes,...e}}async destroy(){await this.flush(),this.flushTimer!==null&&(clearInterval(this.flushTimer),this.flushTimer=null),this.configRefreshTimer!==null&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null),this.eventSource&&(this.eventSource.close(),this.eventSource=null),this.beforeUnloadHandler&&typeof globalThis.removeEventListener=="function"&&(globalThis.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null),this.pageviewCleanup&&(this.pageviewCleanup(),this.pageviewCleanup=null),this.initialized=!1}enrichProperties(e){let t={};if(this.config.captureContext){let i=T();if(i){for(let[s,a]of Object.entries(i))a!==null&&a!==""&&a!==void 0&&(t[s]=a);this.initialReferrer&&(t.referrer=this.initialReferrer)}}if(this.config.captureUtm)for(let[i,s]of Object.entries(this.utmParams))s&&(t[i]=s);this.config.trackSessions&&(t.session_id=E(this.config.sessionTimeout)),this.config.persistDeviceId&&this.deviceId&&(t.device_id=this.deviceId);for(let[i,s]of Object.entries(this.config.superProperties))s!==void 0&&(t[i]=s);if(e)for(let[i,s]of Object.entries(e))s!==void 0&&(t[i]=s);return t}setupPageviewTracking(){let e=globalThis,t=e.history;if(!t?.pushState)return;let i=e.location?.href,s=t.pushState.bind(t);t.pushState=(...o)=>{s(...o),this.onUrlChange(i),i=e.location?.href};let a=t.replaceState.bind(t);t.replaceState=(...o)=>{a(...o),this.onUrlChange(i),i=e.location?.href};let r=()=>{this.onUrlChange(i),i=e.location?.href};e.addEventListener("popstate",r),this.trackPageview().catch(()=>{}),this.pageviewCleanup=()=>{t.pushState=s,t.replaceState=a,e.removeEventListener("popstate",r)}}onUrlChange(e){globalThis.location?.href!==e&&setTimeout(()=>{this.trackPageview({previous_url:e||null}).catch(()=>{})},0)}localEvaluate(e,t){let i={},s={},a=this.config.attributes;for(let r of e.experiments){if(r.targeting_rules&&!this.evaluateRules(r.targeting_rules,a)){i[r.key]=null;continue}let o=g(r.key+":"+t);if(o%1e4/100>=r.traffic_percentage){i[r.key]=null;continue}let u=r.variants.reduce((v,k)=>v+k.weight,0),c=o%u,S=0,d=null;for(let v of r.variants)if(S+=v.weight,c<S){d=v.key;break}d||(d=r.variants[r.variants.length-1].key),i[r.key]=d}for(let r of e.flags){if(r.rules&&!this.evaluateRules(r.rules,a)){s[r.key]=!1;continue}let l=g(r.key+":"+t)%100;s[r.key]=l<r.rollout_percentage}return{experiments:i,flags:s}}evaluateRules(e,t){if(!e.groups||e.groups.length===0)return!0;let i=a=>{let r=t[a.attribute];if(r==null)return!1;switch(a.operator){case"is":return String(r)===String(a.value);case"is_not":return String(r)!==String(a.value);case"contains":return String(r).toLowerCase().includes(String(a.value).toLowerCase());case"not_contains":return!String(r).toLowerCase().includes(String(a.value).toLowerCase());case"gt":return Number(r)>Number(a.value);case"lt":return Number(r)<Number(a.value);case"gte":return Number(r)>=Number(a.value);case"lte":return Number(r)<=Number(a.value);case"in":return Array.isArray(a.value)&&a.value.map(String).includes(String(r));case"not_in":return Array.isArray(a.value)&&!a.value.map(String).includes(String(r));default:return!1}},s=a=>a.conditions.every(i);return e.match==="any"?e.groups.some(s):e.groups.every(s)}async fetchConfig(){let e={};this.lastEtag&&(e["If-None-Match"]=this.lastEtag);let t=await fetch(`${this.config.baseUrl}/api/sdk/config?key=${encodeURIComponent(this.config.apiKey)}`,{method:"GET",headers:e});if(t.status===304)return{config:this.serverConfig,etag:this.lastEtag,notModified:!0};if(!t.ok){let a=await t.text().catch(()=>"");throw new Error(`SplitLab API error ${t.status}: ${a}`)}let i=t.headers.get("etag");return{config:await t.json(),etag:i}}connectConfigStream(){if(typeof EventSource>"u")return;let e=`${this.config.baseUrl}/api/sdk/config/stream?key=${encodeURIComponent(this.config.apiKey)}`;this.eventSource=new EventSource(e),this.eventSource.addEventListener("config_updated",()=>{this.refresh().catch(()=>{})}),this.eventSource.onerror=()=>{}}flushSync(){if(this.eventQueue.length===0)return;let e=this.eventQueue;this.eventQueue=[];let t=JSON.stringify({events:e}),i=`${this.config.ingestUrl}/ingest/batch`;if(typeof globalThis.navigator?.sendBeacon=="function"){let s=new Blob([t],{type:"application/json"});try{if(globalThis.navigator.sendBeacon(i,s))return}catch{}}if(typeof fetch=="function")try{fetch(i,{method:"POST",headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:t,keepalive:!0}).catch(()=>{})}catch{}}async request(e,t,i,s){let a=s?this.config.ingestUrl:this.config.baseUrl,r=await fetch(`${a}${t}`,{method:e,headers:{"Content-Type":"application/json","X-API-Key":this.config.apiKey},body:i?JSON.stringify(i):void 0});if(!r.ok){let o=await r.text().catch(()=>"");throw new Error(`SplitLab API error ${r.status}: ${o}`)}return r.json()}};return M(j);})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@splitlab/js-client",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Lightweight JavaScript client SDK for SplitLab A/B testing and analytics",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"publishConfig": {
|
|
@@ -8,13 +8,13 @@
|
|
|
8
8
|
},
|
|
9
9
|
"type": "module",
|
|
10
10
|
"main": "./dist/index.cjs",
|
|
11
|
-
"module": "./dist/index.
|
|
11
|
+
"module": "./dist/index.js",
|
|
12
12
|
"types": "./dist/index.d.ts",
|
|
13
13
|
"exports": {
|
|
14
14
|
".": {
|
|
15
15
|
"import": {
|
|
16
|
-
"types": "./dist/index.d.
|
|
17
|
-
"default": "./dist/index.
|
|
16
|
+
"types": "./dist/index.d.ts",
|
|
17
|
+
"default": "./dist/index.js"
|
|
18
18
|
},
|
|
19
19
|
"require": {
|
|
20
20
|
"types": "./dist/index.d.cts",
|