@sentientui/core 0.1.0 → 0.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,83 @@
1
+ # @sentientui/core
2
+
3
+ Framework-agnostic JavaScript SDK for [SentientUI](https://sentientui.dev) — an adaptive UI platform that uses a contextual bandit to automatically surface the best-performing variant for each visitor.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @sentientui/core
9
+ ```
10
+
11
+ ## Quick start
12
+
13
+ ```ts
14
+ import { init } from '@sentientui/core';
15
+
16
+ const client = init({
17
+ apiKey: 'pk_your_key',
18
+ context: 'saas', // 'landing' | 'ecommerce' | 'saas' | 'marketplace'
19
+ });
20
+
21
+ // Get a variant assignment for a component
22
+ const result = await client.assign('hero-headline');
23
+ console.log(result?.variantId); // e.g. 'variant-b'
24
+
25
+ // Track a conversion event
26
+ client.track({
27
+ projectId: 'your-project-id',
28
+ componentId: 'hero-headline',
29
+ variantId: result?.variantId ?? 'control',
30
+ eventType: 'click',
31
+ });
32
+ ```
33
+
34
+ ## API
35
+
36
+ ### `init(config)`
37
+
38
+ Initializes the client. Returns a no-op client during SSR and when `consent` is `false`.
39
+
40
+ | Option | Type | Description |
41
+ |--------|------|-------------|
42
+ | `apiKey` | `string` | Your public API key (`pk_…`) |
43
+ | `context` | `string` | Site context — `'landing'`, `'ecommerce'`, `'saas'`, or `'marketplace'` |
44
+ | `initialAssignments` | `Record<string, string>` | SSR-preloaded assignments to seed the cache (prevents variant flash on hydration) |
45
+ | `sessionSegment` | `string` | Segment from SSR (`device:source`) — must match the value used in `preloadAssignments` |
46
+ | `consent` | `boolean` | Set to `false` to disable tracking (e.g. before cookie consent). Defaults to `true` |
47
+ | `debug` | `boolean` | Logs events to the console and exposes `window.__sentient` |
48
+
49
+ ### `client.assign(componentId, variantIds?)`
50
+
51
+ Fetches a variant assignment from the bandit. Returns a cached result immediately if one exists. Returns `null` during SSR.
52
+
53
+ ### `client.track(event)`
54
+
55
+ Queues an event for ingest. Batched and sent automatically.
56
+
57
+ ### `client.getAssignment(componentId, segment)`
58
+
59
+ Synchronously returns the cached assignment for a component/segment pair, or `null` if not yet assigned.
60
+
61
+ ### `client.destroy()`
62
+
63
+ Flushes the event queue and clears the session. Call on page unload if needed.
64
+
65
+ ## SSR helpers
66
+
67
+ ```ts
68
+ import { preloadAssignments, readSessionCookie } from '@sentientui/core';
69
+
70
+ // In your server loader / getServerSideProps / Server Component:
71
+ const sessionSegment = readSessionCookie(request.headers.get('cookie'));
72
+ const initialAssignments = await preloadAssignments({
73
+ apiKey: 'pk_your_key',
74
+ componentIds: ['hero-headline', 'pricing-cta'],
75
+ sessionSegment,
76
+ });
77
+ ```
78
+
79
+ Pass `initialAssignments` and `sessionSegment` to `init()` on the client to prevent hydration mismatches.
80
+
81
+ ## License
82
+
83
+ MIT
@@ -0,0 +1 @@
1
+ var V=Object.defineProperty,X=Object.defineProperties;var H=Object.getOwnPropertyDescriptors;var F=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var z=(e,t,n)=>t in e?V(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,J=(e,t)=>{for(var n in t||(t={}))Z.call(t,n)&&z(e,n,t[n]);if(F)for(var n of F(t))ee.call(t,n)&&z(e,n,t[n]);return e},j=(e,t)=>X(e,H(t));var te="_snt_uid";var k="_snt_uid";function ne(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function re(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function se(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(o){}}function ie(e){try{return localStorage.getItem(e)}catch(t){return null}}function oe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ae(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function ce(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function ue(e){try{sessionStorage.removeItem(e)}catch(t){}}function le(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function de(e){try{localStorage.removeItem(e)}catch(t){}}function ge(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var me={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function W(e){var m,g,f,I,y;if(typeof window=="undefined")return me;let t=(m=e==null?void 0:e.cookieName)!=null?m:te,o=((g=e==null?void 0:e.cookieTTLDays)!=null?g:365)*24*60*60,r=(y=(I=(f=re(t))!=null?f:ie(k))!=null?I:ae(k))!=null?y:ne();se(t,r,o);let a=oe(k,r),s=le(t),i=a?!1:ce(k,r),u=!a&&!s&&!i;return{getSessionId:()=>r,isEphemeral:()=>u,destroy:()=>{r=null,ge(t),de(k),ue(k)}}}var O="_snt_retry";var fe={push:()=>{},flush:()=>{},destroy:()=>{}};function pe(e){try{let t=localStorage.getItem(O);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(O),n.slice(-e)):[]}catch(t){return[]}}function B(e,t){try{let o=[...(()=>{try{let r=localStorage.getItem(O);if(!r)return[];let a=JSON.parse(r);return Array.isArray(a)?a:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(O,JSON.stringify(o))}catch(n){}}function Y(e){var S,T,_;if(typeof window=="undefined")return fe;let t=(S=e.flushIntervalMs)!=null?S:5e3,n=(T=e.maxBatchSize)!=null?T:20,o=(_=e.maxRetrySize)!=null?_:100,r=e.ingestUrl,a=e.apiKey,s=[],i=new Set,u=[],m=c=>{for(let l of c)i.has(l)||(i.add(l),u.push(l));for(;u.length>500;){let l=u.shift();l&&i.delete(l)}},g=new Set,f=c=>{i.has(c.id)||g.has(c.id)||(g.add(c.id),s.push(c))},I=pe(o);for(let c of I)f(c);let y=0,h=0,D=c=>{if(c.length===0)return;let l=JSON.stringify(c),b=c.map(E=>E.id),A;try{A=fetch(r,{method:"POST",keepalive:!0,body:l,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(E){B(c,o),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6));return}let C=E=>{if(E.ok||E.status>=400&&E.status<500&&E.status!==429){m(b),h=0,y=0;return}B(c,o),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6))};A instanceof Promise?A.then(C).catch(()=>{B(c,o),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6))}):C(A)},U=c=>{let l=[],b=2;for(let A of c){let C=JSON.stringify(A).length+1;if(l.length>0&&b+C>57344||l.length>=n)break;l.push(A),b+=C}return l},v=()=>{try{if(Date.now()<y)return;for(;s.length>0;){let c=s.filter(b=>!i.has(b.id));if(s.length=0,c.length===0)break;let l=U(c);if(l.length===0)break;l.length<c.length&&s.push(...c.slice(l.length)),D(l)}}catch(c){}},x=!0,w=null;w=setInterval(()=>{x&&v()},t);let d=()=>{document.visibilityState==="hidden"&&v()},p=()=>{v()};return document.addEventListener("visibilitychange",d),window.addEventListener("beforeunload",p),{push(c){f(c),s.length>=n&&v()},flush:v,destroy(){x=!1,w!==null&&(clearInterval(w),w=null),document.removeEventListener("visibilitychange",d),window.removeEventListener("beforeunload",p),v()}}}var P="_snt_asgn_";function R(e,t){return`${e}:${t}`}function ye(e,t){return`${P}${e}_${t}`}function Q(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(P)&&e.push(n)}return e}catch(e){return[]}}function q(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of Q())try{let a=localStorage.getItem(r);if(!a)continue;let s=JSON.parse(a);if(n(s)){localStorage.removeItem(r);continue}let i=r.slice(P.length),u=i.lastIndexOf("_");if(u<0)continue;let m=i.slice(0,u),g=i.slice(u+1);t.set(R(m,g),s)}catch(a){}})(),{get(r,a){let s=t.get(R(r,a));return s?n(s)?(t.delete(R(r,a)),null):s:null},set(r,a,s){let i=R(r,a);t.set(i,s);try{localStorage.setItem(ye(r,a),JSON.stringify(s))}catch(u){}},invalidate(r){let a=`${r}:`;for(let s of[...t.keys()])s.startsWith(a)&&t.delete(s);for(let s of Q()){let i=s.slice(P.length),u=i.lastIndexOf("_");if(u<0)continue;if(i.slice(0,u)===r)try{localStorage.removeItem(s)}catch(g){}}},clear(){t.clear();for(let r of Q())try{localStorage.removeItem(r)}catch(a){}}}}function L(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function $(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let o=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(o)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(o)?"social":"referral"}catch(n){return"direct"}}function M(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function K(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function Se(e){let t=G("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function G(e,t){var a,s,i,u,m,g,f;let n=(s=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?s:"",o=(u=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?u:"",r=(m=t==null?void 0:t.now)!=null?m:new Date;return{sessionId:e,ephemeral:!1,utmParams:(g=t==null?void 0:t.utmParams)!=null?g:{},deviceClass:n?L(n):"desktop",trafficSource:o?$(o,t==null?void 0:t.appOrigin):"direct",referrerDomain:M(o),timeOfDay:K(r),dayOfWeek:(f=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?f:"sun"}}async function he(e,t,n){let o={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(o.Origin=n.origin);let r=G(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(r)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(i){}let a=await Promise.allSettled(e.map(async({id:i,variantIds:u})=>{let m=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:t,componentId:i,variantIds:u})});if(!m.ok)return null;let g=await m.json();return{id:i,variantId:g.variantId}})),s={};for(let i of a)i.status==="fulfilled"&&i.value&&(s[i.value.id]=i.value.variantId);return s}function ve(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}var Ie="https://sentient-api.fly.dev/v1/events";function we(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var N={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Ae(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,o]of t)n.startsWith("utm_")&&(e[n]=o);return e}catch(e){return{}}}function Ee(e){return e.replace(/\/events\/?$/,"")}function Le(e){var D,U,v,x,w;if(typeof window=="undefined"||e.consent===!1)return N;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),N;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),N;let t=(D=e.ingestUrl)!=null?D:Ie,n=Date.now(),o=W(),r=q(),a=Y({ingestUrl:t,apiKey:e.apiKey}),s=Ee(t),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u=L((U=navigator.userAgent)!=null?U:""),m=typeof window!="undefined"?window.location.origin:void 0,g=$((v=document.referrer)!=null?v:"",m),f=(x=e.sessionSegment)!=null?x:`${u}:${g}`;if(e.initialAssignments)for(let[d,p]of Object.entries(e.initialAssignments))r.set(d,f,{variantId:p,assignedAt:Date.now(),segment:f,confidence:1});let I=Promise.resolve(),y=o.getSessionId();if(y){let d=M((w=document.referrer)!=null?w:""),p={sessionId:y,deviceClass:u,trafficSource:g,referrerDomain:d,utmParams:Ae(),timeOfDay:K(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:o.isEphemeral()};try{I=fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(p),headers:i}).then(S=>{S.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(S){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:a});let h={track(d){let p=o.getSessionId();if(!p)return;let S=j(J({},d),{id:we(),sessionId:p,timestamp:Date.now(),timeInSession:Date.now()-n});a.push(S),e.debug&&console.log("[sentient] track",S)},getAssignment(d,p){return r.get(d,p)},async assign(d,p){let S=o.getSessionId();if(!S)return null;let T=r.get(d,f);if(T)return{variantId:T.variantId,assignmentTtlMs:0};await I;try{let _=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify({sessionId:S,componentId:d,variantIds:p}),headers:i});if(!_.ok)return null;let c=await _.json();return r.set(d,f,{variantId:c.variantId,assignedAt:Date.now(),segment:f,confidence:1}),c}catch(_){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){a.destroy(),o.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let d=window;d.__sentient&&(d.__sentient.client=h)}return h}export{J as a,j as b,L as c,$ as d,M as e,K as f,Se as g,he as h,ve as i,Le as j};
@@ -1,5 +1,5 @@
1
1
  import { SentientConfig, SentientClient } from './index.cjs';
2
- export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, ServerAssignConfig, ServerAssignments, SessionConfig, SessionManager, UserEdge, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, preloadAssignments, readSessionCookie, referrerDomainFromReferer } from './index.cjs';
2
+ export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, ServerAssignConfig, ServerAssignments, SessionConfig, SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, preloadAssignments, readSessionCookie, referrerDomainFromReferer } from './index.cjs';
3
3
 
4
4
  /**
5
5
  * Graph-capable entry point for @sentientui/core.
@@ -1,5 +1,5 @@
1
1
  import { SentientConfig, SentientClient } from './index.js';
2
- export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, ServerAssignConfig, ServerAssignments, SessionConfig, SessionManager, UserEdge, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, preloadAssignments, readSessionCookie, referrerDomainFromReferer } from './index.js';
2
+ export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, ServerAssignConfig, ServerAssignments, SessionConfig, SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, preloadAssignments, readSessionCookie, referrerDomainFromReferer } from './index.js';
3
3
 
4
4
  /**
5
5
  * Graph-capable entry point for @sentientui/core.
@@ -1 +1 @@
1
- "use strict";var k=Object.defineProperty,ie=Object.defineProperties,ae=Object.getOwnPropertyDescriptor,ce=Object.getOwnPropertyDescriptors,de=Object.getOwnPropertyNames,q=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var H=(e,t,n)=>t in e?k(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,I=(e,t)=>{for(var n in t||(t={}))Y.call(t,n)&&H(e,n,t[n]);if(q)for(var n of q(t))ue.call(t,n)&&H(e,n,t[n]);return e},U=(e,t)=>ie(e,ce(t));var ge=(e,t)=>{for(var n in t)k(e,n,{get:t[n],enumerable:!0})},le=(e,t,n,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of de(t))!Y.call(e,s)&&s!==n&&k(e,s,{get:()=>t[s],enumerable:!(c=ae(t,s))||c.enumerable});return e};var pe=e=>le(k({},"__esModule",{value:!0}),e);var Ye={};ge(Ye,{deriveSessionSegment:()=>K,detectDeviceClass:()=>C,detectTimeOfDay:()=>_,detectTrafficSource:()=>x,init:()=>He,preloadAssignments:()=>F,readSessionCookie:()=>j,referrerDomainFromReferer:()=>T});module.exports=pe(Ye);var me="_snt_uid";var A="_snt_uid";function fe(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function he(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ye(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(c){}}function Se(e){try{return localStorage.getItem(e)}catch(t){return null}}function ve(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function be(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function we(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Ee(e){try{sessionStorage.removeItem(e)}catch(t){}}function Ie(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Ae(e){try{localStorage.removeItem(e)}catch(t){}}function Ce(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var xe={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function V(e){var d,u,l,h,y;if(typeof window=="undefined")return xe;let t=(d=e==null?void 0:e.cookieName)!=null?d:me,c=((u=e==null?void 0:e.cookieTTLDays)!=null?u:365)*24*60*60,s=(y=(h=(l=he(t))!=null?l:Se(A))!=null?h:be(A))!=null?y:fe();ye(t,s,c);let r=ve(A,s),o=Ie(t),i=r?!1:we(A,s),a=!r&&!o&&!i;return{getSessionId:()=>s,isEphemeral:()=>a,destroy:()=>{s=null,Ce(t),Ae(A),Ee(A)}}}var R="_snt_retry";var Te={push:()=>{},flush:()=>{},destroy:()=>{}};function _e(e){try{let t=localStorage.getItem(R);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(R),n.slice(-e)):[]}catch(t){return[]}}function Ne(e,t){try{let c=[...(()=>{try{let s=localStorage.getItem(R);if(!s)return[];let r=JSON.parse(s);return Array.isArray(r)?r:[]}catch(s){return[]}})(),...e].slice(-t);localStorage.setItem(R,JSON.stringify(c))}catch(n){}}function X(e){var b,D,E;if(typeof window=="undefined")return Te;let t=(b=e.flushIntervalMs)!=null?b:5e3,n=(D=e.maxBatchSize)!=null?D:20,c=(E=e.maxRetrySize)!=null?E:100,s=e.ingestUrl,r=e.apiKey,o=[],i=new Set,a=[],d=g=>{for(let m of g)i.has(m)||(i.add(m),a.push(m));for(;a.length>500;){let m=a.shift();m&&i.delete(m)}},u=new Set,l=g=>{i.has(g.id)||u.has(g.id)||(u.add(g.id),o.push(g))},h=_e(c);for(let g of h)l(g);let y=g=>{if(g.length===0)return!0;let m=JSON.stringify(g);try{return fetch(s,{method:"POST",keepalive:!0,body:m,headers:{"Content-Type":"application/json",Authorization:`Bearer ${r}`}}),d(g.map(O=>O.id)),!0}catch(O){return Ne(g,c),!1}},S=()=>{try{for(;o.length>0;){let m=o.splice(0,n).filter(oe=>!i.has(oe.id));if(m.length===0)continue;if(!y(m)){o.unshift(...m);break}}}catch(g){}},w=!0,v=null,N=()=>{if(!w)return;let g=Date.now()+t,m=()=>{if(w){if(Date.now()>=g){S(),N();return}try{v=new MessageChannel,v.port1.onmessage=m,v.port2.postMessage(null)}catch(O){}}};m()},p=()=>{document.visibilityState==="hidden"&&S()},f=()=>{S()};return document.addEventListener("visibilitychange",p),window.addEventListener("beforeunload",f),N(),{push(g){l(g),o.length>=n&&S()},flush:S,destroy(){w=!1,document.removeEventListener("visibilitychange",p),window.removeEventListener("beforeunload",f),v&&(v.port1.onmessage=null,v=null),S()}}}var M="_snt_asgn_";function P(e,t){return`${e}:${t}`}function De(e,t){return`${M}${e}_${t}`}function $(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(M)&&e.push(n)}return e}catch(e){return[]}}function Z(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of $())try{let r=localStorage.getItem(s);if(!r)continue;let o=JSON.parse(r);if(n(o)){localStorage.removeItem(s);continue}let i=s.slice(M.length),a=i.lastIndexOf("_");if(a<0)continue;let d=i.slice(0,a),u=i.slice(a+1);t.set(P(d,u),o)}catch(r){}})(),{get(s,r){let o=t.get(P(s,r));return o?n(o)?(t.delete(P(s,r)),null):o:null},set(s,r,o){let i=P(s,r);t.set(i,o);try{localStorage.setItem(De(s,r),JSON.stringify(o))}catch(a){}},invalidate(s){let r=`${s}:`;for(let o of[...t.keys()])o.startsWith(r)&&t.delete(o);for(let o of $()){let i=o.slice(M.length),a=i.lastIndexOf("_");if(a<0)continue;if(i.slice(0,a)===s)try{localStorage.removeItem(o)}catch(u){}}},clear(){t.clear();for(let s of $())try{localStorage.removeItem(s)}catch(r){}}}}function C(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function x(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(s){}let c=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(c)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(c)?"social":"referral"}catch(n){return"direct"}}function T(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function _(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function K(e){let t=G("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function G(e,t){var r,o,i,a,d,u,l;let n=(o=(r=t==null?void 0:t.userAgent)==null?void 0:r.trim())!=null?o:"",c=(a=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?a:"",s=(d=t==null?void 0:t.now)!=null?d:new Date;return{sessionId:e,ephemeral:!1,utmParams:(u=t==null?void 0:t.utmParams)!=null?u:{},deviceClass:n?C(n):"desktop",trafficSource:c?x(c,t==null?void 0:t.appOrigin):"direct",referrerDomain:T(c),timeOfDay:_(s),dayOfWeek:(l=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?l:"sun"}}async function F(e,t,n){let c={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(c.Origin=n.origin);let s=G(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:c,body:JSON.stringify(s)})}catch(i){}let r=await Promise.allSettled(e.map(async({id:i,variantIds:a})=>{let d=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:c,body:JSON.stringify({sessionId:t,componentId:i,variantIds:a})});if(!d.ok)return null;let u=await d.json();return{id:i,variantId:u.variantId}})),o={};for(let i of r)i.status==="fulfilled"&&i.value&&(o[i.value.id]=i.value.variantId);return o}function j(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}function Oe(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var L={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],userEdges:[],capturedAt:0}),destroy:()=>{}};function ke(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,c]of t)n.startsWith("utm_")&&(e[n]=c);return e}catch(e){return{}}}function Ue(e){return e.replace(/\/events\/?$/,"")}function ee(e){var S,w,v,N;if(typeof window=="undefined"||e.consent===!1)return L;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),L;if(!e.ingestUrl)return console.warn("[sentient] init() called without ingestUrl. SDK disabled."),L;let t=Date.now(),n=V(),c=Z(),s=X({ingestUrl:e.ingestUrl,apiKey:e.apiKey}),r=Ue(e.ingestUrl),o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i=C((S=navigator.userAgent)!=null?S:""),a=typeof window!="undefined"?window.location.origin:void 0,d=x((w=document.referrer)!=null?w:"",a),u=(v=e.sessionSegment)!=null?v:`${i}:${d}`;if(e.initialAssignments)for(let[p,f]of Object.entries(e.initialAssignments))c.set(p,u,{variantId:f,assignedAt:Date.now(),segment:u,confidence:1});let l=Promise.resolve(),h=n.getSessionId();if(h){let p=T((N=document.referrer)!=null?N:""),f={sessionId:h,deviceClass:i,trafficSource:d,referrerDomain:p,utmParams:ke(),timeOfDay:_(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:n.isEphemeral()};try{l=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(f),headers:o}).then(()=>{}).catch(()=>{})}catch(b){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:s});let y={track(p){let f=n.getSessionId();if(!f)return;let b=U(I({},p),{id:Oe(),sessionId:f,timestamp:Date.now(),timeInSession:Date.now()-t});s.push(b),e.debug&&console.log("[sentient] track",b)},getAssignment(p,f){return c.get(p,f)},async assign(p,f){let b=n.getSessionId();if(!b)return null;let D=c.get(p,u);if(D)return{variantId:D.variantId,assignmentTtlMs:0};await l;try{let E=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify({sessionId:b,componentId:p,variantIds:f}),headers:o});if(!E.ok)return null;let g=await E.json();return c.set(p,u,{variantId:g.variantId,assignedAt:Date.now(),segment:u,confidence:1}),g}catch(E){return null}},getGraph(){return{pageNodes:[],userEdges:[],capturedAt:0}},destroy(){s.destroy(),n.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let p=window;p.__sentient&&(p.__sentient.client=y)}return y}var Re=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Pe="h1, h2, h3",Me={scan:async()=>({nodes:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function z(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function Le(e){var t,n,c;try{let s=e;for(let r of Object.keys(s)){if(!r.startsWith("__reactFiber")&&!r.startsWith("__reactInternalInstance"))continue;let o=s[r],i=(c=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?c:(n=o==null?void 0:o.type)==null?void 0:n.name;if(i&&i.length>1)return i}}catch(s){}}function $e(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function Ke(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function Ge(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function Fe(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function J(e,t){var c,s,r;let n=e.querySelector(Pe);return{componentId:Ge(e),semanticType:Ke(e),ariaLabel:(c=e.getAttribute("aria-label"))!=null?c:void 0,headingText:(r=(s=n==null?void 0:n.textContent)==null?void 0:s.trim())!=null?r:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:Fe(e),reactComponentName:Le(e),dataAttributes:$e(e)}}function je(e){let t=[],n=new Set;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{r instanceof Element&&!n.has(r)&&(n.add(r),t.push(J(r,e)))}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let o=r.hasAttribute("aria-label"),i=r.hasAttribute("data-sentient-id");!o&&!i||(n.add(r),t.push(J(r,e)))}),t}function te(){if(typeof window=="undefined")return Me;let e=null,t=0,n=null,c=i=>{try{let a=window.getComputedStyle(i),d=parseFloat(a.fontSize)||12,u=parseFloat(a.zIndex)||0,l=i.getBoundingClientRect(),h=Math.max(l.top,0),y=window.innerHeight||1,S=1/(h/y+1),w=z(d,12,48)*.4+z(S,0,1)*.4+z(u,0,100)*.2;return Math.max(0,Math.min(1,w))}catch(a){return .5}};return{scan:()=>new Promise(i=>{let a=()=>{i({nodes:je(c),scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(a,{timeout:100}):a()}catch(d){a()}}),observe:i=>{n=i;try{e=new MutationObserver(a=>{let d=[];for(let u of a)u.type==="childList"&&u.addedNodes.forEach(l=>{if(!(l instanceof Element)||!Re.has(l.tagName))return;let h=l.hasAttribute("data-sentient-id"),y=l.hasAttribute("aria-label");!h&&!y||d.push(J(l,c))});d.length>0&&n&&n({nodes:d,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(a){}},getProminenceScore:c,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null}}}var Q="_snt_graph_nodes",W="_snt_graph_edges",ze={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function B(e){return Math.max(0,Math.min(1,e))}function Je(e){var t;return(t=ze[e])!=null?t:[]}function ne(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function re(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var Qe=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function We(e){return Qe.has(e)?e:"generic"}function Be(e,t,n){let c=`${e}:${t}:${n.join(",")}`,s=5381;for(let r=0;r<c.length;r++)s=(s<<5)+s+c.charCodeAt(r)&4294967295;return(s>>>0).toString(16).padStart(8,"0")}function se(e){let t=new Map,n=new Map,c=()=>{typeof window!="undefined"&&(re(Q,[...t.values()]),re(W,[...n.values()]))},s=o=>{var i,a;try{let d=JSON.parse(o);t.clear(),n.clear();for(let u of(i=d.pageNodes)!=null?i:[])t.set(u.componentId,u);for(let u of(a=d.userEdges)!=null?a:[])n.set(u.componentId,u)}catch(d){}};if(typeof window!="undefined"){let o=ne(Q,[]),i=ne(W,[]);for(let a of o)t.set(a.componentId,a);for(let a of i)n.set(a.componentId,a)}let r=(o,i)=>{let a=n.get(o);a?(a.attentionWeight=B(a.attentionWeight+i),a.lastUpdated=Date.now()):n.set(o,{componentId:o,attentionWeight:B(i),interactionCount:0,dwellTime:0,lastUpdated:Date.now()})};return{addPageNode(o){t.set(o.componentId,o),c()},syncOnce(){if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let o=[...t.values()];if(o.length!==0)try{let i={pageUrl:window.location.href,nodes:o.map(a=>{let d=We(a.semanticType);return{componentId:a.componentId,semanticType:d,answers:a.answers,contentHash:Be(a.componentId,d,a.answers),prominenceScore:a.prominenceScore,depthInPage:a.depth}}),edges:[]};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:I({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(i)}).catch(()=>{})}catch(i){}},updateUserEdge(o,i){var d;let a=(d=n.get(o))!=null?d:{componentId:o,attentionWeight:0,interactionCount:0,dwellTime:0,lastUpdated:Date.now()};a.attentionWeight=B(a.attentionWeight+i),a.interactionCount+=1,a.lastUpdated=Date.now(),n.set(o,a),c()},propagate(o,i){let a=t.get(o);if(!a){r(o,i),c();return}r(o,i);for(let d of Je(a.semanticType))for(let u of t.values())u.semanticType===d&&u.componentId!==o&&r(u.componentId,i*.4);for(let d of t.values())d.depth===a.depth+1&&r(d.componentId,i*.6);for(let d of t.values())d.semanticType===a.semanticType&&d.componentId!==o&&r(d.componentId,i*-.2);c()},snapshot(){return{pageNodes:[...t.values()],userEdges:[...n.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()],userEdges:[...n.values()]})},restore:s,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(Q),localStorage.removeItem(W)}catch(o){}}}}function qe(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function He(e){let t=ee(e);if(!e.graph||typeof window=="undefined")return t;let n=te(),c=se({syncUrl:e.ingestUrl.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:qe()});try{let s=localStorage.getItem("_snt_graph_nodes"),r=localStorage.getItem("_snt_graph_edges");(s||r)&&c.restore(JSON.stringify({pageNodes:s?JSON.parse(s):[],userEdges:r?JSON.parse(r):[]}))}catch(s){}return n.scan().then(s=>{for(let r of s.nodes)c.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});c.syncOnce()}),n.observe(s=>{for(let r of s.nodes)c.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth})}),U(I({},t),{getGraph:()=>c.snapshot(),destroy:()=>{n.destroy(),c.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
1
+ "use strict";var $=Object.defineProperty,de=Object.defineProperties,ue=Object.getOwnPropertyDescriptor,ge=Object.getOwnPropertyDescriptors,le=Object.getOwnPropertyNames,X=Object.getOwnPropertySymbols;var ee=Object.prototype.hasOwnProperty,pe=Object.prototype.propertyIsEnumerable;var Z=(e,t,n)=>t in e?$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,x=(e,t)=>{for(var n in t||(t={}))ee.call(t,n)&&Z(e,n,t[n]);if(X)for(var n of X(t))pe.call(t,n)&&Z(e,n,t[n]);return e},L=(e,t)=>de(e,ge(t));var me=(e,t)=>{for(var n in t)$(e,n,{get:t[n],enumerable:!0})},fe=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of le(t))!ee.call(e,s)&&s!==n&&$(e,s,{get:()=>t[s],enumerable:!(a=ue(t,s))||a.enumerable});return e};var he=e=>fe($({},"__esModule",{value:!0}),e);var nt={};me(nt,{deriveSessionSegment:()=>J,detectDeviceClass:()=>N,detectTimeOfDay:()=>R,detectTrafficSource:()=>O,init:()=>tt,preloadAssignments:()=>q,readSessionCookie:()=>W,referrerDomainFromReferer:()=>D});module.exports=he(nt);var ye="_snt_uid";var k="_snt_uid";function Se(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function ve(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function Ie(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(a){}}function Ee(e){try{return localStorage.getItem(e)}catch(t){return null}}function we(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function be(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Ce(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Ae(e){try{sessionStorage.removeItem(e)}catch(t){}}function _e(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Te(e){try{localStorage.removeItem(e)}catch(t){}}function xe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var ke={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function te(e){var d,g,l,f,u;if(typeof window=="undefined")return ke;let t=(d=e==null?void 0:e.cookieName)!=null?d:ye,a=((g=e==null?void 0:e.cookieTTLDays)!=null?g:365)*24*60*60,s=(u=(f=(l=ve(t))!=null?l:Ee(k))!=null?f:be(k))!=null?u:Se();Ie(t,s,a);let i=we(k,s),r=_e(t),o=i?!1:Ce(k,s),c=!i&&!r&&!o;return{getSessionId:()=>s,isEphemeral:()=>c,destroy:()=>{s=null,xe(t),Te(k),Ae(k)}}}var K="_snt_retry";var Ne={push:()=>{},flush:()=>{},destroy:()=>{}};function Oe(e){try{let t=localStorage.getItem(K);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(K),n.slice(-e)):[]}catch(t){return[]}}function j(e,t){try{let a=[...(()=>{try{let s=localStorage.getItem(K);if(!s)return[];let i=JSON.parse(s);return Array.isArray(i)?i:[]}catch(s){return[]}})(),...e].slice(-t);localStorage.setItem(K,JSON.stringify(a))}catch(n){}}function ne(e){var E,P,_;if(typeof window=="undefined")return Ne;let t=(E=e.flushIntervalMs)!=null?E:5e3,n=(P=e.maxBatchSize)!=null?P:20,a=(_=e.maxRetrySize)!=null?_:100,s=e.ingestUrl,i=e.apiKey,r=[],o=new Set,c=[],d=p=>{for(let h of p)o.has(h)||(o.add(h),c.push(h));for(;c.length>500;){let h=c.shift();h&&o.delete(h)}},g=new Set,l=p=>{o.has(p.id)||g.has(p.id)||(g.add(p.id),r.push(p))},f=Oe(a);for(let p of f)l(p);let u=0,m=0,I=p=>{if(p.length===0)return;let h=JSON.stringify(p),T=p.map(A=>A.id),C;try{C=fetch(s,{method:"POST",keepalive:!0,body:h,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}})}catch(A){j(p,a),m++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(m,6));return}let M=A=>{if(A.ok||A.status>=400&&A.status<500&&A.status!==429){d(T),m=0,u=0;return}j(p,a),m++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(m,6))};C instanceof Promise?C.then(M).catch(()=>{j(p,a),m++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(m,6))}):M(C)},w=p=>{let h=[],T=2;for(let C of p){let M=JSON.stringify(C).length+1;if(h.length>0&&T+M>57344||h.length>=n)break;h.push(C),T+=M}return h},v=()=>{try{if(Date.now()<u)return;for(;r.length>0;){let p=r.filter(T=>!o.has(T.id));if(r.length=0,p.length===0)break;let h=w(p);if(h.length===0)break;h.length<p.length&&r.push(...p.slice(h.length)),I(h)}}catch(p){}},U=!0,b=null;b=setInterval(()=>{U&&v()},t);let y=()=>{document.visibilityState==="hidden"&&v()},S=()=>{v()};return document.addEventListener("visibilitychange",y),window.addEventListener("beforeunload",S),{push(p){l(p),r.length>=n&&v()},flush:v,destroy(){U=!1,b!==null&&(clearInterval(b),b=null),document.removeEventListener("visibilitychange",y),window.removeEventListener("beforeunload",S),v()}}}var F="_snt_asgn_";function G(e,t){return`${e}:${t}`}function De(e,t){return`${F}${e}_${t}`}function z(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(F)&&e.push(n)}return e}catch(e){return[]}}function re(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of z())try{let i=localStorage.getItem(s);if(!i)continue;let r=JSON.parse(i);if(n(r)){localStorage.removeItem(s);continue}let o=s.slice(F.length),c=o.lastIndexOf("_");if(c<0)continue;let d=o.slice(0,c),g=o.slice(c+1);t.set(G(d,g),r)}catch(i){}})(),{get(s,i){let r=t.get(G(s,i));return r?n(r)?(t.delete(G(s,i)),null):r:null},set(s,i,r){let o=G(s,i);t.set(o,r);try{localStorage.setItem(De(s,i),JSON.stringify(r))}catch(c){}},invalidate(s){let i=`${s}:`;for(let r of[...t.keys()])r.startsWith(i)&&t.delete(r);for(let r of z()){let o=r.slice(F.length),c=o.lastIndexOf("_");if(c<0)continue;if(o.slice(0,c)===s)try{localStorage.removeItem(r)}catch(g){}}},clear(){t.clear();for(let s of z())try{localStorage.removeItem(s)}catch(i){}}}}function N(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function O(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(s){}let a=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(a)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(a)?"social":"referral"}catch(n){return"direct"}}function D(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function R(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function J(e){let t=Q("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Q(e,t){var i,r,o,c,d,g,l;let n=(r=(i=t==null?void 0:t.userAgent)==null?void 0:i.trim())!=null?r:"",a=(c=(o=t==null?void 0:t.referer)==null?void 0:o.trim())!=null?c:"",s=(d=t==null?void 0:t.now)!=null?d:new Date;return{sessionId:e,ephemeral:!1,utmParams:(g=t==null?void 0:t.utmParams)!=null?g:{},deviceClass:n?N(n):"desktop",trafficSource:a?O(a,t==null?void 0:t.appOrigin):"direct",referrerDomain:D(a),timeOfDay:R(s),dayOfWeek:(l=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?l:"sun"}}async function q(e,t,n){let a={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(a.Origin=n.origin);let s=Q(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:a,body:JSON.stringify(s)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(o){}let i=await Promise.allSettled(e.map(async({id:o,variantIds:c})=>{let d=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:a,body:JSON.stringify({sessionId:t,componentId:o,variantIds:c})});if(!d.ok)return null;let g=await d.json();return{id:o,variantId:g.variantId}})),r={};for(let o of i)o.status==="fulfilled"&&o.value&&(r[o.value.id]=o.value.variantId);return r}function W(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}var Re="https://sentient-api.fly.dev/v1/events";function Ue(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var B={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Pe(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,a]of t)n.startsWith("utm_")&&(e[n]=a);return e}catch(e){return{}}}function Me(e){return e.replace(/\/events\/?$/,"")}function oe(e){var I,w,v,U,b;if(typeof window=="undefined"||e.consent===!1)return B;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),B;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),B;let t=(I=e.ingestUrl)!=null?I:Re,n=Date.now(),a=te(),s=re(),i=ne({ingestUrl:t,apiKey:e.apiKey}),r=Me(t),o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c=N((w=navigator.userAgent)!=null?w:""),d=typeof window!="undefined"?window.location.origin:void 0,g=O((v=document.referrer)!=null?v:"",d),l=(U=e.sessionSegment)!=null?U:`${c}:${g}`;if(e.initialAssignments)for(let[y,S]of Object.entries(e.initialAssignments))s.set(y,l,{variantId:S,assignedAt:Date.now(),segment:l,confidence:1});let f=Promise.resolve(),u=a.getSessionId();if(u){let y=D((b=document.referrer)!=null?b:""),S={sessionId:u,deviceClass:c,trafficSource:g,referrerDomain:y,utmParams:Pe(),timeOfDay:R(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:a.isEphemeral()};try{f=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(S),headers:o}).then(E=>{E.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(E){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:i});let m={track(y){let S=a.getSessionId();if(!S)return;let E=L(x({},y),{id:Ue(),sessionId:S,timestamp:Date.now(),timeInSession:Date.now()-n});i.push(E),e.debug&&console.log("[sentient] track",E)},getAssignment(y,S){return s.get(y,S)},async assign(y,S){let E=a.getSessionId();if(!E)return null;let P=s.get(y,l);if(P)return{variantId:P.variantId,assignmentTtlMs:0};await f;try{let _=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify({sessionId:E,componentId:y,variantIds:S}),headers:o});if(!_.ok)return null;let p=await _.json();return s.set(y,l,{variantId:p.variantId,assignedAt:Date.now(),segment:l,confidence:1}),p}catch(_){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){i.destroy(),a.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let y=window;y.__sentient&&(y.__sentient.client=m)}return m}var $e=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Le="h1, h2, h3",Ke={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function Y(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function Ge(e){var t,n,a;try{let s=e;for(let i of Object.keys(s)){if(!i.startsWith("__reactFiber")&&!i.startsWith("__reactInternalInstance"))continue;let r=s[i],o=(a=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?a:(n=r==null?void 0:r.type)==null?void 0:n.name;if(o&&o.length>1)return o}}catch(s){}}function Fe(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function Be(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function je(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function ze(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function H(e,t){var a,s,i;let n=e.querySelector(Le);return{componentId:je(e),semanticType:Be(e),ariaLabel:(a=e.getAttribute("aria-label"))!=null?a:void 0,headingText:(i=(s=n==null?void 0:n.textContent)==null?void 0:s.trim())!=null?i:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:ze(e),reactComponentName:Ge(e),dataAttributes:Fe(e)}}function se(e){var i;let t=[],n=new Set,a="__root__",s=new Map;for(let[r,o]of e){let c=r.parentElement,d=a;for(;c;){if(e.has(c)){d=e.get(c);let l=e.get(r),f=`${d}->${l}`;!n.has(f)&&d!==l&&(n.add(f),t.push({fromComponentId:d,toComponentId:l,weight:.6}));break}c=c.parentElement}let g=(i=s.get(d))!=null?i:[];g.push(r),s.set(d,g)}for(let r of s.values())if(!(r.length<2))for(let o=0;o<r.length;o++)for(let c=o+1;c<r.length;c++){let d=e.get(r[o]),g=e.get(r[c]);if(d===g)continue;let l=`${d}->${g}::sib`,f=`${g}->${d}::sib`;n.has(l)||(n.add(l),t.push({fromComponentId:d,toComponentId:g,weight:.3})),n.has(f)||(n.add(f),t.push({fromComponentId:g,toComponentId:d,weight:.3}))}return t}function Je(e){let t=[],n=new Set,a=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let o=H(r,e);t.push(o),a.set(r,o.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let o=r.hasAttribute("aria-label"),c=r.hasAttribute("data-sentient-id");if(!o&&!c)return;n.add(r);let d=H(r,e);t.push(d),a.set(r,d.componentId)}),{nodes:t,edges:se(a)}}function ie(){if(typeof window=="undefined")return Ke;let e=null,t=0,n=null,a=o=>{try{let c=window.getComputedStyle(o),d=parseFloat(c.fontSize)||12,g=parseFloat(c.zIndex)||0,l=o.getBoundingClientRect(),f=Math.max(l.top,0),u=window.innerHeight||1,m=1/(f/u+1),I=Y(d,12,48)*.4+Y(m,0,1)*.4+Y(g,0,100)*.2;return Math.max(0,Math.min(1,I))}catch(c){return .5}};return{scan:()=>new Promise(o=>{let c=()=>{let{nodes:d,edges:g}=Je(a);o({nodes:d,edges:g,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(d){c()}}),observe:o=>{n=o;try{e=new MutationObserver(c=>{let d=[],g=new Map;for(let l of c)l.type==="childList"&&l.addedNodes.forEach(f=>{if(!(f instanceof Element)||!$e.has(f.tagName))return;let u=f.hasAttribute("data-sentient-id"),m=f.hasAttribute("aria-label");if(!u&&!m)return;let I=H(f,a);d.push(I),g.set(f,I.componentId)});d.length>0&&n&&n({nodes:d,edges:se(g),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:a,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(o){}t=0,n=null}}}var V="_snt_graph_nodes",ae="_snt_graph_edges",Qe={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function qe(e){var t;return(t=Qe[e])!=null?t:[]}function We(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function Ye(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var He=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function Ve(e){return He.has(e)?e:"generic"}function Xe(e,t,n){let a=`${e}:${t}:${n.join(",")}`,s=5381;for(let i=0;i<a.length;i++)s=(s<<5)+s+a.charCodeAt(i)&4294967295;return(s>>>0).toString(16).padStart(8,"0")}function ce(e){let t=new Map,n=new Map,a=()=>{typeof window!="undefined"&&Ye(V,[...t.values()])},s=i=>{var r;try{let o=JSON.parse(i);t.clear();for(let c of(r=o.pageNodes)!=null?r:[])t.set(c.componentId,c)}catch(o){}};if(typeof window!="undefined"){let i=We(V,[]);for(let r of i)t.set(r.componentId,r);try{localStorage.removeItem(ae)}catch(r){}}return{addPageNode(i){t.set(i.componentId,i),a()},addStructuralEdge(i){let r=`${i.fromComponentId}->${i.toComponentId}`;n.set(r,i)},syncOnce(){var r,o;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let i=[...t.values()];if(i.length!==0)try{let c=new Map;for(let u of i){let m=(r=c.get(u.semanticType))!=null?r:[];m.push(u),c.set(u.semanticType,m)}let d=[],g=new Set;for(let u of i)for(let m of qe(u.semanticType)){let I=(o=c.get(m))!=null?o:[];for(let w of I){if(w.componentId===u.componentId)continue;let v=`semantic:${u.componentId}->${w.componentId}`;g.has(v)||(g.add(v),d.push({fromComponentId:u.componentId,toComponentId:w.componentId,type:"semantic",weight:.4,confidence:.9}))}}let l=new Set(i.map(u=>u.componentId));for(let u of n.values()){if(!l.has(u.fromComponentId)||!l.has(u.toComponentId))continue;let m=`structural:${u.fromComponentId}->${u.toComponentId}`;g.has(m)||(g.add(m),d.push({fromComponentId:u.fromComponentId,toComponentId:u.toComponentId,type:"structural",weight:u.weight,confidence:1}))}let f={pageUrl:window.location.href,nodes:i.map(u=>{let m=Ve(u.semanticType);return{componentId:u.componentId,semanticType:m,answers:u.answers,contentHash:Xe(u.componentId,m,u.answers),prominenceScore:u.prominenceScore,depthInPage:u.depth}}),edges:d};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:x({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(f)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:s,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(V),localStorage.removeItem(ae)}catch(i){}}}}var Ze="https://sentient-api.fly.dev/v1/events";function et(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function tt(e){var i;let t=oe(e);if(!e.graph||typeof window=="undefined")return t;let n=ie(),a=(i=e.ingestUrl)!=null?i:Ze,s=ce({syncUrl:a.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:et()});try{let r=localStorage.getItem("_snt_graph_nodes");r&&s.restore(JSON.stringify({pageNodes:JSON.parse(r)}))}catch(r){}return n.scan().then(r=>{for(let o of r.nodes)s.addPageNode({id:o.componentId,componentId:o.componentId,semanticType:o.semanticType,answers:o.headingText?[o.headingText]:[],prominenceScore:o.prominenceScore,depth:o.depth});for(let o of r.edges)s.addStructuralEdge(o);s.syncOnce()}),n.observe(r=>{for(let o of r.nodes)s.addPageNode({id:o.componentId,componentId:o.componentId,semanticType:o.semanticType,answers:o.headingText?[o.headingText]:[],prominenceScore:o.prominenceScore,depth:o.depth});for(let o of r.edges)s.addStructuralEdge(o)}),L(x({},t),{getGraph:()=>s.snapshot(),destroy:()=>{n.destroy(),s.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
@@ -1 +1 @@
1
- import{a as g,b,c as x,d as O,e as _,f as U,g as D,h as R,i as P,j as E}from"./chunk-HRRGYUE4.mjs";var M=new Set(["SECTION","ARTICLE","MAIN","DIV"]),G="h1, h2, h3",k={scan:async()=>({nodes:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function f(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function j(e){var t,n,i;try{let c=e;for(let r of Object.keys(c)){if(!r.startsWith("__reactFiber")&&!r.startsWith("__reactInternalInstance"))continue;let s=c[r],a=(i=(t=s==null?void 0:s.type)==null?void 0:t.displayName)!=null?i:(n=s==null?void 0:s.type)==null?void 0:n.name;if(a&&a.length>1)return a}}catch(c){}}function W(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function F(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function L(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function q(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function h(e,t){var i,c,r;let n=e.querySelector(G);return{componentId:L(e),semanticType:F(e),ariaLabel:(i=e.getAttribute("aria-label"))!=null?i:void 0,headingText:(r=(c=n==null?void 0:n.textContent)==null?void 0:c.trim())!=null?r:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:q(e),reactComponentName:j(e),dataAttributes:W(e)}}function z(e){let t=[],n=new Set;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{r instanceof Element&&!n.has(r)&&(n.add(r),t.push(h(r,e)))}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let s=r.hasAttribute("aria-label"),a=r.hasAttribute("data-sentient-id");!s&&!a||(n.add(r),t.push(h(r,e)))}),t}function C(){if(typeof window=="undefined")return k;let e=null,t=0,n=null,i=a=>{try{let o=window.getComputedStyle(a),d=parseFloat(o.fontSize)||12,p=parseFloat(o.zIndex)||0,u=a.getBoundingClientRect(),l=Math.max(u.top,0),m=window.innerHeight||1,A=1/(l/m+1),T=f(d,12,48)*.4+f(A,0,1)*.4+f(p,0,100)*.2;return Math.max(0,Math.min(1,T))}catch(o){return .5}};return{scan:()=>new Promise(a=>{let o=()=>{a({nodes:z(i),scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(o,{timeout:100}):o()}catch(d){o()}}),observe:a=>{n=a;try{e=new MutationObserver(o=>{let d=[];for(let p of o)p.type==="childList"&&p.addedNodes.forEach(u=>{if(!(u instanceof Element)||!M.has(u.tagName))return;let l=u.hasAttribute("data-sentient-id"),m=u.hasAttribute("aria-label");!l&&!m||d.push(h(u,i))});d.length>0&&n&&n({nodes:d,addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(o){}},getProminenceScore:i,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(a){}t=0,n=null}}}var y="_snt_graph_nodes",S="_snt_graph_edges",J={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function v(e){return Math.max(0,Math.min(1,e))}function K(e){var t;return(t=J[e])!=null?t:[]}function N(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function w(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var H=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function B(e){return H.has(e)?e:"generic"}function $(e,t,n){let i=`${e}:${t}:${n.join(",")}`,c=5381;for(let r=0;r<i.length;r++)c=(c<<5)+c+i.charCodeAt(r)&4294967295;return(c>>>0).toString(16).padStart(8,"0")}function I(e){let t=new Map,n=new Map,i=()=>{typeof window!="undefined"&&(w(y,[...t.values()]),w(S,[...n.values()]))},c=s=>{var a,o;try{let d=JSON.parse(s);t.clear(),n.clear();for(let p of(a=d.pageNodes)!=null?a:[])t.set(p.componentId,p);for(let p of(o=d.userEdges)!=null?o:[])n.set(p.componentId,p)}catch(d){}};if(typeof window!="undefined"){let s=N(y,[]),a=N(S,[]);for(let o of s)t.set(o.componentId,o);for(let o of a)n.set(o.componentId,o)}let r=(s,a)=>{let o=n.get(s);o?(o.attentionWeight=v(o.attentionWeight+a),o.lastUpdated=Date.now()):n.set(s,{componentId:s,attentionWeight:v(a),interactionCount:0,dwellTime:0,lastUpdated:Date.now()})};return{addPageNode(s){t.set(s.componentId,s),i()},syncOnce(){if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let s=[...t.values()];if(s.length!==0)try{let a={pageUrl:window.location.href,nodes:s.map(o=>{let d=B(o.semanticType);return{componentId:o.componentId,semanticType:d,answers:o.answers,contentHash:$(o.componentId,d,o.answers),prominenceScore:o.prominenceScore,depthInPage:o.depth}}),edges:[]};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:g({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(a)}).catch(()=>{})}catch(a){}},updateUserEdge(s,a){var d;let o=(d=n.get(s))!=null?d:{componentId:s,attentionWeight:0,interactionCount:0,dwellTime:0,lastUpdated:Date.now()};o.attentionWeight=v(o.attentionWeight+a),o.interactionCount+=1,o.lastUpdated=Date.now(),n.set(s,o),i()},propagate(s,a){let o=t.get(s);if(!o){r(s,a),i();return}r(s,a);for(let d of K(o.semanticType))for(let p of t.values())p.semanticType===d&&p.componentId!==s&&r(p.componentId,a*.4);for(let d of t.values())d.depth===o.depth+1&&r(d.componentId,a*.6);for(let d of t.values())d.semanticType===o.semanticType&&d.componentId!==s&&r(d.componentId,a*-.2);i()},snapshot(){return{pageNodes:[...t.values()],userEdges:[...n.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()],userEdges:[...n.values()]})},restore:c,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(y),localStorage.removeItem(S)}catch(s){}}}}function V(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function ne(e){let t=E(e);if(!e.graph||typeof window=="undefined")return t;let n=C(),i=I({syncUrl:e.ingestUrl.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:V()});try{let c=localStorage.getItem("_snt_graph_nodes"),r=localStorage.getItem("_snt_graph_edges");(c||r)&&i.restore(JSON.stringify({pageNodes:c?JSON.parse(c):[],userEdges:r?JSON.parse(r):[]}))}catch(c){}return n.scan().then(c=>{for(let r of c.nodes)i.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});i.syncOnce()}),n.observe(c=>{for(let r of c.nodes)i.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth})}),b(g({},t),{getGraph:()=>i.snapshot(),destroy:()=>{n.destroy(),i.destroy(),t.destroy()}})}export{D as deriveSessionSegment,x as detectDeviceClass,U as detectTimeOfDay,O as detectTrafficSource,ne as init,R as preloadAssignments,P as readSessionCookie,_ as referrerDomainFromReferer};
1
+ import{a as h,b,c as x,d as _,e as O,f as M,g as R,h as P,i as D,j as v}from"./chunk-FYITIEH3.mjs";var G=new Set(["SECTION","ARTICLE","MAIN","DIV"]),k="h1, h2, h3",$={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function S(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function L(e){var t,n,p;try{let d=e;for(let s of Object.keys(d)){if(!s.startsWith("__reactFiber")&&!s.startsWith("__reactInternalInstance"))continue;let o=d[s],r=(p=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?p:(n=o==null?void 0:o.type)==null?void 0:n.name;if(r&&r.length>1)return r}}catch(d){}}function U(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function j(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function F(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function K(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function I(e,t){var p,d,s;let n=e.querySelector(k);return{componentId:F(e),semanticType:j(e),ariaLabel:(p=e.getAttribute("aria-label"))!=null?p:void 0,headingText:(s=(d=n==null?void 0:n.textContent)==null?void 0:d.trim())!=null?s:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:K(e),reactComponentName:L(e),dataAttributes:U(e)}}function w(e){var s;let t=[],n=new Set,p="__root__",d=new Map;for(let[o,r]of e){let a=o.parentElement,c=p;for(;a;){if(e.has(a)){c=e.get(a);let m=e.get(o),g=`${c}->${m}`;!n.has(g)&&c!==m&&(n.add(g),t.push({fromComponentId:c,toComponentId:m,weight:.6}));break}a=a.parentElement}let u=(s=d.get(c))!=null?s:[];u.push(o),d.set(c,u)}for(let o of d.values())if(!(o.length<2))for(let r=0;r<o.length;r++)for(let a=r+1;a<o.length;a++){let c=e.get(o[r]),u=e.get(o[a]);if(c===u)continue;let m=`${c}->${u}::sib`,g=`${u}->${c}::sib`;n.has(m)||(n.add(m),t.push({fromComponentId:c,toComponentId:u,weight:.3})),n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:c,weight:.3}))}return t}function q(e){let t=[],n=new Set,p=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let r=I(o,e);t.push(r),p.set(o,r.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let r=o.hasAttribute("aria-label"),a=o.hasAttribute("data-sentient-id");if(!r&&!a)return;n.add(o);let c=I(o,e);t.push(c),p.set(o,c.componentId)}),{nodes:t,edges:w(p)}}function N(){if(typeof window=="undefined")return $;let e=null,t=0,n=null,p=r=>{try{let a=window.getComputedStyle(r),c=parseFloat(a.fontSize)||12,u=parseFloat(a.zIndex)||0,m=r.getBoundingClientRect(),g=Math.max(m.top,0),i=window.innerHeight||1,f=1/(g/i+1),l=S(c,12,48)*.4+S(f,0,1)*.4+S(u,0,100)*.2;return Math.max(0,Math.min(1,l))}catch(a){return .5}};return{scan:()=>new Promise(r=>{let a=()=>{let{nodes:c,edges:u}=q(p);r({nodes:c,edges:u,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(a,{timeout:100}):a()}catch(c){a()}}),observe:r=>{n=r;try{e=new MutationObserver(a=>{let c=[],u=new Map;for(let m of a)m.type==="childList"&&m.addedNodes.forEach(g=>{if(!(g instanceof Element)||!G.has(g.tagName))return;let i=g.hasAttribute("data-sentient-id"),f=g.hasAttribute("aria-label");if(!i&&!f)return;let l=I(g,p);c.push(l),u.set(g,l.componentId)});c.length>0&&n&&n({nodes:c,edges:w(u),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(a){}},getProminenceScore:p,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(r){}t=0,n=null}}}var C="_snt_graph_nodes",A="_snt_graph_edges",z={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function H(e){var t;return(t=z[e])!=null?t:[]}function J(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function B(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var V=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function W(e){return V.has(e)?e:"generic"}function Y(e,t,n){let p=`${e}:${t}:${n.join(",")}`,d=5381;for(let s=0;s<p.length;s++)d=(d<<5)+d+p.charCodeAt(s)&4294967295;return(d>>>0).toString(16).padStart(8,"0")}function T(e){let t=new Map,n=new Map,p=()=>{typeof window!="undefined"&&B(C,[...t.values()])},d=s=>{var o;try{let r=JSON.parse(s);t.clear();for(let a of(o=r.pageNodes)!=null?o:[])t.set(a.componentId,a)}catch(r){}};if(typeof window!="undefined"){let s=J(C,[]);for(let o of s)t.set(o.componentId,o);try{localStorage.removeItem(A)}catch(o){}}return{addPageNode(s){t.set(s.componentId,s),p()},addStructuralEdge(s){let o=`${s.fromComponentId}->${s.toComponentId}`;n.set(o,s)},syncOnce(){var o,r;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let s=[...t.values()];if(s.length!==0)try{let a=new Map;for(let i of s){let f=(o=a.get(i.semanticType))!=null?o:[];f.push(i),a.set(i.semanticType,f)}let c=[],u=new Set;for(let i of s)for(let f of H(i.semanticType)){let l=(r=a.get(f))!=null?r:[];for(let y of l){if(y.componentId===i.componentId)continue;let E=`semantic:${i.componentId}->${y.componentId}`;u.has(E)||(u.add(E),c.push({fromComponentId:i.componentId,toComponentId:y.componentId,type:"semantic",weight:.4,confidence:.9}))}}let m=new Set(s.map(i=>i.componentId));for(let i of n.values()){if(!m.has(i.fromComponentId)||!m.has(i.toComponentId))continue;let f=`structural:${i.fromComponentId}->${i.toComponentId}`;u.has(f)||(u.add(f),c.push({fromComponentId:i.fromComponentId,toComponentId:i.toComponentId,type:"structural",weight:i.weight,confidence:1}))}let g={pageUrl:window.location.href,nodes:s.map(i=>{let f=W(i.semanticType);return{componentId:i.componentId,semanticType:f,answers:i.answers,contentHash:Y(i.componentId,f,i.answers),prominenceScore:i.prominenceScore,depthInPage:i.depth}}),edges:c};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:h({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(g)}).catch(()=>{})}catch(a){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:d,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(C),localStorage.removeItem(A)}catch(s){}}}}var Q="https://sentient-api.fly.dev/v1/events";function X(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function se(e){var s;let t=v(e);if(!e.graph||typeof window=="undefined")return t;let n=N(),p=(s=e.ingestUrl)!=null?s:Q,d=T({syncUrl:p.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:X()});try{let o=localStorage.getItem("_snt_graph_nodes");o&&d.restore(JSON.stringify({pageNodes:JSON.parse(o)}))}catch(o){}return n.scan().then(o=>{for(let r of o.nodes)d.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of o.edges)d.addStructuralEdge(r);d.syncOnce()}),n.observe(o=>{for(let r of o.nodes)d.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of o.edges)d.addStructuralEdge(r)}),b(h({},t),{getGraph:()=>d.snapshot(),destroy:()=>{n.destroy(),d.destroy(),t.destroy()}})}export{R as deriveSessionSegment,x as detectDeviceClass,M as detectTimeOfDay,_ as detectTrafficSource,se as init,P as preloadAssignments,D as readSessionCookie,O as referrerDomainFromReferer};
package/dist/index.d.cts CHANGED
@@ -10,7 +10,7 @@ type SessionManager = {
10
10
  destroy(): void;
11
11
  };
12
12
 
13
- /** Batched event queue with reliable transport (beacon fetch localStorage retry). */
13
+ /** Batched event queue with reliable transport (fetch + keepalive, localStorage retry). */
14
14
  type EventType = 'variant_assigned' | 'goal_achieved' | 'scroll_depth' | 'dwell' | 'cursor_signal' | 'component_visible' | 'component_exited';
15
15
  type SentientEvent = {
16
16
  id: string;
@@ -63,12 +63,20 @@ type ScannedNode = {
63
63
  reactComponentName?: string;
64
64
  dataAttributes: Record<string, string>;
65
65
  };
66
+ type StructuralEdge$1 = {
67
+ fromComponentId: string;
68
+ toComponentId: string;
69
+ /** 0.6 for direct parent → child, 0.3 for sibling (both directions emitted). */
70
+ weight: number;
71
+ };
66
72
  type ScanResult = {
67
73
  nodes: ScannedNode[];
74
+ edges: StructuralEdge$1[];
68
75
  scannedAt: number;
69
76
  };
70
77
  type ContentAddedEvent = {
71
78
  nodes: ScannedNode[];
79
+ edges: StructuralEdge$1[];
72
80
  addedAt: number;
73
81
  };
74
82
  type DOMScanner = {
@@ -87,16 +95,8 @@ type PageNode = {
87
95
  prominenceScore: number;
88
96
  depth: number;
89
97
  };
90
- type UserEdge = {
91
- componentId: string;
92
- attentionWeight: number;
93
- interactionCount: number;
94
- dwellTime: number;
95
- lastUpdated: number;
96
- };
97
98
  type GraphSnapshot = {
98
99
  pageNodes: PageNode[];
99
- userEdges: UserEdge[];
100
100
  capturedAt: number;
101
101
  };
102
102
  type GraphConfig = {
@@ -105,10 +105,15 @@ type GraphConfig = {
105
105
  projectId?: string;
106
106
  sessionId?: string;
107
107
  };
108
+ type StructuralEdge = {
109
+ fromComponentId: string;
110
+ toComponentId: string;
111
+ weight: number;
112
+ };
108
113
  type GraphClient = {
109
114
  addPageNode(node: PageNode): void;
110
- updateUserEdge(componentId: string, attentionDelta: number): void;
111
- propagate(componentId: string, delta: number): void;
115
+ /** Record a DOM-derived parent/child or sibling relationship between two components. */
116
+ addStructuralEdge(edge: StructuralEdge): void;
112
117
  /** One-shot batch sync of all current page nodes to the backend. */
113
118
  syncOnce(): void;
114
119
  snapshot(): GraphSnapshot;
@@ -187,7 +192,8 @@ declare function readSessionCookie(cookies: {
187
192
  type SentientConfig = {
188
193
  apiKey: string;
189
194
  context: 'landing' | 'ecommerce' | 'saas' | 'marketplace';
190
- ingestUrl: string;
195
+ /** @internal — not exposed to users; defaults to the hosted SentientUI API. */
196
+ ingestUrl?: string;
191
197
  debug?: boolean;
192
198
  /**
193
199
  * Pre-seeded assignments from `preloadAssignments()` (SSR).
@@ -225,4 +231,4 @@ type SentientClient = {
225
231
  */
226
232
  declare function init(config: SentientConfig): SentientClient;
227
233
 
228
- export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, type UserEdge, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, readSessionCookie, referrerDomainFromReferer };
234
+ export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, readSessionCookie, referrerDomainFromReferer };
package/dist/index.d.ts CHANGED
@@ -10,7 +10,7 @@ type SessionManager = {
10
10
  destroy(): void;
11
11
  };
12
12
 
13
- /** Batched event queue with reliable transport (beacon fetch localStorage retry). */
13
+ /** Batched event queue with reliable transport (fetch + keepalive, localStorage retry). */
14
14
  type EventType = 'variant_assigned' | 'goal_achieved' | 'scroll_depth' | 'dwell' | 'cursor_signal' | 'component_visible' | 'component_exited';
15
15
  type SentientEvent = {
16
16
  id: string;
@@ -63,12 +63,20 @@ type ScannedNode = {
63
63
  reactComponentName?: string;
64
64
  dataAttributes: Record<string, string>;
65
65
  };
66
+ type StructuralEdge$1 = {
67
+ fromComponentId: string;
68
+ toComponentId: string;
69
+ /** 0.6 for direct parent → child, 0.3 for sibling (both directions emitted). */
70
+ weight: number;
71
+ };
66
72
  type ScanResult = {
67
73
  nodes: ScannedNode[];
74
+ edges: StructuralEdge$1[];
68
75
  scannedAt: number;
69
76
  };
70
77
  type ContentAddedEvent = {
71
78
  nodes: ScannedNode[];
79
+ edges: StructuralEdge$1[];
72
80
  addedAt: number;
73
81
  };
74
82
  type DOMScanner = {
@@ -87,16 +95,8 @@ type PageNode = {
87
95
  prominenceScore: number;
88
96
  depth: number;
89
97
  };
90
- type UserEdge = {
91
- componentId: string;
92
- attentionWeight: number;
93
- interactionCount: number;
94
- dwellTime: number;
95
- lastUpdated: number;
96
- };
97
98
  type GraphSnapshot = {
98
99
  pageNodes: PageNode[];
99
- userEdges: UserEdge[];
100
100
  capturedAt: number;
101
101
  };
102
102
  type GraphConfig = {
@@ -105,10 +105,15 @@ type GraphConfig = {
105
105
  projectId?: string;
106
106
  sessionId?: string;
107
107
  };
108
+ type StructuralEdge = {
109
+ fromComponentId: string;
110
+ toComponentId: string;
111
+ weight: number;
112
+ };
108
113
  type GraphClient = {
109
114
  addPageNode(node: PageNode): void;
110
- updateUserEdge(componentId: string, attentionDelta: number): void;
111
- propagate(componentId: string, delta: number): void;
115
+ /** Record a DOM-derived parent/child or sibling relationship between two components. */
116
+ addStructuralEdge(edge: StructuralEdge): void;
112
117
  /** One-shot batch sync of all current page nodes to the backend. */
113
118
  syncOnce(): void;
114
119
  snapshot(): GraphSnapshot;
@@ -187,7 +192,8 @@ declare function readSessionCookie(cookies: {
187
192
  type SentientConfig = {
188
193
  apiKey: string;
189
194
  context: 'landing' | 'ecommerce' | 'saas' | 'marketplace';
190
- ingestUrl: string;
195
+ /** @internal — not exposed to users; defaults to the hosted SentientUI API. */
196
+ ingestUrl?: string;
191
197
  debug?: boolean;
192
198
  /**
193
199
  * Pre-seeded assignments from `preloadAssignments()` (SSR).
@@ -225,4 +231,4 @@ type SentientClient = {
225
231
  */
226
232
  declare function init(config: SentientConfig): SentientClient;
227
233
 
228
- export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, type UserEdge, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, readSessionCookie, referrerDomainFromReferer };
234
+ export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, readSessionCookie, referrerDomainFromReferer };
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- "use strict";var O=Object.defineProperty,X=Object.defineProperties,H=Object.getOwnPropertyDescriptor,V=Object.getOwnPropertyDescriptors,Z=Object.getOwnPropertyNames,K=Object.getOwnPropertySymbols;var Q=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var N=(e,t,n)=>t in e?O(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,F=(e,t)=>{for(var n in t||(t={}))Q.call(t,n)&&N(e,n,t[n]);if(K)for(var n of K(t))ee.call(t,n)&&N(e,n,t[n]);return e},G=(e,t)=>X(e,V(t));var te=(e,t)=>{for(var n in t)O(e,n,{get:t[n],enumerable:!0})},ne=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of Z(t))!Q.call(e,r)&&r!==n&&O(e,r,{get:()=>t[r],enumerable:!(o=H(t,r))||o.enumerable});return e};var re=e=>ne(O({},"__esModule",{value:!0}),e);var _e={};te(_e,{deriveSessionSegment:()=>j,detectDeviceClass:()=>k,detectTimeOfDay:()=>D,detectTrafficSource:()=>C,init:()=>Ee,preloadAssignments:()=>W,readSessionCookie:()=>Y,referrerDomainFromReferer:()=>x});module.exports=re(_e);var se="_snt_uid";var b="_snt_uid";function ie(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function oe(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ae(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(o){}}function ce(e){try{return localStorage.getItem(e)}catch(t){return null}}function ue(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function de(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function le(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function ge(e){try{sessionStorage.removeItem(e)}catch(t){}}function me(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function fe(e){try{localStorage.removeItem(e)}catch(t){}}function pe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var ye={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function B(e){var g,d,p,v,w;if(typeof window=="undefined")return ye;let t=(g=e==null?void 0:e.cookieName)!=null?g:se,o=((d=e==null?void 0:e.cookieTTLDays)!=null?d:365)*24*60*60,r=(w=(v=(p=oe(t))!=null?p:ce(b))!=null?v:de(b))!=null?w:ie();ae(t,r,o);let a=ue(b,r),s=me(t),i=a?!1:le(b,r),u=!a&&!s&&!i;return{getSessionId:()=>r,isEphemeral:()=>u,destroy:()=>{r=null,pe(t),fe(b),ge(b)}}}var U="_snt_retry";var Se={push:()=>{},flush:()=>{},destroy:()=>{}};function he(e){try{let t=localStorage.getItem(U);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(U),n.slice(-e)):[]}catch(t){return[]}}function ve(e,t){try{let o=[...(()=>{try{let r=localStorage.getItem(U);if(!r)return[];let a=JSON.parse(r);return Array.isArray(a)?a:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(U,JSON.stringify(o))}catch(n){}}function z(e){var h,_,I;if(typeof window=="undefined")return Se;let t=(h=e.flushIntervalMs)!=null?h:5e3,n=(_=e.maxBatchSize)!=null?_:20,o=(I=e.maxRetrySize)!=null?I:100,r=e.ingestUrl,a=e.apiKey,s=[],i=new Set,u=[],g=c=>{for(let m of c)i.has(m)||(i.add(m),u.push(m));for(;u.length>500;){let m=u.shift();m&&i.delete(m)}},d=new Set,p=c=>{i.has(c.id)||d.has(c.id)||(d.add(c.id),s.push(c))},v=he(o);for(let c of v)p(c);let w=c=>{if(c.length===0)return!0;let m=JSON.stringify(c);try{return fetch(r,{method:"POST",keepalive:!0,body:m,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}}),g(c.map(T=>T.id)),!0}catch(T){return ve(c,o),!1}},y=()=>{try{for(;s.length>0;){let m=s.splice(0,n).filter(q=>!i.has(q.id));if(m.length===0)continue;if(!w(m)){s.unshift(...m);break}}}catch(c){}},A=!0,S=null,E=()=>{if(!A)return;let c=Date.now()+t,m=()=>{if(A){if(Date.now()>=c){y(),E();return}try{S=new MessageChannel,S.port1.onmessage=m,S.port2.postMessage(null)}catch(T){}}};m()},l=()=>{document.visibilityState==="hidden"&&y()},f=()=>{y()};return document.addEventListener("visibilitychange",l),window.addEventListener("beforeunload",f),E(),{push(c){p(c),s.length>=n&&y()},flush:y,destroy(){A=!1,document.removeEventListener("visibilitychange",l),window.removeEventListener("beforeunload",f),S&&(S.port1.onmessage=null,S=null),y()}}}var $="_snt_asgn_";function R(e,t){return`${e}:${t}`}function we(e,t){return`${$}${e}_${t}`}function L(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith($)&&e.push(n)}return e}catch(e){return[]}}function J(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of L())try{let a=localStorage.getItem(r);if(!a)continue;let s=JSON.parse(a);if(n(s)){localStorage.removeItem(r);continue}let i=r.slice($.length),u=i.lastIndexOf("_");if(u<0)continue;let g=i.slice(0,u),d=i.slice(u+1);t.set(R(g,d),s)}catch(a){}})(),{get(r,a){let s=t.get(R(r,a));return s?n(s)?(t.delete(R(r,a)),null):s:null},set(r,a,s){let i=R(r,a);t.set(i,s);try{localStorage.setItem(we(r,a),JSON.stringify(s))}catch(u){}},invalidate(r){let a=`${r}:`;for(let s of[...t.keys()])s.startsWith(a)&&t.delete(s);for(let s of L()){let i=s.slice($.length),u=i.lastIndexOf("_");if(u<0)continue;if(i.slice(0,u)===r)try{localStorage.removeItem(s)}catch(d){}}},clear(){t.clear();for(let r of L())try{localStorage.removeItem(r)}catch(a){}}}}function k(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function C(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let o=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(o)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(o)?"social":"referral"}catch(n){return"direct"}}function x(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function D(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function j(e){let t=M("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function M(e,t){var a,s,i,u,g,d,p;let n=(s=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?s:"",o=(u=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?u:"",r=(g=t==null?void 0:t.now)!=null?g:new Date;return{sessionId:e,ephemeral:!1,utmParams:(d=t==null?void 0:t.utmParams)!=null?d:{},deviceClass:n?k(n):"desktop",trafficSource:o?C(o,t==null?void 0:t.appOrigin):"direct",referrerDomain:x(o),timeOfDay:D(r),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?p:"sun"}}async function W(e,t,n){let o={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(o.Origin=n.origin);let r=M(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(r)})}catch(i){}let a=await Promise.allSettled(e.map(async({id:i,variantIds:u})=>{let g=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:t,componentId:i,variantIds:u})});if(!g.ok)return null;let d=await g.json();return{id:i,variantId:d.variantId}})),s={};for(let i of a)i.status==="fulfilled"&&i.value&&(s[i.value.id]=i.value.variantId);return s}function Y(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}function Ae(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var P={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],userEdges:[],capturedAt:0}),destroy:()=>{}};function Ie(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,o]of t)n.startsWith("utm_")&&(e[n]=o);return e}catch(e){return{}}}function be(e){return e.replace(/\/events\/?$/,"")}function Ee(e){var y,A,S,E;if(typeof window=="undefined"||e.consent===!1)return P;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),P;if(!e.ingestUrl)return console.warn("[sentient] init() called without ingestUrl. SDK disabled."),P;let t=Date.now(),n=B(),o=J(),r=z({ingestUrl:e.ingestUrl,apiKey:e.apiKey}),a=be(e.ingestUrl),s={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i=k((y=navigator.userAgent)!=null?y:""),u=typeof window!="undefined"?window.location.origin:void 0,g=C((A=document.referrer)!=null?A:"",u),d=(S=e.sessionSegment)!=null?S:`${i}:${g}`;if(e.initialAssignments)for(let[l,f]of Object.entries(e.initialAssignments))o.set(l,d,{variantId:f,assignedAt:Date.now(),segment:d,confidence:1});let p=Promise.resolve(),v=n.getSessionId();if(v){let l=x((E=document.referrer)!=null?E:""),f={sessionId:v,deviceClass:i,trafficSource:g,referrerDomain:l,utmParams:Ie(),timeOfDay:D(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:n.isEphemeral()};try{p=fetch(`${a}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(f),headers:s}).then(()=>{}).catch(()=>{})}catch(h){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:r});let w={track(l){let f=n.getSessionId();if(!f)return;let h=G(F({},l),{id:Ae(),sessionId:f,timestamp:Date.now(),timeInSession:Date.now()-t});r.push(h),e.debug&&console.log("[sentient] track",h)},getAssignment(l,f){return o.get(l,f)},async assign(l,f){let h=n.getSessionId();if(!h)return null;let _=o.get(l,d);if(_)return{variantId:_.variantId,assignmentTtlMs:0};await p;try{let I=await fetch(`${a}/assign`,{method:"POST",body:JSON.stringify({sessionId:h,componentId:l,variantIds:f}),headers:s});if(!I.ok)return null;let c=await I.json();return o.set(l,d,{variantId:c.variantId,assignedAt:Date.now(),segment:d,confidence:1}),c}catch(I){return null}},getGraph(){return{pageNodes:[],userEdges:[],capturedAt:0}},destroy(){r.destroy(),n.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let l=window;l.__sentient&&(l.__sentient.client=w)}return w}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
1
+ "use strict";var $=Object.defineProperty,te=Object.defineProperties,ne=Object.getOwnPropertyDescriptor,re=Object.getOwnPropertyDescriptors,se=Object.getOwnPropertyNames,z=Object.getOwnPropertySymbols;var j=Object.prototype.hasOwnProperty,ie=Object.prototype.propertyIsEnumerable;var J=(e,t,n)=>t in e?$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,W=(e,t)=>{for(var n in t||(t={}))j.call(t,n)&&J(e,n,t[n]);if(z)for(var n of z(t))ie.call(t,n)&&J(e,n,t[n]);return e},Y=(e,t)=>te(e,re(t));var oe=(e,t)=>{for(var n in t)$(e,n,{get:t[n],enumerable:!0})},ae=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of se(t))!j.call(e,r)&&r!==n&&$(e,r,{get:()=>t[r],enumerable:!(i=ne(t,r))||i.enumerable});return e};var ce=e=>ae($({},"__esModule",{value:!0}),e);var De={};oe(De,{deriveSessionSegment:()=>H,detectDeviceClass:()=>D,detectTimeOfDay:()=>R,detectTrafficSource:()=>U,init:()=>Ce,preloadAssignments:()=>Z,readSessionCookie:()=>ee,referrerDomainFromReferer:()=>O});module.exports=ce(De);var ue="_snt_uid";var k="_snt_uid";function le(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function de(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ge(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function me(e){try{return localStorage.getItem(e)}catch(t){return null}}function fe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function pe(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function ye(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Se(e){try{sessionStorage.removeItem(e)}catch(t){}}function he(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function ve(e){try{localStorage.removeItem(e)}catch(t){}}function Ie(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var we={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function q(e){var m,g,f,I,y;if(typeof window=="undefined")return we;let t=(m=e==null?void 0:e.cookieName)!=null?m:ue,i=((g=e==null?void 0:e.cookieTTLDays)!=null?g:365)*24*60*60,r=(y=(I=(f=de(t))!=null?f:me(k))!=null?I:pe(k))!=null?y:le();ge(t,r,i);let a=fe(k,r),s=he(t),o=a?!1:ye(k,r),u=!a&&!s&&!o;return{getSessionId:()=>r,isEphemeral:()=>u,destroy:()=>{r=null,Ie(t),ve(k),Se(k)}}}var M="_snt_retry";var Ae={push:()=>{},flush:()=>{},destroy:()=>{}};function Ee(e){try{let t=localStorage.getItem(M);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(M),n.slice(-e)):[]}catch(t){return[]}}function Q(e,t){try{let i=[...(()=>{try{let r=localStorage.getItem(M);if(!r)return[];let a=JSON.parse(r);return Array.isArray(a)?a:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(M,JSON.stringify(i))}catch(n){}}function V(e){var S,T,_;if(typeof window=="undefined")return Ae;let t=(S=e.flushIntervalMs)!=null?S:5e3,n=(T=e.maxBatchSize)!=null?T:20,i=(_=e.maxRetrySize)!=null?_:100,r=e.ingestUrl,a=e.apiKey,s=[],o=new Set,u=[],m=c=>{for(let l of c)o.has(l)||(o.add(l),u.push(l));for(;u.length>500;){let l=u.shift();l&&o.delete(l)}},g=new Set,f=c=>{o.has(c.id)||g.has(c.id)||(g.add(c.id),s.push(c))},I=Ee(i);for(let c of I)f(c);let y=0,h=0,P=c=>{if(c.length===0)return;let l=JSON.stringify(c),b=c.map(E=>E.id),A;try{A=fetch(r,{method:"POST",keepalive:!0,body:l,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(E){Q(c,i),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6));return}let C=E=>{if(E.ok||E.status>=400&&E.status<500&&E.status!==429){m(b),h=0,y=0;return}Q(c,i),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6))};A instanceof Promise?A.then(C).catch(()=>{Q(c,i),h++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(h,6))}):C(A)},L=c=>{let l=[],b=2;for(let A of c){let C=JSON.stringify(A).length+1;if(l.length>0&&b+C>57344||l.length>=n)break;l.push(A),b+=C}return l},v=()=>{try{if(Date.now()<y)return;for(;s.length>0;){let c=s.filter(b=>!o.has(b.id));if(s.length=0,c.length===0)break;let l=L(c);if(l.length===0)break;l.length<c.length&&s.push(...c.slice(l.length)),P(l)}}catch(c){}},x=!0,w=null;w=setInterval(()=>{x&&v()},t);let d=()=>{document.visibilityState==="hidden"&&v()},p=()=>{v()};return document.addEventListener("visibilitychange",d),window.addEventListener("beforeunload",p),{push(c){f(c),s.length>=n&&v()},flush:v,destroy(){x=!1,w!==null&&(clearInterval(w),w=null),document.removeEventListener("visibilitychange",d),window.removeEventListener("beforeunload",p),v()}}}var N="_snt_asgn_";function K(e,t){return`${e}:${t}`}function _e(e,t){return`${N}${e}_${t}`}function G(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(N)&&e.push(n)}return e}catch(e){return[]}}function X(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of G())try{let a=localStorage.getItem(r);if(!a)continue;let s=JSON.parse(a);if(n(s)){localStorage.removeItem(r);continue}let o=r.slice(N.length),u=o.lastIndexOf("_");if(u<0)continue;let m=o.slice(0,u),g=o.slice(u+1);t.set(K(m,g),s)}catch(a){}})(),{get(r,a){let s=t.get(K(r,a));return s?n(s)?(t.delete(K(r,a)),null):s:null},set(r,a,s){let o=K(r,a);t.set(o,s);try{localStorage.setItem(_e(r,a),JSON.stringify(s))}catch(u){}},invalidate(r){let a=`${r}:`;for(let s of[...t.keys()])s.startsWith(a)&&t.delete(s);for(let s of G()){let o=s.slice(N.length),u=o.lastIndexOf("_");if(u<0)continue;if(o.slice(0,u)===r)try{localStorage.removeItem(s)}catch(g){}}},clear(){t.clear();for(let r of G())try{localStorage.removeItem(r)}catch(a){}}}}function D(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function U(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let i=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(i)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(i)?"social":"referral"}catch(n){return"direct"}}function O(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function R(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function H(e){let t=F("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function F(e,t){var a,s,o,u,m,g,f;let n=(s=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?s:"",i=(u=(o=t==null?void 0:t.referer)==null?void 0:o.trim())!=null?u:"",r=(m=t==null?void 0:t.now)!=null?m:new Date;return{sessionId:e,ephemeral:!1,utmParams:(g=t==null?void 0:t.utmParams)!=null?g:{},deviceClass:n?D(n):"desktop",trafficSource:i?U(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:O(i),timeOfDay:R(r),dayOfWeek:(f=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?f:"sun"}}async function Z(e,t,n){let i={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(i.Origin=n.origin);let r=F(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:i,body:JSON.stringify(r)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(o){}let a=await Promise.allSettled(e.map(async({id:o,variantIds:u})=>{let m=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:i,body:JSON.stringify({sessionId:t,componentId:o,variantIds:u})});if(!m.ok)return null;let g=await m.json();return{id:o,variantId:g.variantId}})),s={};for(let o of a)o.status==="fulfilled"&&o.value&&(s[o.value.id]=o.value.variantId);return s}function ee(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}var be="https://sentient-api.fly.dev/v1/events";function ke(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var B={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function xe(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,i]of t)n.startsWith("utm_")&&(e[n]=i);return e}catch(e){return{}}}function Te(e){return e.replace(/\/events\/?$/,"")}function Ce(e){var P,L,v,x,w;if(typeof window=="undefined"||e.consent===!1)return B;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),B;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),B;let t=(P=e.ingestUrl)!=null?P:be,n=Date.now(),i=q(),r=X(),a=V({ingestUrl:t,apiKey:e.apiKey}),s=Te(t),o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u=D((L=navigator.userAgent)!=null?L:""),m=typeof window!="undefined"?window.location.origin:void 0,g=U((v=document.referrer)!=null?v:"",m),f=(x=e.sessionSegment)!=null?x:`${u}:${g}`;if(e.initialAssignments)for(let[d,p]of Object.entries(e.initialAssignments))r.set(d,f,{variantId:p,assignedAt:Date.now(),segment:f,confidence:1});let I=Promise.resolve(),y=i.getSessionId();if(y){let d=O((w=document.referrer)!=null?w:""),p={sessionId:y,deviceClass:u,trafficSource:g,referrerDomain:d,utmParams:xe(),timeOfDay:R(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:i.isEphemeral()};try{I=fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(p),headers:o}).then(S=>{S.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(S){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:a});let h={track(d){let p=i.getSessionId();if(!p)return;let S=Y(W({},d),{id:ke(),sessionId:p,timestamp:Date.now(),timeInSession:Date.now()-n});a.push(S),e.debug&&console.log("[sentient] track",S)},getAssignment(d,p){return r.get(d,p)},async assign(d,p){let S=i.getSessionId();if(!S)return null;let T=r.get(d,f);if(T)return{variantId:T.variantId,assignmentTtlMs:0};await I;try{let _=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify({sessionId:S,componentId:d,variantIds:p}),headers:o});if(!_.ok)return null;let c=await _.json();return r.set(d,f,{variantId:c.variantId,assignedAt:Date.now(),segment:f,confidence:1}),c}catch(_){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){a.destroy(),i.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let d=window;d.__sentient&&(d.__sentient.client=h)}return h}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
package/dist/index.mjs CHANGED
@@ -1 +1 @@
1
- import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h}from"./chunk-HRRGYUE4.mjs";export{e as deriveSessionSegment,a as detectDeviceClass,d as detectTimeOfDay,b as detectTrafficSource,h as init,f as preloadAssignments,g as readSessionCookie,c as referrerDomainFromReferer};
1
+ import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h}from"./chunk-FYITIEH3.mjs";export{e as deriveSessionSegment,a as detectDeviceClass,d as detectTimeOfDay,b as detectTrafficSource,h as init,f as preloadAssignments,g as readSessionCookie,c as referrerDomainFromReferer};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentientui/core",
3
- "version": "0.1.0",
3
+ "version": "0.2.1",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -21,6 +21,13 @@
21
21
  "files": [
22
22
  "dist"
23
23
  ],
24
+ "scripts": {
25
+ "build": "tsup",
26
+ "test": "vitest run",
27
+ "typecheck": "tsc --noEmit",
28
+ "size-check": "tsx scripts/size-check.ts",
29
+ "lint": "eslint src"
30
+ },
24
31
  "devDependencies": {
25
32
  "@types/node": "^22.10.2",
26
33
  "jsdom": "^25.0.1",
@@ -28,12 +35,5 @@
28
35
  "tsx": "^4.19.2",
29
36
  "typescript": "^5.7.2",
30
37
  "vitest": "^2.1.8"
31
- },
32
- "scripts": {
33
- "build": "tsup",
34
- "test": "vitest run",
35
- "typecheck": "tsc --noEmit",
36
- "size-check": "tsx scripts/size-check.ts",
37
- "lint": "eslint src"
38
38
  }
39
- }
39
+ }
@@ -1 +0,0 @@
1
- var J=Object.defineProperty,j=Object.defineProperties;var W=Object.getOwnPropertyDescriptors;var M=Object.getOwnPropertySymbols;var Y=Object.prototype.hasOwnProperty,q=Object.prototype.propertyIsEnumerable;var K=(e,t,n)=>t in e?J(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,N=(e,t)=>{for(var n in t||(t={}))Y.call(t,n)&&K(e,n,t[n]);if(M)for(var n of M(t))q.call(t,n)&&K(e,n,t[n]);return e},Q=(e,t)=>j(e,W(t));var X="_snt_uid";var b="_snt_uid";function H(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function V(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function Z(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(a){}}function ee(e){try{return localStorage.getItem(e)}catch(t){return null}}function te(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ne(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function re(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function se(e){try{sessionStorage.removeItem(e)}catch(t){}}function ie(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function oe(e){try{localStorage.removeItem(e)}catch(t){}}function ae(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var ce={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function F(e){var g,d,p,v,w;if(typeof window=="undefined")return ce;let t=(g=e==null?void 0:e.cookieName)!=null?g:X,a=((d=e==null?void 0:e.cookieTTLDays)!=null?d:365)*24*60*60,r=(w=(v=(p=V(t))!=null?p:ee(b))!=null?v:ne(b))!=null?w:H();Z(t,r,a);let o=te(b,r),s=ie(t),i=o?!1:re(b,r),u=!o&&!s&&!i;return{getSessionId:()=>r,isEphemeral:()=>u,destroy:()=>{r=null,ae(t),oe(b),se(b)}}}var C="_snt_retry";var ue={push:()=>{},flush:()=>{},destroy:()=>{}};function de(e){try{let t=localStorage.getItem(C);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(C),n.slice(-e)):[]}catch(t){return[]}}function le(e,t){try{let a=[...(()=>{try{let r=localStorage.getItem(C);if(!r)return[];let o=JSON.parse(r);return Array.isArray(o)?o:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(C,JSON.stringify(a))}catch(n){}}function G(e){var h,_,I;if(typeof window=="undefined")return ue;let t=(h=e.flushIntervalMs)!=null?h:5e3,n=(_=e.maxBatchSize)!=null?_:20,a=(I=e.maxRetrySize)!=null?I:100,r=e.ingestUrl,o=e.apiKey,s=[],i=new Set,u=[],g=c=>{for(let m of c)i.has(m)||(i.add(m),u.push(m));for(;u.length>500;){let m=u.shift();m&&i.delete(m)}},d=new Set,p=c=>{i.has(c.id)||d.has(c.id)||(d.add(c.id),s.push(c))},v=de(a);for(let c of v)p(c);let w=c=>{if(c.length===0)return!0;let m=JSON.stringify(c);try{return fetch(r,{method:"POST",keepalive:!0,body:m,headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`}}),g(c.map(k=>k.id)),!0}catch(k){return le(c,a),!1}},y=()=>{try{for(;s.length>0;){let m=s.splice(0,n).filter(z=>!i.has(z.id));if(m.length===0)continue;if(!w(m)){s.unshift(...m);break}}}catch(c){}},A=!0,S=null,E=()=>{if(!A)return;let c=Date.now()+t,m=()=>{if(A){if(Date.now()>=c){y(),E();return}try{S=new MessageChannel,S.port1.onmessage=m,S.port2.postMessage(null)}catch(k){}}};m()},l=()=>{document.visibilityState==="hidden"&&y()},f=()=>{y()};return document.addEventListener("visibilitychange",l),window.addEventListener("beforeunload",f),E(),{push(c){p(c),s.length>=n&&y()},flush:y,destroy(){A=!1,document.removeEventListener("visibilitychange",l),window.removeEventListener("beforeunload",f),S&&(S.port1.onmessage=null,S=null),y()}}}var D="_snt_asgn_";function x(e,t){return`${e}:${t}`}function ge(e,t){return`${D}${e}_${t}`}function P(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(D)&&e.push(n)}return e}catch(e){return[]}}function B(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of P())try{let o=localStorage.getItem(r);if(!o)continue;let s=JSON.parse(o);if(n(s)){localStorage.removeItem(r);continue}let i=r.slice(D.length),u=i.lastIndexOf("_");if(u<0)continue;let g=i.slice(0,u),d=i.slice(u+1);t.set(x(g,d),s)}catch(o){}})(),{get(r,o){let s=t.get(x(r,o));return s?n(s)?(t.delete(x(r,o)),null):s:null},set(r,o,s){let i=x(r,o);t.set(i,s);try{localStorage.setItem(ge(r,o),JSON.stringify(s))}catch(u){}},invalidate(r){let o=`${r}:`;for(let s of[...t.keys()])s.startsWith(o)&&t.delete(s);for(let s of P()){let i=s.slice(D.length),u=i.lastIndexOf("_");if(u<0)continue;if(i.slice(0,u)===r)try{localStorage.removeItem(s)}catch(d){}}},clear(){t.clear();for(let r of P())try{localStorage.removeItem(r)}catch(o){}}}}function T(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function O(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let a=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(a)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(a)?"social":"referral"}catch(n){return"direct"}}function U(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function R(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function me(e){let t=L("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function L(e,t){var o,s,i,u,g,d,p;let n=(s=(o=t==null?void 0:t.userAgent)==null?void 0:o.trim())!=null?s:"",a=(u=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?u:"",r=(g=t==null?void 0:t.now)!=null?g:new Date;return{sessionId:e,ephemeral:!1,utmParams:(d=t==null?void 0:t.utmParams)!=null?d:{},deviceClass:n?T(n):"desktop",trafficSource:a?O(a,t==null?void 0:t.appOrigin):"direct",referrerDomain:U(a),timeOfDay:R(r),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?p:"sun"}}async function fe(e,t,n){let a={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(a.Origin=n.origin);let r=L(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:a,body:JSON.stringify(r)})}catch(i){}let o=await Promise.allSettled(e.map(async({id:i,variantIds:u})=>{let g=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:a,body:JSON.stringify({sessionId:t,componentId:i,variantIds:u})});if(!g.ok)return null;let d=await g.json();return{id:i,variantId:d.variantId}})),s={};for(let i of o)i.status==="fulfilled"&&i.value&&(s[i.value.id]=i.value.variantId);return s}function pe(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}function ye(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var $={track:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],userEdges:[],capturedAt:0}),destroy:()=>{}};function Se(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,a]of t)n.startsWith("utm_")&&(e[n]=a);return e}catch(e){return{}}}function he(e){return e.replace(/\/events\/?$/,"")}function Te(e){var y,A,S,E;if(typeof window=="undefined"||e.consent===!1)return $;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),$;if(!e.ingestUrl)return console.warn("[sentient] init() called without ingestUrl. SDK disabled."),$;let t=Date.now(),n=F(),a=B(),r=G({ingestUrl:e.ingestUrl,apiKey:e.apiKey}),o=he(e.ingestUrl),s={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i=T((y=navigator.userAgent)!=null?y:""),u=typeof window!="undefined"?window.location.origin:void 0,g=O((A=document.referrer)!=null?A:"",u),d=(S=e.sessionSegment)!=null?S:`${i}:${g}`;if(e.initialAssignments)for(let[l,f]of Object.entries(e.initialAssignments))a.set(l,d,{variantId:f,assignedAt:Date.now(),segment:d,confidence:1});let p=Promise.resolve(),v=n.getSessionId();if(v){let l=U((E=document.referrer)!=null?E:""),f={sessionId:v,deviceClass:i,trafficSource:g,referrerDomain:l,utmParams:Se(),timeOfDay:R(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:n.isEphemeral()};try{p=fetch(`${o}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(f),headers:s}).then(()=>{}).catch(()=>{})}catch(h){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:r});let w={track(l){let f=n.getSessionId();if(!f)return;let h=Q(N({},l),{id:ye(),sessionId:f,timestamp:Date.now(),timeInSession:Date.now()-t});r.push(h),e.debug&&console.log("[sentient] track",h)},getAssignment(l,f){return a.get(l,f)},async assign(l,f){let h=n.getSessionId();if(!h)return null;let _=a.get(l,d);if(_)return{variantId:_.variantId,assignmentTtlMs:0};await p;try{let I=await fetch(`${o}/assign`,{method:"POST",body:JSON.stringify({sessionId:h,componentId:l,variantIds:f}),headers:s});if(!I.ok)return null;let c=await I.json();return a.set(l,d,{variantId:c.variantId,assignedAt:Date.now(),segment:d,confidence:1}),c}catch(I){return null}},getGraph(){return{pageNodes:[],userEdges:[],capturedAt:0}},destroy(){r.destroy(),n.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let l=window;l.__sentient&&(l.__sentient.client=w)}return w}export{N as a,Q as b,T as c,O as d,U as e,R as f,me as g,fe as h,pe as i,Te as j};