@sentientui/core 0.8.1 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +26 -4
- package/dist/chunk-6PD6FNO7.mjs +1 -0
- package/dist/chunk-CFXMEZCZ.mjs +1 -0
- package/dist/index-graph.d.cts +1 -1
- package/dist/index-graph.d.ts +1 -1
- package/dist/index-graph.js +1 -1
- package/dist/index-graph.mjs +1 -1
- package/dist/index-server.d.cts +2 -2
- package/dist/index-server.d.ts +2 -2
- package/dist/index-server.js +1 -1
- package/dist/index-server.mjs +1 -1
- package/dist/index.d.cts +41 -3
- package/dist/index.d.ts +41 -3
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/dist/session-meta-D5IgJuRW.d.cts +53 -0
- package/dist/session-meta-D5IgJuRW.d.ts +53 -0
- package/package.json +1 -1
- package/dist/chunk-NXCIN4O2.mjs +0 -1
- package/dist/chunk-QCYVBCUV.mjs +0 -1
- package/dist/session-meta-DCN-QCHQ.d.cts +0 -34
- package/dist/session-meta-DCN-QCHQ.d.ts +0 -34
package/README.md
CHANGED
|
@@ -25,7 +25,11 @@ const result = await client.assign('hero_headline', ['control', 'variant_b']);
|
|
|
25
25
|
console.log(result?.variantId); // e.g. 'variant_b'
|
|
26
26
|
console.log(result?.content); // managed text content if the variant is WYSIWYG-managed
|
|
27
27
|
|
|
28
|
-
//
|
|
28
|
+
// Credit the variant served for a component when the visitor converts
|
|
29
|
+
// (feeds the per-variant CVR funnel — no variantId plumbing needed)
|
|
30
|
+
client.componentGoal('hero_headline', 'trial_started');
|
|
31
|
+
|
|
32
|
+
// Or record a session-level funnel goal not tied to any component
|
|
29
33
|
client.goal('trial_started', { plan: 'pro' });
|
|
30
34
|
```
|
|
31
35
|
|
|
@@ -65,11 +69,24 @@ Queues an event for batched ingest. Events flush every 5 s and on `visibilitycha
|
|
|
65
69
|
|
|
66
70
|
Fires a named goal for the current session. Used for cross-component conversions (e.g. `'trial_started'`, `'purchase_completed'`) where you cannot scope the reward to a single `<Adaptive>`.
|
|
67
71
|
|
|
68
|
-
> **Two reward paths:** `client.goal()` sends a named reward event that the bandit attributes to whatever variant was active at goal time. When using `@sentientui/react`, the `<Adaptive>` component's `onConvert` prop (or the `goal` prop on `<AdaptiveText>`) is the preferred path for rewards scoped to a single component — it ties the reward directly to the assignment without needing the component ID. Use `client.goal()` for funnel steps that span multiple components or occur after navigation.
|
|
69
|
-
|
|
70
72
|
- `weight` (0–1, default `1.0`) — partial reward value. Use values < 1 for funnel steps that precede the final conversion. The bandit learns from each step immediately.
|
|
71
73
|
- `stepIndex` (default `0`) — position in the funnel for analytics grouping.
|
|
72
74
|
|
|
75
|
+
> **Which goal method?** `goal()` is **session-level** — it POSTs to `/v1/goals` with no component/variant, so it appears in funnel charts but **not** the per-variant CVR breakdown. For variant experiments, prefer **`componentGoal()`** (below) or the declarative `<Adaptive goal={…}>` prop, both of which attribute the conversion to the served variant.
|
|
76
|
+
|
|
77
|
+
### `client.componentGoal(componentId, goalType, opts?)`
|
|
78
|
+
|
|
79
|
+
Records a conversion **attributed to the variant currently served** for `componentId`, so it feeds the per-variant CVR funnel. Resolves the served variant from the local assignment cache — you don't pass `variantId` or `projectId`. Emits a `goal_achieved` event (the same signal `<Adaptive goal>` fires automatically).
|
|
80
|
+
|
|
81
|
+
```ts
|
|
82
|
+
client.componentGoal('hero_headline', 'hero_contact', {
|
|
83
|
+
reward: 1, // 0–1, default 1
|
|
84
|
+
metadata: { method: 'whatsapp' } // merged into the event payload
|
|
85
|
+
});
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
No-ops (with a `debug` warning) if the component has not been assigned yet — render its `<Adaptive>` / call `assign()` first. Prefer this over a hand-rolled `client.track({ eventType: 'goal_achieved', … })`, which requires you to thread the `variantId` through yourself. In React, use the [`useAdaptiveGoal`](../react/README.md#useadaptivegoalcomponentid) hook.
|
|
89
|
+
|
|
73
90
|
### `client.identify(userId)`
|
|
74
91
|
|
|
75
92
|
Attaches a stable user ID to the session. Portraits and cluster assignment carry forward across future sessions for the same `userId`.
|
|
@@ -103,7 +120,7 @@ const initialAssignments = await preloadAssignments(
|
|
|
103
120
|
],
|
|
104
121
|
sessionId,
|
|
105
122
|
{
|
|
106
|
-
apiKey: process.env.
|
|
123
|
+
apiKey: process.env.NEXT_PUBLIC_SENTIENT_API_KEY!,
|
|
107
124
|
baseUrl: 'https://api.sentient-ui.com/v1',
|
|
108
125
|
origin: process.env.APP_ORIGIN, // must be in the project's allowed origins
|
|
109
126
|
userAgent, // from request headers, aligns segment with the client
|
|
@@ -126,6 +143,11 @@ import('@sentientui/core/graph');
|
|
|
126
143
|
|
|
127
144
|
The lean bundle stays under 8 KB gzip; graph adds roughly another 8 KB.
|
|
128
145
|
|
|
146
|
+
> **Using `@sentientui/react`?** Don't import this entry yourself — pass the
|
|
147
|
+
> `enableGraph` prop to `AdaptiveProvider` / `AdaptiveRoot` instead. The provider
|
|
148
|
+
> wires the graph-capable `init()` into its single client for you; calling `init`
|
|
149
|
+
> from this entry alongside the provider would create a second client.
|
|
150
|
+
|
|
129
151
|
## Local overrides (development)
|
|
130
152
|
|
|
131
153
|
```
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{a as D,b as K,d as W,f as B,g as Q,h as F,i as j}from"./chunk-CFXMEZCZ.mjs";var ie="_snt_uid";var A="_snt_uid";function oe(){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 ae(e,t,a){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${a}; SameSite=strict; path=/`}catch(c){}}function ce(e){try{return localStorage.getItem(e)}catch(t){return null}}function le(e,t){try{return localStorage.setItem(e,t),!0}catch(a){return!1}}function de(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function ue(e,t){try{return sessionStorage.setItem(e,t),!0}catch(a){return!1}}function ge(e){try{sessionStorage.removeItem(e)}catch(t){}}function pe(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 me(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var ye={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function Y(e){var p,m,y,S,E,h;if(typeof window=="undefined")return ye;let t=(p=e==null?void 0:e.cookieName)!=null?p:ie,c=((m=e==null?void 0:e.cookieTTLDays)!=null?m:365)*24*60*60,o=(h=(E=(S=(y=re(t))!=null?y:ce(A))!=null?S:de(A))!=null?E:e==null?void 0:e.ssrSessionId)!=null?h:oe();ae(t,o,c);let i=le(A,o),r=pe(t),n=i?!1:ue(A,o),s=!i&&!r&&!n;return{getSessionId:()=>o,isEphemeral:()=>s,destroy:()=>{o=null,me(t),fe(A),ge(A)}}}var he={push:()=>{},flush:()=>{},destroy:()=>{}};function Se(e,t){try{let a=localStorage.getItem(t);if(!a)return[];let c=JSON.parse(a);return Array.isArray(c)?(localStorage.removeItem(t),c.slice(-e)):[]}catch(a){return[]}}function z(e,t,a){try{let o=[...(()=>{try{let i=localStorage.getItem(a);if(!i)return[];let r=JSON.parse(i);return Array.isArray(r)?r:[]}catch(i){return[]}})(),...e].slice(-t);localStorage.setItem(a,JSON.stringify(o))}catch(c){}}function q(e){var f,_,I;if(typeof window=="undefined")return he;let t=(f=e.flushIntervalMs)!=null?f:5e3,a=(_=e.maxBatchSize)!=null?_:20,c=(I=e.maxRetrySize)!=null?I:100,o=e.ingestUrl,i=e.apiKey,r=`_snt_retry_${i.slice(0,12)}`,n=[],s=new Set,p=[],m=l=>{for(let g of l)y.delete(g),!s.has(g)&&(s.add(g),p.push(g));for(;p.length>500;){let g=p.shift();g&&s.delete(g)}},y=new Set,S=l=>{s.has(l.id)||y.has(l.id)||(y.add(l.id),n.push(l))},E=Se(c,r);for(let l of E)S(l);let h=0,k=0,N=l=>{if(l.length===0)return;let g=JSON.stringify(l),v=l.map(w=>w.id),x;try{x=fetch(o,{method:"POST",keepalive:!0,body:g,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}})}catch(w){z(l,c,r);for(let G of v)y.delete(G);k++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6));return}let T=w=>{if(w.ok||w.status>=400&&w.status<500&&w.status!==429){m(v),k=0,h=0;return}z(l,c,r);for(let G of v)y.delete(G);k++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6))};x instanceof Promise?x.then(T).catch(()=>{z(l,c,r);for(let w of v)y.delete(w);k++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6))}):T(x)},O=typeof TextEncoder!="undefined"?new TextEncoder:null,L=l=>O?O.encode(l).length:l.length,$=l=>{let g=[],v=2;for(let x of l){let T=L(JSON.stringify(x))+1;if(g.length>0&&v+T>57344||g.length>=a)break;g.push(x),v+=T}return g},b=()=>{try{if(Date.now()<h)return;for(;n.length>0;){let l=n.filter(v=>!s.has(v.id));if(n.length=0,l.length===0)break;let g=$(l);if(g.length===0)break;g.length<l.length&&n.push(...l.slice(g.length)),N(g)}}catch(l){}},R=!0,C=null;C=setInterval(()=>{R&&b()},t);let d=()=>{document.visibilityState==="hidden"&&b()},u=()=>{b()};return document.addEventListener("visibilitychange",d),window.addEventListener("beforeunload",u),{push(l){S(l),n.length>=a&&b()},flush:b,destroy(){R=!1,C!==null&&(clearInterval(C),C=null),document.removeEventListener("visibilitychange",d),window.removeEventListener("beforeunload",u),b()}}}var H="_snt_asgn_";function P(e,t){return`${e}:${t}`}function ve(e,t){return`${H}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function X(e){let t=e.slice(H.length),a=t.indexOf(":");if(a<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,a)),segment:decodeURIComponent(t.slice(a+1))}}catch(c){return null}}function J(){try{let e=[];for(let t=0;t<localStorage.length;t++){let a=localStorage.key(t);a!=null&&a.startsWith(H)&&e.push(a)}return e}catch(e){return[]}}function Z(e=18e5){let t=new Map,a=o=>o.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let o of J())try{let i=localStorage.getItem(o);if(!i)continue;let r=JSON.parse(i);if(a(r)){localStorage.removeItem(o);continue}let n=X(o);if(!n)continue;t.set(P(n.componentId,n.segment),r)}catch(i){}})(),{get(o,i){let r=t.get(P(o,i));return r?a(r)?(t.delete(P(o,i)),null):r:null},set(o,i,r){let n=P(o,i);t.set(n,r);try{localStorage.setItem(ve(o,i),JSON.stringify(r))}catch(s){}},invalidate(o){let i=`${o}:`;for(let r of[...t.keys()])r.startsWith(i)&&t.delete(r);for(let r of J()){let n=X(r);if((n==null?void 0:n.componentId)===o)try{localStorage.removeItem(r)}catch(s){}}},clear(){t.clear();for(let o of J())try{localStorage.removeItem(o)}catch(i){}}}}function we(e,t,a){var o;let c=[];{let n=!1,s=[],p=()=>{if(n)return;let m=Date.now();for(s.push(m);s.length>0&&m-s[0]>500;)s.shift();s.length>=3&&(n=!0,e("rage_click"))};t.addEventListener("click",p),c.push(()=>t.removeEventListener("click",p))}{let i=!1,r=n=>{if(i||!(n.target instanceof Node)||!t.contains(n.target)&&t!==n.target)return;i=!0;let s=typeof window!="undefined"?window.getSelection():null,p=s?s.toString().length:0;e("text_copy",{selectionLength:p})};document.addEventListener("copy",r),c.push(()=>document.removeEventListener("copy",r))}{let i=!1,r=!1,n=null,s=()=>{n!==null&&(clearTimeout(n),n=null)},p=()=>{i||!r||(s(),n=setTimeout(()=>{!i&&r&&(i=!0,e("scroll_hesitation"))},3e3))},m=()=>{s(),p()},y=E=>{for(let h of E)r=h.intersectionRatio>.3,r?p():s()};typeof process!="undefined"&&((o=process.env)==null?void 0:o.NODE_ENV)!=="production"&&(window.__lastIOCallback=y);let S=new IntersectionObserver(y,{threshold:[.3]});S.observe(t),window.addEventListener("scroll",m,{passive:!0}),c.push(()=>{S.disconnect(),window.removeEventListener("scroll",m),s()})}{let i=!1,r=a!=null?a:Date.now(),n=()=>{if(i||document.visibilityState!=="hidden")return;let s=Date.now()-r;s<15e3&&(i=!0,e("tab_loss",{timeOnPage:s}))};document.addEventListener("visibilitychange",n),c.push(()=>document.removeEventListener("visibilitychange",n))}return()=>{for(let i of c)i()}}var ee="https://api.sentient-ui.com/v1/events",M=new Map,te=null;function V(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var U={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Ee(){try{let e={},t=new URLSearchParams(window.location.search);for(let[a,c]of t)a.startsWith("utm_")&&(e[a]=c);return e}catch(e){return{}}}function ne(e){return e.replace(/\/events\/?$/,"")}function se(){return[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function Ne(e){if(typeof window=="undefined")return;let t=e!=null?e:te;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let a=M.get(t);if(!a){console.warn("[sentient] grantConsent() called before init()");return}let{config:c,upgrade:o}=a;if(!o||c.respectDoNotTrack!==!1&&se())return;let i=Ie(K(D({},c),{consent:!0}));o(i),M.set(t,{config:K(D({},c),{consent:!0}),upgrade:null})}function xe(e){var r;let t=ne((r=e.ingestUrl)!=null?r:ee),a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(n,s,p){try{let m=new URLSearchParams({componentId:n});for(let E of s!=null?s:[])m.append("variantIds[]",E);let y=await fetch(`${t}/winner?${m.toString()}`,{headers:a});return y.ok?{variantId:(await y.json()).variantId,assignmentTtlMs:0}:s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}catch(m){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},o={track:n=>c.track(n),goal:(n,s,p,m)=>c.goal(n,s,p,m),componentGoal:(n,s,p)=>c.componentGoal(n,s,p),identify:n=>c.identify(n),getAssignment:(n,s)=>c.getAssignment(n,s),assign:(n,s,p,m)=>c.assign(n,s,p,m),fetchWeights:()=>c.fetchWeights(),getGraph:()=>c.getGraph(),destroy:()=>c.destroy()};function i(n){c=n}return{proxy:o,setInner:i}}function Ie(e){var O,L,$,b,R,C;if(typeof window=="undefined")return U;te=e.apiKey;let t=e.respectDoNotTrack!==!1&&se();if(e.consent===!1||t){if(e.preConsentBehavior==="statistical_winner"){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."),U;let{proxy:d,setInner:u}=xe(e);return M.set(e.apiKey,{config:e,upgrade:t?null:u}),d}return M.set(e.apiKey,{config:e,upgrade:null}),U}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."),U;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),U;let a=(O=e.ingestUrl)!=null?O:ee,c=Date.now(),o=Y({ssrSessionId:e.ssrSessionId}),i=Z(),r=q({ingestUrl:a,apiKey:e.apiKey}),n=ne(a),s={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},p=B((L=navigator.userAgent)!=null?L:""),m=typeof window!="undefined"?window.location.origin:void 0,y=Q(($=document.referrer)!=null?$:"",m),S=(b=e.sessionSegment)!=null?b:`${p}:${y}`,E=new Map;if(e.initialAssignments)for(let[d,u]of Object.entries(e.initialAssignments))i.set(d,S,{variantId:u,assignedAt:Date.now(),segment:S,confidence:1});let h=Promise.resolve(),k=o.getSessionId();if(k){let d=F((R=document.referrer)!=null?R:""),u=D(D({sessionId:k,deviceClass:p,trafficSource:y,referrerDomain:d,utmParams:Ee(),timeOfDay:j(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:o.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||W((C=navigator.userAgent)!=null?C:"")},e.userId?{userId:e.userId}:{}),e.country?{country:e.country}:{});try{h=fetch(`${n}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(u),headers:s}).then(f=>{f.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(f){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:r});let N={goal(d,u={},f=1,_=0){let I=o.getSessionId();if(!I)return;let l=V();h.then(()=>{fetch(`${n}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:I,name:d,metadata:u,weight:f,stepIndex:_,goalId:l}),headers:s}).catch(()=>{})})},componentGoal(d,u,f){var g,v;let _=o.getSessionId();if(!_)return;let I=i.get(d,S);if(!I){e.debug&&console.warn(`[sentient] componentGoal("${d}"): no assignment yet \u2014 render its <Adaptive> or call assign() before recording a goal.`);return}let l={id:V(),sessionId:_,projectId:e.apiKey,componentId:d,variantId:I.variantId,eventType:"goal_achieved",goalType:u,payload:D({reward:(g=f==null?void 0:f.reward)!=null?g:1},(v=f==null?void 0:f.metadata)!=null?v:{}),timestamp:Date.now(),timeInSession:Date.now()-c};e.debug&&console.log("[sentient] componentGoal",l),h.then(()=>r.push(l))},identify(d){let u=o.getSessionId();u&&h.then(()=>{fetch(`${n}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:u,userId:d,ephemeral:o.isEphemeral()}),headers:s}).catch(()=>{})})},track(d){let u=o.getSessionId();if(!u)return;let f=K(D({},d),{id:V(),sessionId:u,timestamp:Date.now(),timeInSession:Date.now()-c});e.debug&&console.log("[sentient] track",f),h.then(()=>r.push(f))},getAssignment(d,u){return i.get(d,u)},async assign(d,u,f,_){let I=o.getSessionId();if(!I)return null;let l=i.get(d,S);if(l&&(u!=null&&u.length||l.content!==void 0))return{variantId:l.variantId,assignmentTtlMs:0,content:l.content};let g=E.get(d);if(g)return g;let v=(async()=>{await h;try{let x={sessionId:I,componentId:d,variantIds:u};_!==void 0?x.agentDataByVariant=_:f!==void 0&&(x.agentData=f);let T=await fetch(`${n}/assign`,{method:"POST",body:JSON.stringify(x),headers:s});if(!T.ok)return null;let w=await T.json();return i.set(d,S,{variantId:w.variantId,assignedAt:Date.now(),segment:S,confidence:1,content:w.content}),w}catch(x){return null}finally{E.delete(d)}})();return E.set(d,v),v},async fetchWeights(){var d;try{let u=await fetch(`${n}/weights`,{headers:s});return u.ok?(d=(await u.json()).components)!=null?d:[]:[]}catch(u){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){r.destroy(),o.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(M.set(e.apiKey,{config:e,upgrade:null}),e.debug){let d=window;d.__sentient&&(d.__sentient.client=N)}return N}export{we as a,se as b,Ne as c,Ie as d};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var m=Object.defineProperty,h=Object.defineProperties;var y=Object.getOwnPropertyDescriptors;var d=Object.getOwnPropertySymbols;var b=Object.prototype.hasOwnProperty,x=Object.prototype.propertyIsEnumerable;var f=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,L=(r,e)=>{for(var t in e||(e={}))b.call(e,t)&&f(r,t,e[t]);if(d)for(var t of d(e))x.call(e,t)&&f(r,t,e[t]);return r},O=(r,e)=>h(r,y(e));var w=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function C(r){return k(r)!==null}function k(r){var t;if(!r)return null;let e=r.toLowerCase();return(t=w.find(n=>e.includes(n.toLowerCase())))!=null?t:null}function D(r){let e=r.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(e)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(e)?"mobile":"desktop"}function P(r,e){if(!r)return"direct";try{let t=new URL(r);if(e)try{if(new URL(e).host===t.host)return"direct"}catch(i){}let n=t.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(n)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(n)?"social":"referral"}catch(t){return"direct"}}function S(r){if(!r)return null;try{return new URL(r).hostname}catch(e){return null}}function U(r){let e=r.getHours();return e<6?"night":e<12?"morning":e<18?"afternoon":"evening"}function B(r){let e=v("__segment__",r);return`${e.deviceClass}:${e.trafficSource}`}function v(r,e){var o,a,s,u,c,l,g;let t=(a=(o=e==null?void 0:e.userAgent)==null?void 0:o.trim())!=null?a:"",n=(u=(s=e==null?void 0:e.referer)==null?void 0:s.trim())!=null?u:"",i=(c=e==null?void 0:e.now)!=null?c:new Date;return{sessionId:r,ephemeral:!1,utmParams:(l=e==null?void 0:e.utmParams)!=null?l:{},deviceClass:t?D(t):"desktop",trafficSource:n?P(n,e==null?void 0:e.appOrigin):"direct",referrerDomain:S(n),timeOfDay:U(i),dayOfWeek:(g=["sun","mon","tue","wed","thu","fri","sat"][i.getDay()])!=null?g:"sun",automation:(e==null?void 0:e.webdriver)===!0||C(t)}}export{L as a,O as b,w as c,C as d,k as e,D as f,P as g,S as h,U as i,B as j,v as k};
|
package/dist/index-graph.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SentientConfig, SentientClient } from './index.cjs';
|
|
2
2
|
export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, SessionConfig, SessionManager } from './index.cjs';
|
|
3
|
-
export { d as deriveSessionSegment,
|
|
3
|
+
export { d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-D5IgJuRW.cjs';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Graph-capable entry point for @sentientui/core.
|
package/dist/index-graph.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { SentientConfig, SentientClient } from './index.js';
|
|
2
2
|
export { AssignResult, Assignment, AssignmentCache, ContentAddedEvent, DOMScanner, EventQueue, EventType, GraphClient, GraphConfig, GraphSnapshot, PageNode, QueueConfig, ScanResult, ScannedNode, SentientEvent, SessionConfig, SessionManager } from './index.js';
|
|
3
|
-
export { d as deriveSessionSegment,
|
|
3
|
+
export { d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-D5IgJuRW.js';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* Graph-capable entry point for @sentientui/core.
|
package/dist/index-graph.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var W=Object.defineProperty,fe=Object.defineProperties,me=Object.getOwnPropertyDescriptor,he=Object.getOwnPropertyDescriptors,ye=Object.getOwnPropertyNames,Z=Object.getOwnPropertySymbols;var te=Object.prototype.hasOwnProperty,Se=Object.prototype.propertyIsEnumerable;var ee=(e,t,n)=>t in e?W(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,D=(e,t)=>{for(var n in t||(t={}))te.call(t,n)&&ee(e,n,t[n]);if(Z)for(var n of Z(t))Se.call(t,n)&&ee(e,n,t[n]);return e},B=(e,t)=>fe(e,he(t));var ve=(e,t)=>{for(var n in t)W(e,n,{get:t[n],enumerable:!0})},we=(e,t,n,c)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of ye(t))!te.call(e,s)&&s!==n&&W(e,s,{get:()=>t[s],enumerable:!(c=me(t,s))||c.enumerable});return e};var Ee=e=>we(W({},"__esModule",{value:!0}),e);var at={};ve(at,{deriveSessionSegment:()=>H,detectDeviceClass:()=>O,detectTimeOfDay:()=>U,detectTrafficSource:()=>R,init:()=>it,referrerDomainFromReferer:()=>M});module.exports=Ee(at);var Ie="_snt_uid";var N="_snt_uid";function be(){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 Ce(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function xe(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(c){}}function _e(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 Ae(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function ke(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function De(e){try{sessionStorage.removeItem(e)}catch(t){}}function Ne(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 Re(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Me={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function ne(e){var d,l,g,h,u,y;if(typeof window=="undefined")return Me;let t=(d=e==null?void 0:e.cookieName)!=null?d:Ie,c=((l=e==null?void 0:e.cookieTTLDays)!=null?l:365)*24*60*60,s=(y=(u=(h=(g=Ce(t))!=null?g:_e(N))!=null?h:Ae(N))!=null?u:e==null?void 0:e.ssrSessionId)!=null?y:be();xe(t,s,c);let a=Te(N,s),r=Ne(t),i=a?!1:ke(N,s),o=!a&&!r&&!i;return{getSessionId:()=>s,isEphemeral:()=>o,destroy:()=>{s=null,Re(t),Oe(N),De(N)}}}var Ue={push:()=>{},flush:()=>{},destroy:()=>{}};function Pe(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let c=JSON.parse(n);return Array.isArray(c)?(localStorage.removeItem(t),c.slice(-e)):[]}catch(n){return[]}}function z(e,t,n){try{let s=[...(()=>{try{let a=localStorage.getItem(n);if(!a)return[];let r=JSON.parse(a);return Array.isArray(r)?r:[]}catch(a){return[]}})(),...e].slice(-t);localStorage.setItem(n,JSON.stringify(s))}catch(c){}}function re(e){var A,C,P;if(typeof window=="undefined")return Ue;let t=(A=e.flushIntervalMs)!=null?A:5e3,n=(C=e.maxBatchSize)!=null?C:20,c=(P=e.maxRetrySize)!=null?P:100,s=e.ingestUrl,a=e.apiKey,r=`_snt_retry_${a.slice(0,12)}`,i=[],o=new Set,d=[],l=p=>{for(let S of p)g.delete(S),!o.has(S)&&(o.add(S),d.push(S));for(;d.length>500;){let S=d.shift();S&&o.delete(S)}},g=new Set,h=p=>{o.has(p.id)||g.has(p.id)||(g.add(p.id),i.push(p))},u=Pe(c,r);for(let p of u)h(p);let y=0,v=0,_=p=>{if(p.length===0)return;let S=JSON.stringify(p),E=p.map(x=>x.id),I;try{I=fetch(s,{method:"POST",keepalive:!0,body:S,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(x){z(p,c,r);for(let j of E)g.delete(j);v++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6));return}let L=x=>{if(x.ok||x.status>=400&&x.status<500&&x.status!==429){l(E),v=0,y=0;return}z(p,c,r);for(let j of E)g.delete(j);v++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))};I instanceof Promise?I.then(L).catch(()=>{z(p,c,r);for(let x of E)g.delete(x);v++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))}):L(I)},T=typeof TextEncoder!="undefined"?new TextEncoder:null,K=p=>T?T.encode(p).length:p.length,G=p=>{let S=[],E=2;for(let I of p){let L=K(JSON.stringify(I))+1;if(S.length>0&&E+L>57344||S.length>=n)break;S.push(I),E+=L}return S},b=()=>{try{if(Date.now()<y)return;for(;i.length>0;){let p=i.filter(E=>!o.has(E.id));if(i.length=0,p.length===0)break;let S=G(p);if(S.length===0)break;S.length<p.length&&i.push(...p.slice(S.length)),_(S)}}catch(p){}},f=!0,m=null;m=setInterval(()=>{f&&b()},t);let w=()=>{document.visibilityState==="hidden"&&b()},k=()=>{b()};return document.addEventListener("visibilitychange",w),window.addEventListener("beforeunload",k),{push(p){h(p),i.length>=n&&b()},flush:b,destroy(){f=!1,m!==null&&(clearInterval(m),m=null),document.removeEventListener("visibilitychange",w),window.removeEventListener("beforeunload",k),b()}}}var Q="_snt_asgn_";function F(e,t){return`${e}:${t}`}function Le(e,t){return`${Q}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function oe(e){let t=e.slice(Q.length),n=t.indexOf(":");if(n<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,n)),segment:decodeURIComponent(t.slice(n+1))}}catch(c){return null}}function J(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(Q)&&e.push(n)}return e}catch(e){return[]}}function se(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of J())try{let a=localStorage.getItem(s);if(!a)continue;let r=JSON.parse(a);if(n(r)){localStorage.removeItem(s);continue}let i=oe(s);if(!i)continue;t.set(F(i.componentId,i.segment),r)}catch(a){}})(),{get(s,a){let r=t.get(F(s,a));return r?n(r)?(t.delete(F(s,a)),null):r:null},set(s,a,r){let i=F(s,a);t.set(i,r);try{localStorage.setItem(Le(s,a),JSON.stringify(r))}catch(o){}},invalidate(s){let a=`${s}:`;for(let r of[...t.keys()])r.startsWith(a)&&t.delete(r);for(let r of J()){let i=oe(r);if((i==null?void 0:i.componentId)===s)try{localStorage.removeItem(r)}catch(o){}}},clear(){t.clear();for(let s of J())try{localStorage.removeItem(s)}catch(a){}}}}function O(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 R(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 M(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function U(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function H(e){let t=$e("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function $e(e,t){var a,r,i,o,d,l,g;let n=(r=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?r:"",c=(o=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?o:"",s=(d=t==null?void 0:t.now)!=null?d:new Date;return{sessionId:e,ephemeral:!1,utmParams:(l=t==null?void 0:t.utmParams)!=null?l:{},deviceClass:n?O(n):"desktop",trafficSource:c?R(c,t==null?void 0:t.appOrigin):"direct",referrerDomain:M(c),timeOfDay:U(s),dayOfWeek:(g=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?g:"sun"}}var ae="https://api.sentient-ui.com/v1/events",q=new Map,Ke=null;function ie(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var $={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Ge(){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 ce(e){return e.replace(/\/events\/?$/,"")}function We(e){var r;let t=ce((r=e.ingestUrl)!=null?r:ae),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(i,o,d){try{let l=new URLSearchParams({componentId:i});for(let u of o!=null?o:[])l.append("variantIds[]",u);let g=await fetch(`${t}/winner?${l.toString()}`,{headers:n});return g.ok?{variantId:(await g.json()).variantId,assignmentTtlMs:0}:o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}catch(l){return o!=null&&o[0]?{variantId:o[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},s={track:i=>c.track(i),goal:(i,o,d,l)=>c.goal(i,o,d,l),identify:i=>c.identify(i),getAssignment:(i,o)=>c.getAssignment(i,o),assign:(i,o,d,l)=>c.assign(i,o,d,l),fetchWeights:()=>c.fetchWeights(),getGraph:()=>c.getGraph(),destroy:()=>c.destroy()};function a(i){c=i}return{proxy:s,setInner:a}}function de(e){var _,T,K,G,b;if(typeof window=="undefined")return $;if(Ke=e.apiKey,e.consent===!1){if(e.preConsentBehavior==="statistical_winner"){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."),$;let{proxy:f,setInner:m}=We(e);return q.set(e.apiKey,{config:e,upgrade:m}),f}return q.set(e.apiKey,{config:e,upgrade:null}),$}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 with an empty ingestUrl. SDK disabled."),$;let t=(_=e.ingestUrl)!=null?_:ae,n=Date.now(),c=ne({ssrSessionId:e.ssrSessionId}),s=se(),a=re({ingestUrl:t,apiKey:e.apiKey}),r=ce(t),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},o=O((T=navigator.userAgent)!=null?T:""),d=typeof window!="undefined"?window.location.origin:void 0,l=R((K=document.referrer)!=null?K:"",d),g=(G=e.sessionSegment)!=null?G:`${o}:${l}`,h=new Map;if(e.initialAssignments)for(let[f,m]of Object.entries(e.initialAssignments))s.set(f,g,{variantId:m,assignedAt:Date.now(),segment:g,confidence:1});let u=Promise.resolve(),y=c.getSessionId();if(y){let f=M((b=document.referrer)!=null?b:""),m=D({sessionId:y,deviceClass:o,trafficSource:l,referrerDomain:f,utmParams:Ge(),timeOfDay:U(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:c.isEphemeral()},e.userId?{userId:e.userId}:{});try{u=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(m),headers:i}).then(w=>{w.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(w){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:a});let v={goal(f,m={},w=1,k=0){let A=c.getSessionId();if(!A)return;let C=ie();u.then(()=>{fetch(`${r}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:A,name:f,metadata:m,weight:w,stepIndex:k,goalId:C}),headers:i}).catch(()=>{})})},identify(f){let m=c.getSessionId();m&&u.then(()=>{fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:m,userId:f,ephemeral:c.isEphemeral()}),headers:i}).catch(()=>{})})},track(f){let m=c.getSessionId();if(!m)return;let w=B(D({},f),{id:ie(),sessionId:m,timestamp:Date.now(),timeInSession:Date.now()-n});a.push(w),e.debug&&console.log("[sentient] track",w)},getAssignment(f,m){return s.get(f,m)},async assign(f,m,w,k){let A=c.getSessionId();if(!A)return null;let C=s.get(f,g);if(C&&(m!=null&&m.length||C.content!==void 0))return{variantId:C.variantId,assignmentTtlMs:0,content:C.content};let P=h.get(f);if(P)return P;let p=(async()=>{await u;try{let S={sessionId:A,componentId:f,variantIds:m};k!==void 0?S.agentDataByVariant=k:w!==void 0&&(S.agentData=w);let E=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify(S),headers:i});if(!E.ok)return null;let I=await E.json();return s.set(f,g,{variantId:I.variantId,assignedAt:Date.now(),segment:g,confidence:1,content:I.content}),I}catch(S){return null}finally{h.delete(f)}})();return h.set(f,p),p},async fetchWeights(){var f;try{let m=await fetch(`${r}/weights`,{headers:i});return m.ok?(f=(await m.json()).components)!=null?f:[]:[]}catch(m){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){a.destroy(),c.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(q.set(e.apiKey,{config:e,upgrade:null}),e.debug){let f=window;f.__sentient&&(f.__sentient.client=v)}return v}var Be=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Fe="h1, h2, h3",je={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function V(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function ze(e){var t,n,c;try{let s=e;for(let a of Object.keys(s)){if(!a.startsWith("__reactFiber")&&!a.startsWith("__reactInternalInstance"))continue;let r=s[a],i=(c=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?c:(n=r==null?void 0:r.type)==null?void 0:n.name;if(i&&i.length>1)return i}}catch(s){}}function Je(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function Qe(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function He(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function qe(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function Y(e,t){var c,s,a;let n=e.querySelector(Fe);return{componentId:He(e),semanticType:Qe(e),ariaLabel:(c=e.getAttribute("aria-label"))!=null?c:void 0,headingText:(a=(s=n==null?void 0:n.textContent)==null?void 0:s.trim())!=null?a:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:qe(e),reactComponentName:ze(e),dataAttributes:Je(e)}}function ue(e){var a;let t=[],n=new Set,c="__root__",s=new Map;for(let[r,i]of e){let o=r.parentElement,d=c;for(;o;){if(e.has(o)){d=e.get(o);let g=e.get(r),h=`${d}->${g}`;!n.has(h)&&d!==g&&(n.add(h),t.push({fromComponentId:d,toComponentId:g,weight:.6}));break}o=o.parentElement}let l=(a=s.get(d))!=null?a:[];l.push(r),s.set(d,l)}for(let r of s.values())if(!(r.length<2))for(let i=0;i<r.length;i++)for(let o=i+1;o<r.length;o++){let d=e.get(r[i]),l=e.get(r[o]);if(d===l)continue;let g=`${d}->${l}::sib`,h=`${l}->${d}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:d,toComponentId:l,weight:.3})),n.has(h)||(n.add(h),t.push({fromComponentId:l,toComponentId:d,weight:.3}))}return t}function Ve(e){let t=[],n=new Set,c=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let i=Y(r,e);t.push(i),c.set(r,i.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let i=r.hasAttribute("aria-label"),o=r.hasAttribute("data-sentient-id");if(!i&&!o)return;n.add(r);let d=Y(r,e);t.push(d),c.set(r,d.componentId)}),{nodes:t,edges:ue(c)}}function le(){if(typeof window=="undefined")return je;let e=null,t=0,n=null,c=i=>{try{let o=window.getComputedStyle(i),d=parseFloat(o.fontSize)||12,l=parseFloat(o.zIndex)||0,g=i.getBoundingClientRect(),h=Math.max(g.top,0),u=window.innerHeight||1,y=1/(h/u+1),v=V(d,12,48)*.4+V(y,0,1)*.4+V(l,0,100)*.2;return Math.max(0,Math.min(1,v))}catch(o){return .5}};return{scan:()=>new Promise(i=>{let o=()=>{let{nodes:d,edges:l}=Ve(c);i({nodes:d,edges:l,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(o,{timeout:100}):o()}catch(d){o()}}),observe:i=>{n=i;try{e=new MutationObserver(o=>{let d=[],l=new Map;for(let g of o)g.type==="childList"&&g.addedNodes.forEach(h=>{if(!(h instanceof Element)||!Be.has(h.tagName))return;let u=h.hasAttribute("data-sentient-id"),y=h.hasAttribute("aria-label");if(!u&&!y)return;let v=Y(h,c);d.push(v),l.set(h,v.componentId)});d.length>0&&n&&n({nodes:d,edges:ue(l),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(o){}},getProminenceScore:c,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null}}}var X="_snt_graph_nodes",ge="_snt_graph_edges",Ye={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function Xe(e){var t;return(t=Ye[e])!=null?t:[]}function Ze(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function et(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var tt=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function nt(e){return tt.has(e)?e:"generic"}function rt(e,t,n){let c=`${e}:${t}:${n.join(",")}`,s=5381;for(let a=0;a<c.length;a++)s=(s<<5)+s+c.charCodeAt(a)&4294967295;return(s>>>0).toString(16).padStart(8,"0")}function pe(e){let t=new Map,n=new Map,c=()=>{typeof window!="undefined"&&et(X,[...t.values()])},s=a=>{var r;try{let i=JSON.parse(a);t.clear();for(let o of(r=i.pageNodes)!=null?r:[])t.set(o.componentId,o)}catch(i){}};if(typeof window!="undefined"){let a=Ze(X,[]);for(let r of a)t.set(r.componentId,r);try{localStorage.removeItem(ge)}catch(r){}}return{addPageNode(a){t.set(a.componentId,a),c()},addStructuralEdge(a){let r=`${a.fromComponentId}->${a.toComponentId}`;n.set(r,a)},syncOnce(){var r,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let a=[...t.values()];if(a.length!==0)try{let o=new Map;for(let u of a){let y=(r=o.get(u.semanticType))!=null?r:[];y.push(u),o.set(u.semanticType,y)}let d=[],l=new Set;for(let u of a)for(let y of Xe(u.semanticType)){let v=(i=o.get(y))!=null?i:[];for(let _ of v){if(_.componentId===u.componentId)continue;let T=`semantic:${u.componentId}->${_.componentId}`;l.has(T)||(l.add(T),d.push({fromComponentId:u.componentId,toComponentId:_.componentId,type:"semantic",weight:.4,confidence:.9}))}}let g=new Set(a.map(u=>u.componentId));for(let u of n.values()){if(!g.has(u.fromComponentId)||!g.has(u.toComponentId))continue;let y=`structural:${u.fromComponentId}->${u.toComponentId}`;l.has(y)||(l.add(y),d.push({fromComponentId:u.fromComponentId,toComponentId:u.toComponentId,type:"structural",weight:u.weight,confidence:1}))}let h={pageUrl:window.location.href,nodes:a.map(u=>{let y=nt(u.semanticType);return{componentId:u.componentId,semanticType:y,answers:u.answers,contentHash:rt(u.componentId,y,u.answers),prominenceScore:u.prominenceScore,depthInPage:u.depth}}),edges:d};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:D({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(h)}).catch(()=>{})}catch(o){}},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(X),localStorage.removeItem(ge)}catch(a){}}}}var ot="https://api.sentient-ui.com/v1/events";function st(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function it(e){var i;let t=de(e);if(!e.graph||typeof window=="undefined")return t;let n=le(),c=(i=e.ingestUrl)!=null?i:ot,s=pe({syncUrl:c.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:st()});try{let o=localStorage.getItem("_snt_graph_nodes");o&&s.restore(JSON.stringify({pageNodes:JSON.parse(o)}))}catch(o){}n.scan().then(o=>{for(let d of o.nodes)s.addPageNode({id:d.componentId,componentId:d.componentId,semanticType:d.semanticType,answers:d.headingText?[d.headingText]:[],prominenceScore:d.prominenceScore,depth:d.depth});for(let d of o.edges)s.addStructuralEdge(d);s.syncOnce()});let a=null,r=()=>{a!==null&&clearTimeout(a),a=setTimeout(()=>{a=null,s.syncOnce()},500)};return n.observe(o=>{for(let d of o.nodes)s.addPageNode({id:d.componentId,componentId:d.componentId,semanticType:d.semanticType,answers:d.headingText?[d.headingText]:[],prominenceScore:d.prominenceScore,depth:d.depth});for(let d of o.edges)s.addStructuralEdge(d);r()}),B(D({},t),{getGraph:()=>s.snapshot(),destroy:()=>{a!==null&&clearTimeout(a),n.destroy(),s.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,referrerDomainFromReferer});
|
|
1
|
+
"use strict";var B=Object.defineProperty,ye=Object.defineProperties,Se=Object.getOwnPropertyDescriptor,ve=Object.getOwnPropertyDescriptors,we=Object.getOwnPropertyNames,te=Object.getOwnPropertySymbols;var oe=Object.prototype.hasOwnProperty,Ee=Object.prototype.propertyIsEnumerable;var ne=(e,t,n)=>t in e?B(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))oe.call(t,n)&&ne(e,n,t[n]);if(te)for(var n of te(t))Ee.call(t,n)&&ne(e,n,t[n]);return e},W=(e,t)=>ye(e,ve(t));var Ie=(e,t)=>{for(var n in t)B(e,n,{get:t[n],enumerable:!0})},be=(e,t,n,d)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of we(t))!oe.call(e,s)&&s!==n&&B(e,s,{get:()=>t[s],enumerable:!(d=Se(t,s))||d.enumerable});return e};var Ce=e=>be(B({},"__esModule",{value:!0}),e);var lt={};Ie(lt,{deriveSessionSegment:()=>q,detectDeviceClass:()=>R,detectTimeOfDay:()=>P,detectTrafficSource:()=>M,init:()=>ut,referrerDomainFromReferer:()=>U});module.exports=Ce(lt);var xe="_snt_uid";var O="_snt_uid";function Te(){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 _e(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ke(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(d){}}function Ae(e){try{return localStorage.getItem(e)}catch(t){return null}}function De(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 Oe(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Re(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 Ue(e){try{localStorage.removeItem(e)}catch(t){}}function Pe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Le={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function re(e){var c,l,p,m,u,h;if(typeof window=="undefined")return Le;let t=(c=e==null?void 0:e.cookieName)!=null?c:xe,d=((l=e==null?void 0:e.cookieTTLDays)!=null?l:365)*24*60*60,s=(h=(u=(m=(p=_e(t))!=null?p:Ae(O))!=null?m:Ne(O))!=null?u:e==null?void 0:e.ssrSessionId)!=null?h:Te();ke(t,s,d);let a=De(O,s),o=Me(t),i=a?!1:Oe(O,s),r=!a&&!o&&!i;return{getSessionId:()=>s,isEphemeral:()=>r,destroy:()=>{s=null,Pe(t),Ue(O),Re(O)}}}var Ge={push:()=>{},flush:()=>{},destroy:()=>{}};function $e(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let d=JSON.parse(n);return Array.isArray(d)?(localStorage.removeItem(t),d.slice(-e)):[]}catch(n){return[]}}function J(e,t,n){try{let s=[...(()=>{try{let a=localStorage.getItem(n);if(!a)return[];let o=JSON.parse(a);return Array.isArray(o)?o:[]}catch(a){return[]}})(),...e].slice(-t);localStorage.setItem(n,JSON.stringify(s))}catch(d){}}function se(e){var v,x,C;if(typeof window=="undefined")return Ge;let t=(v=e.flushIntervalMs)!=null?v:5e3,n=(x=e.maxBatchSize)!=null?x:20,d=(C=e.maxRetrySize)!=null?C:100,s=e.ingestUrl,a=e.apiKey,o=`_snt_retry_${a.slice(0,12)}`,i=[],r=new Set,c=[],l=g=>{for(let S of g)p.delete(S),!r.has(S)&&(r.add(S),c.push(S));for(;c.length>500;){let S=c.shift();S&&r.delete(S)}},p=new Set,m=g=>{r.has(g.id)||p.has(g.id)||(p.add(g.id),i.push(g))},u=$e(d,o);for(let g of u)m(g);let h=0,w=0,k=g=>{if(g.length===0)return;let S=JSON.stringify(g),E=g.map(I=>I.id),b;try{b=fetch(s,{method:"POST",keepalive:!0,body:S,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(I){J(g,d,o);for(let z of E)p.delete(z);w++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(w,6));return}let D=I=>{if(I.ok||I.status>=400&&I.status<500&&I.status!==429){l(E),w=0,h=0;return}J(g,d,o);for(let z of E)p.delete(z);w++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(w,6))};b instanceof Promise?b.then(D).catch(()=>{J(g,d,o);for(let I of E)p.delete(I);w++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(w,6))}):D(b)},A=typeof TextEncoder!="undefined"?new TextEncoder:null,$=g=>A?A.encode(g).length:g.length,K=g=>{let S=[],E=2;for(let b of g){let D=$(JSON.stringify(b))+1;if(S.length>0&&E+D>57344||S.length>=n)break;S.push(b),E+=D}return S},T=()=>{try{if(Date.now()<h)return;for(;i.length>0;){let g=i.filter(E=>!r.has(E.id));if(i.length=0,g.length===0)break;let S=K(g);if(S.length===0)break;S.length<g.length&&i.push(...g.slice(S.length)),k(S)}}catch(g){}},L=!0,N=null;N=setInterval(()=>{L&&T()},t);let f=()=>{document.visibilityState==="hidden"&&T()},y=()=>{T()};return document.addEventListener("visibilitychange",f),window.addEventListener("beforeunload",y),{push(g){m(g),i.length>=n&&T()},flush:T,destroy(){L=!1,N!==null&&(clearInterval(N),N=null),document.removeEventListener("visibilitychange",f),window.removeEventListener("beforeunload",y),T()}}}var H="_snt_asgn_";function F(e,t){return`${e}:${t}`}function Ke(e,t){return`${H}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function ie(e){let t=e.slice(H.length),n=t.indexOf(":");if(n<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,n)),segment:decodeURIComponent(t.slice(n+1))}}catch(d){return null}}function Q(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(H)&&e.push(n)}return e}catch(e){return[]}}function ae(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of Q())try{let a=localStorage.getItem(s);if(!a)continue;let o=JSON.parse(a);if(n(o)){localStorage.removeItem(s);continue}let i=ie(s);if(!i)continue;t.set(F(i.componentId,i.segment),o)}catch(a){}})(),{get(s,a){let o=t.get(F(s,a));return o?n(o)?(t.delete(F(s,a)),null):o:null},set(s,a,o){let i=F(s,a);t.set(i,o);try{localStorage.setItem(Ke(s,a),JSON.stringify(o))}catch(r){}},invalidate(s){let a=`${s}:`;for(let o of[...t.keys()])o.startsWith(a)&&t.delete(o);for(let o of Q()){let i=ie(o);if((i==null?void 0:i.componentId)===s)try{localStorage.removeItem(o)}catch(r){}}},clear(){t.clear();for(let s of Q())try{localStorage.removeItem(s)}catch(a){}}}}var ce=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function j(e){return de(e)!==null}function de(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=ce.find(d=>t.includes(d.toLowerCase())))!=null?n:null}function R(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 M(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 d=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(d)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(d)?"social":"referral"}catch(n){return"direct"}}function U(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function P(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function q(e){let t=Be("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Be(e,t){var a,o,i,r,c,l,p;let n=(o=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?o:"",d=(r=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?r:"",s=(c=t==null?void 0:t.now)!=null?c:new Date;return{sessionId:e,ephemeral:!1,utmParams:(l=t==null?void 0:t.utmParams)!=null?l:{},deviceClass:n?R(n):"desktop",trafficSource:d?M(d,t==null?void 0:t.appOrigin):"direct",referrerDomain:U(d),timeOfDay:P(s),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?p:"sun",automation:(t==null?void 0:t.webdriver)===!0||j(n)}}var ue="https://api.sentient-ui.com/v1/events",V=new Map,We=null;function Y(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var G={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Fe(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,d]of t)n.startsWith("utm_")&&(e[n]=d);return e}catch(e){return{}}}function le(e){return e.replace(/\/events\/?$/,"")}function je(){return[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function ze(e){var o;let t=le((o=e.ingestUrl)!=null?o:ue),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},d={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(i,r,c){try{let l=new URLSearchParams({componentId:i});for(let u of r!=null?r:[])l.append("variantIds[]",u);let p=await fetch(`${t}/winner?${l.toString()}`,{headers:n});return p.ok?{variantId:(await p.json()).variantId,assignmentTtlMs:0}:r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}catch(l){return r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},s={track:i=>d.track(i),goal:(i,r,c,l)=>d.goal(i,r,c,l),componentGoal:(i,r,c)=>d.componentGoal(i,r,c),identify:i=>d.identify(i),getAssignment:(i,r)=>d.getAssignment(i,r),assign:(i,r,c,l)=>d.assign(i,r,c,l),fetchWeights:()=>d.fetchWeights(),getGraph:()=>d.getGraph(),destroy:()=>d.destroy()};function a(i){d=i}return{proxy:s,setInner:a}}function ge(e){var A,$,K,T,L,N;if(typeof window=="undefined")return G;We=e.apiKey;let t=e.respectDoNotTrack!==!1&&je();if(e.consent===!1||t){if(e.preConsentBehavior==="statistical_winner"){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."),G;let{proxy:f,setInner:y}=ze(e);return V.set(e.apiKey,{config:e,upgrade:t?null:y}),f}return V.set(e.apiKey,{config:e,upgrade:null}),G}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."),G;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),G;let n=(A=e.ingestUrl)!=null?A:ue,d=Date.now(),s=re({ssrSessionId:e.ssrSessionId}),a=ae(),o=se({ingestUrl:n,apiKey:e.apiKey}),i=le(n),r={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c=R(($=navigator.userAgent)!=null?$:""),l=typeof window!="undefined"?window.location.origin:void 0,p=M((K=document.referrer)!=null?K:"",l),m=(T=e.sessionSegment)!=null?T:`${c}:${p}`,u=new Map;if(e.initialAssignments)for(let[f,y]of Object.entries(e.initialAssignments))a.set(f,m,{variantId:y,assignedAt:Date.now(),segment:m,confidence:1});let h=Promise.resolve(),w=s.getSessionId();if(w){let f=U((L=document.referrer)!=null?L:""),y=_(_({sessionId:w,deviceClass:c,trafficSource:p,referrerDomain:f,utmParams:Fe(),timeOfDay:P(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:s.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||j((N=navigator.userAgent)!=null?N:"")},e.userId?{userId:e.userId}:{}),e.country?{country:e.country}:{});try{h=fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(y),headers:r}).then(v=>{v.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(v){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let k={goal(f,y={},v=1,x=0){let C=s.getSessionId();if(!C)return;let g=Y();h.then(()=>{fetch(`${i}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:C,name:f,metadata:y,weight:v,stepIndex:x,goalId:g}),headers:r}).catch(()=>{})})},componentGoal(f,y,v){var S,E;let x=s.getSessionId();if(!x)return;let C=a.get(f,m);if(!C){e.debug&&console.warn(`[sentient] componentGoal("${f}"): no assignment yet \u2014 render its <Adaptive> or call assign() before recording a goal.`);return}let g={id:Y(),sessionId:x,projectId:e.apiKey,componentId:f,variantId:C.variantId,eventType:"goal_achieved",goalType:y,payload:_({reward:(S=v==null?void 0:v.reward)!=null?S:1},(E=v==null?void 0:v.metadata)!=null?E:{}),timestamp:Date.now(),timeInSession:Date.now()-d};e.debug&&console.log("[sentient] componentGoal",g),h.then(()=>o.push(g))},identify(f){let y=s.getSessionId();y&&h.then(()=>{fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,userId:f,ephemeral:s.isEphemeral()}),headers:r}).catch(()=>{})})},track(f){let y=s.getSessionId();if(!y)return;let v=W(_({},f),{id:Y(),sessionId:y,timestamp:Date.now(),timeInSession:Date.now()-d});e.debug&&console.log("[sentient] track",v),h.then(()=>o.push(v))},getAssignment(f,y){return a.get(f,y)},async assign(f,y,v,x){let C=s.getSessionId();if(!C)return null;let g=a.get(f,m);if(g&&(y!=null&&y.length||g.content!==void 0))return{variantId:g.variantId,assignmentTtlMs:0,content:g.content};let S=u.get(f);if(S)return S;let E=(async()=>{await h;try{let b={sessionId:C,componentId:f,variantIds:y};x!==void 0?b.agentDataByVariant=x:v!==void 0&&(b.agentData=v);let D=await fetch(`${i}/assign`,{method:"POST",body:JSON.stringify(b),headers:r});if(!D.ok)return null;let I=await D.json();return a.set(f,m,{variantId:I.variantId,assignedAt:Date.now(),segment:m,confidence:1,content:I.content}),I}catch(b){return null}finally{u.delete(f)}})();return u.set(f,E),E},async fetchWeights(){var f;try{let y=await fetch(`${i}/weights`,{headers:r});return y.ok?(f=(await y.json()).components)!=null?f:[]:[]}catch(y){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){o.destroy(),s.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(V.set(e.apiKey,{config:e,upgrade:null}),e.debug){let f=window;f.__sentient&&(f.__sentient.client=k)}return k}var Je=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Qe="h1, h2, h3",He={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function X(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function qe(e){var t,n,d;try{let s=e;for(let a of Object.keys(s)){if(!a.startsWith("__reactFiber")&&!a.startsWith("__reactInternalInstance"))continue;let o=s[a],i=(d=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?d:(n=o==null?void 0:o.type)==null?void 0:n.name;if(i&&i.length>1)return i}}catch(s){}}function Ve(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function Ye(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function Xe(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 Z(e,t){var d,s,a;let n=e.querySelector(Qe);return{componentId:Xe(e),semanticType:Ye(e),ariaLabel:(d=e.getAttribute("aria-label"))!=null?d:void 0,headingText:(a=(s=n==null?void 0:n.textContent)==null?void 0:s.trim())!=null?a:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:Ze(e),reactComponentName:qe(e),dataAttributes:Ve(e)}}function pe(e){var a;let t=[],n=new Set,d="__root__",s=new Map;for(let[o,i]of e){let r=o.parentElement,c=d;for(;r;){if(e.has(r)){c=e.get(r);let p=e.get(o),m=`${c}->${p}`;!n.has(m)&&c!==p&&(n.add(m),t.push({fromComponentId:c,toComponentId:p,weight:.6}));break}r=r.parentElement}let l=(a=s.get(c))!=null?a:[];l.push(o),s.set(c,l)}for(let o of s.values())if(!(o.length<2))for(let i=0;i<o.length;i++)for(let r=i+1;r<o.length;r++){let c=e.get(o[i]),l=e.get(o[r]);if(c===l)continue;let p=`${c}->${l}::sib`,m=`${l}->${c}::sib`;n.has(p)||(n.add(p),t.push({fromComponentId:c,toComponentId:l,weight:.3})),n.has(m)||(n.add(m),t.push({fromComponentId:l,toComponentId:c,weight:.3}))}return t}function et(e){let t=[],n=new Set,d=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let i=Z(o,e);t.push(i),d.set(o,i.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let i=o.hasAttribute("aria-label"),r=o.hasAttribute("data-sentient-id");if(!i&&!r)return;n.add(o);let c=Z(o,e);t.push(c),d.set(o,c.componentId)}),{nodes:t,edges:pe(d)}}function fe(){if(typeof window=="undefined")return He;let e=null,t=0,n=null,d=i=>{try{let r=window.getComputedStyle(i),c=parseFloat(r.fontSize)||12,l=parseFloat(r.zIndex)||0,p=i.getBoundingClientRect(),m=Math.max(p.top,0),u=window.innerHeight||1,h=1/(m/u+1),w=X(c,12,48)*.4+X(h,0,1)*.4+X(l,0,100)*.2;return Math.max(0,Math.min(1,w))}catch(r){return .5}};return{scan:()=>new Promise(i=>{let r=()=>{let{nodes:c,edges:l}=et(d);i({nodes:c,edges:l,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(r,{timeout:100}):r()}catch(c){r()}}),observe:i=>{n=i;try{e=new MutationObserver(r=>{let c=[],l=new Map;for(let p of r)p.type==="childList"&&p.addedNodes.forEach(m=>{if(!(m instanceof Element)||!Je.has(m.tagName))return;let u=m.hasAttribute("data-sentient-id"),h=m.hasAttribute("aria-label");if(!u&&!h)return;let w=Z(m,d);c.push(w),l.set(m,w.componentId)});c.length>0&&n&&n({nodes:c,edges:pe(l),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(r){}},getProminenceScore:d,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null}}}var ee="_snt_graph_nodes",me="_snt_graph_edges",tt={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function nt(e){var t;return(t=tt[e])!=null?t:[]}function ot(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function rt(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var st=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function it(e){return st.has(e)?e:"generic"}function at(e,t,n){let d=`${e}:${t}:${n.join(",")}`,s=5381;for(let a=0;a<d.length;a++)s=(s<<5)+s+d.charCodeAt(a)&4294967295;return(s>>>0).toString(16).padStart(8,"0")}function he(e){let t=new Map,n=new Map,d=()=>{typeof window!="undefined"&&rt(ee,[...t.values()])},s=a=>{var o;try{let i=JSON.parse(a);t.clear();for(let r of(o=i.pageNodes)!=null?o:[])t.set(r.componentId,r)}catch(i){}};if(typeof window!="undefined"){let a=ot(ee,[]);for(let o of a)t.set(o.componentId,o);try{localStorage.removeItem(me)}catch(o){}}return{addPageNode(a){t.set(a.componentId,a),d()},addStructuralEdge(a){let o=`${a.fromComponentId}->${a.toComponentId}`;n.set(o,a)},syncOnce(){var o,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let a=[...t.values()];if(a.length!==0)try{let r=new Map;for(let u of a){let h=(o=r.get(u.semanticType))!=null?o:[];h.push(u),r.set(u.semanticType,h)}let c=[],l=new Set;for(let u of a)for(let h of nt(u.semanticType)){let w=(i=r.get(h))!=null?i:[];for(let k of w){if(k.componentId===u.componentId)continue;let A=`semantic:${u.componentId}->${k.componentId}`;l.has(A)||(l.add(A),c.push({fromComponentId:u.componentId,toComponentId:k.componentId,type:"semantic",weight:.4,confidence:.9}))}}let p=new Set(a.map(u=>u.componentId));for(let u of n.values()){if(!p.has(u.fromComponentId)||!p.has(u.toComponentId))continue;let h=`structural:${u.fromComponentId}->${u.toComponentId}`;l.has(h)||(l.add(h),c.push({fromComponentId:u.fromComponentId,toComponentId:u.toComponentId,type:"structural",weight:u.weight,confidence:1}))}let m={pageUrl:window.location.href,nodes:a.map(u=>{let h=it(u.semanticType);return{componentId:u.componentId,semanticType:h,answers:u.answers,contentHash:at(u.componentId,h,u.answers),prominenceScore:u.prominenceScore,depthInPage:u.depth}}),edges:c};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:_({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(m)}).catch(()=>{})}catch(r){}},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(ee),localStorage.removeItem(me)}catch(a){}}}}var ct="https://api.sentient-ui.com/v1/events";function dt(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function ut(e){var i;let t=ge(e);if(!e.graph||typeof window=="undefined")return t;let n=fe(),d=(i=e.ingestUrl)!=null?i:ct,s=he({syncUrl:d.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:dt()});try{let r=localStorage.getItem("_snt_graph_nodes");r&&s.restore(JSON.stringify({pageNodes:JSON.parse(r)}))}catch(r){}n.scan().then(r=>{for(let c of r.nodes)s.addPageNode({id:c.componentId,componentId:c.componentId,semanticType:c.semanticType,answers:c.headingText?[c.headingText]:[],prominenceScore:c.prominenceScore,depth:c.depth});for(let c of r.edges)s.addStructuralEdge(c);s.syncOnce()});let a=null,o=()=>{a!==null&&clearTimeout(a),a=setTimeout(()=>{a=null,s.syncOnce()},500)};return n.observe(r=>{for(let c of r.nodes)s.addPageNode({id:c.componentId,componentId:c.componentId,semanticType:c.semanticType,answers:c.headingText?[c.headingText]:[],prominenceScore:c.prominenceScore,depth:c.depth});for(let c of r.edges)s.addStructuralEdge(c);o()}),W(_({},t),{getGraph:()=>s.snapshot(),destroy:()=>{a!==null&&clearTimeout(a),n.destroy(),s.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,referrerDomainFromReferer});
|
package/dist/index-graph.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{d as v}from"./chunk-6PD6FNO7.mjs";import{a as h,b,f as x,g as _,h as O,i as R,j as M}from"./chunk-CFXMEZCZ.mjs";var P=new Set(["SECTION","ARTICLE","MAIN","DIV"]),D="h1, h2, h3",G={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 k(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 r=d[s],i=(p=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?p:(n=r==null?void 0:r.type)==null?void 0:n.name;if(i&&i.length>1)return i}}catch(d){}}function $(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function L(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function U(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function j(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(D);return{componentId:U(e),semanticType:L(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:j(e),reactComponentName:k(e),dataAttributes:$(e)}}function w(e){var s;let t=[],n=new Set,p="__root__",d=new Map;for(let[r,i]of e){let a=r.parentElement,o=p;for(;a;){if(e.has(a)){o=e.get(a);let m=e.get(r),g=`${o}->${m}`;!n.has(g)&&o!==m&&(n.add(g),t.push({fromComponentId:o,toComponentId:m,weight:.6}));break}a=a.parentElement}let u=(s=d.get(o))!=null?s:[];u.push(r),d.set(o,u)}for(let r of d.values())if(!(r.length<2))for(let i=0;i<r.length;i++)for(let a=i+1;a<r.length;a++){let o=e.get(r[i]),u=e.get(r[a]);if(o===u)continue;let m=`${o}->${u}::sib`,g=`${u}->${o}::sib`;n.has(m)||(n.add(m),t.push({fromComponentId:o,toComponentId:u,weight:.3})),n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:o,weight:.3}))}return t}function F(e){let t=[],n=new Set,p=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let i=I(r,e);t.push(i),p.set(r,i.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let i=r.hasAttribute("aria-label"),a=r.hasAttribute("data-sentient-id");if(!i&&!a)return;n.add(r);let o=I(r,e);t.push(o),p.set(r,o.componentId)}),{nodes:t,edges:w(p)}}function N(){if(typeof window=="undefined")return G;let e=null,t=0,n=null,p=i=>{try{let a=window.getComputedStyle(i),o=parseFloat(a.fontSize)||12,u=parseFloat(a.zIndex)||0,m=i.getBoundingClientRect(),g=Math.max(m.top,0),c=window.innerHeight||1,l=1/(g/c+1),f=S(o,12,48)*.4+S(l,0,1)*.4+S(u,0,100)*.2;return Math.max(0,Math.min(1,f))}catch(a){return .5}};return{scan:()=>new Promise(i=>{let a=()=>{let{nodes:o,edges:u}=F(p);i({nodes:o,edges:u,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(a,{timeout:100}):a()}catch(o){a()}}),observe:i=>{n=i;try{e=new MutationObserver(a=>{let o=[],u=new Map;for(let m of a)m.type==="childList"&&m.addedNodes.forEach(g=>{if(!(g instanceof Element)||!P.has(g.tagName))return;let c=g.hasAttribute("data-sentient-id"),l=g.hasAttribute("aria-label");if(!c&&!l)return;let f=I(g,p);o.push(f),u.set(g,f.componentId)});o.length>0&&n&&n({nodes:o,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(i){}t=0,n=null}}}var C="_snt_graph_nodes",A="_snt_graph_edges",K={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function q(e){var t;return(t=K[e])!=null?t:[]}function z(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function H(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var J=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function B(e){return J.has(e)?e:"generic"}function V(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"&&H(C,[...t.values()])},d=s=>{var r;try{let i=JSON.parse(s);t.clear();for(let a of(r=i.pageNodes)!=null?r:[])t.set(a.componentId,a)}catch(i){}};if(typeof window!="undefined"){let s=z(C,[]);for(let r of s)t.set(r.componentId,r);try{localStorage.removeItem(A)}catch(r){}}return{addPageNode(s){t.set(s.componentId,s),p()},addStructuralEdge(s){let r=`${s.fromComponentId}->${s.toComponentId}`;n.set(r,s)},syncOnce(){var r,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let s=[...t.values()];if(s.length!==0)try{let a=new Map;for(let c of s){let l=(r=a.get(c.semanticType))!=null?r:[];l.push(c),a.set(c.semanticType,l)}let o=[],u=new Set;for(let c of s)for(let l of q(c.semanticType)){let f=(i=a.get(l))!=null?i:[];for(let y of f){if(y.componentId===c.componentId)continue;let E=`semantic:${c.componentId}->${y.componentId}`;u.has(E)||(u.add(E),o.push({fromComponentId:c.componentId,toComponentId:y.componentId,type:"semantic",weight:.4,confidence:.9}))}}let m=new Set(s.map(c=>c.componentId));for(let c of n.values()){if(!m.has(c.fromComponentId)||!m.has(c.toComponentId))continue;let l=`structural:${c.fromComponentId}->${c.toComponentId}`;u.has(l)||(u.add(l),o.push({fromComponentId:c.fromComponentId,toComponentId:c.toComponentId,type:"structural",weight:c.weight,confidence:1}))}let g={pageUrl:window.location.href,nodes:s.map(c=>{let l=B(c.semanticType);return{componentId:c.componentId,semanticType:l,answers:c.answers,contentHash:V(c.componentId,l,c.answers),prominenceScore:c.prominenceScore,depthInPage:c.depth}}),edges:o};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 W="https://api.sentient-ui.com/v1/events";function Y(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function oe(e){var i;let t=v(e);if(!e.graph||typeof window=="undefined")return t;let n=N(),p=(i=e.ingestUrl)!=null?i:W,d=T({syncUrl:p.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:Y()});try{let a=localStorage.getItem("_snt_graph_nodes");a&&d.restore(JSON.stringify({pageNodes:JSON.parse(a)}))}catch(a){}n.scan().then(a=>{for(let o of a.nodes)d.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 a.edges)d.addStructuralEdge(o);d.syncOnce()});let s=null,r=()=>{s!==null&&clearTimeout(s),s=setTimeout(()=>{s=null,d.syncOnce()},500)};return n.observe(a=>{for(let o of a.nodes)d.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 a.edges)d.addStructuralEdge(o);r()}),b(h({},t),{getGraph:()=>d.snapshot(),destroy:()=>{s!==null&&clearTimeout(s),n.destroy(),d.destroy(),t.destroy()}})}export{M as deriveSessionSegment,x as detectDeviceClass,R as detectTimeOfDay,_ as detectTrafficSource,oe as init,O as referrerDomainFromReferer};
|
package/dist/index-server.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { S as SessionUpsertPayload, b as buildSessionUpsertPayload, d as deriveSessionSegment,
|
|
1
|
+
export { S as SessionUpsertPayload, b as buildSessionUpsertPayload, d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-D5IgJuRW.cjs';
|
|
2
2
|
|
|
3
3
|
type ServerAssignConfig = {
|
|
4
4
|
/** Public API key (pk_...). */
|
|
@@ -40,7 +40,7 @@ type ServerAssignments = Record<string, string>;
|
|
|
40
40
|
* { id: 'cta', variantIds: ['cta-short', 'cta-long'] },
|
|
41
41
|
* ],
|
|
42
42
|
* sessionId, // read from cookies() or req.cookies
|
|
43
|
-
* { apiKey: process.env.
|
|
43
|
+
* { apiKey: process.env.NEXT_PUBLIC_SENTIENT_API_KEY!, baseUrl: 'https://api.sentient-ui.com/v1' },
|
|
44
44
|
* );
|
|
45
45
|
* return <AdaptiveProvider ... initialAssignments={assignments}>{children}</AdaptiveProvider>;
|
|
46
46
|
* ```
|
package/dist/index-server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { S as SessionUpsertPayload, b as buildSessionUpsertPayload, d as deriveSessionSegment,
|
|
1
|
+
export { S as SessionUpsertPayload, b as buildSessionUpsertPayload, d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, r as referrerDomainFromReferer } from './session-meta-D5IgJuRW.js';
|
|
2
2
|
|
|
3
3
|
type ServerAssignConfig = {
|
|
4
4
|
/** Public API key (pk_...). */
|
|
@@ -40,7 +40,7 @@ type ServerAssignments = Record<string, string>;
|
|
|
40
40
|
* { id: 'cta', variantIds: ['cta-short', 'cta-long'] },
|
|
41
41
|
* ],
|
|
42
42
|
* sessionId, // read from cookies() or req.cookies
|
|
43
|
-
* { apiKey: process.env.
|
|
43
|
+
* { apiKey: process.env.NEXT_PUBLIC_SENTIENT_API_KEY!, baseUrl: 'https://api.sentient-ui.com/v1' },
|
|
44
44
|
* );
|
|
45
45
|
* return <AdaptiveProvider ... initialAssignments={assignments}>{children}</AdaptiveProvider>;
|
|
46
46
|
* ```
|
package/dist/index-server.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var m=Object.defineProperty,
|
|
1
|
+
"use strict";var m=Object.defineProperty,k=Object.defineProperties,I=Object.getOwnPropertyDescriptor,$=Object.getOwnPropertyDescriptors,j=Object.getOwnPropertyNames,b=Object.getOwnPropertySymbols;var A=Object.prototype.hasOwnProperty,B=Object.prototype.propertyIsEnumerable;var w=(t,e,r)=>e in t?m(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,v=(t,e)=>{for(var r in e||(e={}))A.call(e,r)&&w(t,r,e[r]);if(b)for(var r of b(e))B.call(e,r)&&w(t,r,e[r]);return t},U=(t,e)=>k(t,$(e));var M=(t,e)=>{for(var r in e)m(t,r,{get:e[r],enumerable:!0})},L=(t,e,r,s)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of j(e))!A.call(t,i)&&i!==r&&m(t,i,{get:()=>e[i],enumerable:!(s=I(e,i))||s.enumerable});return t};var _=t=>L(m({},"__esModule",{value:!0}),t);var z={};M(z,{buildSessionUpsertPayload:()=>g,deriveSessionSegment:()=>x,detectDeviceClass:()=>p,detectTimeOfDay:()=>S,detectTrafficSource:()=>y,preloadAssignments:()=>P,preloadDecisions:()=>O,readSessionCookie:()=>C,referrerDomainFromReferer:()=>h});module.exports=_(z);var E=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function J(t){return N(t)!==null}function N(t){var r;if(!t)return null;let e=t.toLowerCase();return(r=E.find(s=>e.includes(s.toLowerCase())))!=null?r:null}function p(t){let e=t.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(e)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(e)?"mobile":"desktop"}function y(t,e){if(!t)return"direct";try{let r=new URL(t);if(e)try{if(new URL(e).host===r.host)return"direct"}catch(i){}let s=r.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(s)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(s)?"social":"referral"}catch(r){return"direct"}}function h(t){if(!t)return null;try{return new URL(t).hostname}catch(e){return null}}function S(t){let e=t.getHours();return e<6?"night":e<12?"morning":e<18?"afternoon":"evening"}function x(t){let e=g("__segment__",t);return`${e.deviceClass}:${e.trafficSource}`}function g(t,e){var a,l,c,o,n,d,u;let r=(l=(a=e==null?void 0:e.userAgent)==null?void 0:a.trim())!=null?l:"",s=(o=(c=e==null?void 0:e.referer)==null?void 0:c.trim())!=null?o:"",i=(n=e==null?void 0:e.now)!=null?n:new Date;return{sessionId:t,ephemeral:!1,utmParams:(d=e==null?void 0:e.utmParams)!=null?d:{},deviceClass:r?p(r):"desktop",trafficSource:s?y(s,e==null?void 0:e.appOrigin):"direct",referrerDomain:h(s),timeOfDay:S(i),dayOfWeek:(u=["sun","mon","tue","wed","thu","fri","sat"][i.getDay()])!=null?u:"sun",automation:(e==null?void 0:e.webdriver)===!0||J(r)}}var D=1500;function f(t,e,r){let s=new AbortController,i=setTimeout(()=>s.abort(),r);return fetch(t,U(v({},e),{signal:s.signal})).finally(()=>clearTimeout(i))}async function P(t,e,r){var o;let s=(o=r.timeoutMs)!=null?o:D,i={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(i.Origin=r.origin);let a=g(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let n=await f(`${r.baseUrl}/sessions`,{method:"POST",headers:i,body:JSON.stringify(a)},s);if(n.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!n.ok){let d=await n.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${n.status})`,d)}}catch(n){console.error("[SentientUI] preloadAssignments: session upsert threw",n)}let l=await Promise.allSettled(t.map(async({id:n,variantIds:d})=>{let u=await f(`${r.baseUrl}/assign`,{method:"POST",headers:i,body:JSON.stringify({sessionId:e,componentId:n,variantIds:d})},s);if(!u.ok){let T=await u.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${n}" (${u.status})`,T),null}let R=await u.json();return{id:n,variantId:R.variantId}})),c={};for(let n of l)n.status==="fulfilled"&&n.value&&(c[n.value.id]=n.value.variantId);return c}function C(t){var e,r;return(r=(e=t.get("_snt_uid"))==null?void 0:e.value)!=null?r:null}async function O(t,e,r){var c;let s=(c=r.timeoutMs)!=null?c:D,i={layoutOrder:t.sections,assignments:{},persona:"unknown",confidence:0},a={"Content-Type":"application/json",Authorization:`Bearer ${r.apiKey}`};r.origin&&(a.Origin=r.origin);let l=g(e,{userAgent:r.userAgent,referer:r.referer,utmParams:r.utmParams,appOrigin:r.origin});try{let o=await f(`${r.baseUrl}/sessions`,{method:"POST",headers:a,body:JSON.stringify(l)},s);if(!o.ok){let n=await o.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${o.status})`,n)}}catch(o){console.error("[SentientUI] preloadDecisions: session upsert threw",o)}try{let o=await f(`${r.baseUrl}/decide`,{method:"POST",headers:a,body:JSON.stringify({sessionId:e,sections:t.sections.map(n=>({id:n})),components:t.components})},s);if(!o.ok){let n=await o.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${o.status})`,n),i}return await o.json()}catch(o){return console.error("[SentientUI] preloadDecisions: decide threw",o),i}}0&&(module.exports={buildSessionUpsertPayload,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,preloadAssignments,preloadDecisions,readSessionCookie,referrerDomainFromReferer});
|
package/dist/index-server.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as p,b as y,
|
|
1
|
+
import{a as p,b as y,f as b,g as h,h as v,i as U,j as w,k as d}from"./chunk-CFXMEZCZ.mjs";var S=1500;function u(n,r,e){let i=new AbortController,o=setTimeout(()=>i.abort(),e);return fetch(n,y(p({},r),{signal:i.signal})).finally(()=>clearTimeout(o))}async function O(n,r,e){var t;let i=(t=e.timeoutMs)!=null?t:S,o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(o.Origin=e.origin);let a=d(r,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let s=await u(`${e.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(a)},i);if(s.status===402)console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing");else if(!s.ok){let m=await s.json().catch(()=>({}));console.error(`[SentientUI] preloadAssignments: session upsert failed (${s.status})`,m)}}catch(s){console.error("[SentientUI] preloadAssignments: session upsert threw",s)}let g=await Promise.allSettled(n.map(async({id:s,variantIds:m})=>{let c=await u(`${e.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:r,componentId:s,variantIds:m})},i);if(!c.ok){let A=await c.json().catch(()=>({}));return console.error(`[SentientUI] preloadAssignments: assign failed for "${s}" (${c.status})`,A),null}let f=await c.json();return{id:s,variantId:f.variantId}})),l={};for(let s of g)s.status==="fulfilled"&&s.value&&(l[s.value.id]=s.value.variantId);return l}function P(n){var r,e;return(e=(r=n.get("_snt_uid"))==null?void 0:r.value)!=null?e:null}async function R(n,r,e){var l;let i=(l=e.timeoutMs)!=null?l:S,o={layoutOrder:n.sections,assignments:{},persona:"unknown",confidence:0},a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`};e.origin&&(a.Origin=e.origin);let g=d(r,{userAgent:e.userAgent,referer:e.referer,utmParams:e.utmParams,appOrigin:e.origin});try{let t=await u(`${e.baseUrl}/sessions`,{method:"POST",headers:a,body:JSON.stringify(g)},i);if(!t.ok){let s=await t.json().catch(()=>({}));console.error(`[SentientUI] preloadDecisions: session upsert failed (${t.status})`,s)}}catch(t){console.error("[SentientUI] preloadDecisions: session upsert threw",t)}try{let t=await u(`${e.baseUrl}/decide`,{method:"POST",headers:a,body:JSON.stringify({sessionId:r,sections:n.sections.map(s=>({id:s})),components:n.components})},i);if(!t.ok){let s=await t.json().catch(()=>({}));return console.error(`[SentientUI] preloadDecisions: decide failed (${t.status})`,s),o}return await t.json()}catch(t){return console.error("[SentientUI] preloadDecisions: decide threw",t),o}}export{d as buildSessionUpsertPayload,w as deriveSessionSegment,b as detectDeviceClass,U as detectTimeOfDay,h as detectTrafficSource,O as preloadAssignments,R as preloadDecisions,P as readSessionCookie,v as referrerDomainFromReferer};
|
package/dist/index.d.cts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { d as deriveSessionSegment,
|
|
1
|
+
export { a as agentUaList, d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, m as matchedAgentToken, r as referrerDomainFromReferer, u as uaTokenMatch } from './session-meta-D5IgJuRW.cjs';
|
|
2
2
|
|
|
3
3
|
/** Manages anonymous session identity with cookie + localStorage layers. */
|
|
4
4
|
type SessionConfig = {
|
|
@@ -168,9 +168,18 @@ type SentientConfig = {
|
|
|
168
168
|
* Behavior before consent is granted. `'statistical_winner'` fetches the
|
|
169
169
|
* best-performing variant via `GET /v1/winner` — no session or tracking data
|
|
170
170
|
* is stored. `'control'` (default) shows `variantIds[0]` with no API call.
|
|
171
|
-
*
|
|
171
|
+
* Applies when tracking is gated off — either `consent: false` or an active
|
|
172
|
+
* Do Not Track signal.
|
|
172
173
|
*/
|
|
173
174
|
preConsentBehavior?: 'statistical_winner' | 'control';
|
|
175
|
+
/**
|
|
176
|
+
* Whether to honor the browser's Do Not Track (DNT) signal. Defaults to `true`.
|
|
177
|
+
* When `true` and the visitor has DNT enabled, the SDK sets no cookies and
|
|
178
|
+
* sends no tracking data — behaving exactly as `consent: false` (still serving
|
|
179
|
+
* the read-only `preConsentBehavior` winner if configured), and `grantConsent()`
|
|
180
|
+
* will not upgrade it. Set `false` to make your own consent gate authoritative.
|
|
181
|
+
*/
|
|
182
|
+
respectDoNotTrack?: boolean;
|
|
174
183
|
userId?: string;
|
|
175
184
|
/**
|
|
176
185
|
* Session ID generated server-side (from `loadAdaptiveAssignments` / `loadAdaptiveDecision`).
|
|
@@ -178,6 +187,13 @@ type SentientConfig = {
|
|
|
178
187
|
* ensuring events and goals are attributed to the same session the server used for assignment.
|
|
179
188
|
*/
|
|
180
189
|
ssrSessionId?: string;
|
|
190
|
+
/**
|
|
191
|
+
* ISO 3166-1 alpha-2 country code for the visitor. When provided (e.g. from
|
|
192
|
+
* the `CF-IPCountry` header in a Next.js server component), it is included in
|
|
193
|
+
* the session upsert so country-based segmentation works without client-side
|
|
194
|
+
* geo lookup.
|
|
195
|
+
*/
|
|
196
|
+
country?: string;
|
|
181
197
|
};
|
|
182
198
|
type AssignResult = {
|
|
183
199
|
variantId: string;
|
|
@@ -194,9 +210,24 @@ type ComponentWeightEntry = {
|
|
|
194
210
|
updatedAt: number;
|
|
195
211
|
variants: WeightEntry[];
|
|
196
212
|
};
|
|
213
|
+
type ComponentGoalOptions = {
|
|
214
|
+
/** Reward credited to the served variant (0–1). Defaults to 1. */
|
|
215
|
+
reward?: number;
|
|
216
|
+
/** Extra fields merged into the event payload. */
|
|
217
|
+
metadata?: Record<string, unknown>;
|
|
218
|
+
};
|
|
197
219
|
type SentientClient = {
|
|
198
220
|
track(event: Omit<SentientEvent, 'id' | 'sessionId' | 'timestamp' | 'timeInSession'>): void;
|
|
199
221
|
goal(name: string, metadata?: Record<string, unknown>, weight?: number, stepIndex?: number): void;
|
|
222
|
+
/**
|
|
223
|
+
* Records a conversion attributed to the variant currently served for
|
|
224
|
+
* `componentId`, so it feeds the per-variant CVR funnel. Resolves the served
|
|
225
|
+
* variant from the local assignment cache — no need to pass variantId or
|
|
226
|
+
* projectId. No-ops if the component has not been assigned yet (render its
|
|
227
|
+
* `<Adaptive>`/call `assign()` first). Prefer this over bare `goal()` for
|
|
228
|
+
* variant experiments; `goal()` is session-level only (no component attribution).
|
|
229
|
+
*/
|
|
230
|
+
componentGoal(componentId: string, goalType: string, opts?: ComponentGoalOptions): void;
|
|
200
231
|
identify(userId: string): void;
|
|
201
232
|
getAssignment(componentId: string, segment: string): Assignment | null;
|
|
202
233
|
/** Server-side variant assignment. Caches the result locally per (component, segment). */
|
|
@@ -207,6 +238,13 @@ type SentientClient = {
|
|
|
207
238
|
destroy(): void;
|
|
208
239
|
};
|
|
209
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Detects whether the visitor has enabled the browser's Do Not Track signal.
|
|
243
|
+
* Checks the standard `navigator.doNotTrack`, the legacy `window.doNotTrack`
|
|
244
|
+
* (older Firefox), and `navigator.msDoNotTrack` (old IE/Edge). Returns `true`
|
|
245
|
+
* only when one is explicitly set to opt out (`'1'` or `'yes'`).
|
|
246
|
+
*/
|
|
247
|
+
declare function isDoNotTrackEnabled(): boolean;
|
|
210
248
|
/**
|
|
211
249
|
* Upgrades a pre-consent client (created with `consent: false, preConsentBehavior: 'statistical_winner'`)
|
|
212
250
|
* to a fully-tracking client. Call this from your consent management platform callback.
|
|
@@ -219,4 +257,4 @@ declare function grantConsent(apiKey?: string): void;
|
|
|
219
257
|
*/
|
|
220
258
|
declare function init(config: SentientConfig): SentientClient;
|
|
221
259
|
|
|
222
|
-
export { type AssignResult, type Assignment, type AssignmentCache, type ComponentWeightEntry, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type MicroSignalEmitter, type MicroSignalType, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type SessionConfig, type SessionManager, type WeightEntry, attachMicroSignalDetectors, grantConsent, init };
|
|
260
|
+
export { type AssignResult, type Assignment, type AssignmentCache, type ComponentGoalOptions, type ComponentWeightEntry, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type MicroSignalEmitter, type MicroSignalType, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type SessionConfig, type SessionManager, type WeightEntry, attachMicroSignalDetectors, grantConsent, init, isDoNotTrackEnabled };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { d as deriveSessionSegment,
|
|
1
|
+
export { a as agentUaList, d as deriveSessionSegment, c as detectDeviceClass, e as detectTimeOfDay, f as detectTrafficSource, m as matchedAgentToken, r as referrerDomainFromReferer, u as uaTokenMatch } from './session-meta-D5IgJuRW.js';
|
|
2
2
|
|
|
3
3
|
/** Manages anonymous session identity with cookie + localStorage layers. */
|
|
4
4
|
type SessionConfig = {
|
|
@@ -168,9 +168,18 @@ type SentientConfig = {
|
|
|
168
168
|
* Behavior before consent is granted. `'statistical_winner'` fetches the
|
|
169
169
|
* best-performing variant via `GET /v1/winner` — no session or tracking data
|
|
170
170
|
* is stored. `'control'` (default) shows `variantIds[0]` with no API call.
|
|
171
|
-
*
|
|
171
|
+
* Applies when tracking is gated off — either `consent: false` or an active
|
|
172
|
+
* Do Not Track signal.
|
|
172
173
|
*/
|
|
173
174
|
preConsentBehavior?: 'statistical_winner' | 'control';
|
|
175
|
+
/**
|
|
176
|
+
* Whether to honor the browser's Do Not Track (DNT) signal. Defaults to `true`.
|
|
177
|
+
* When `true` and the visitor has DNT enabled, the SDK sets no cookies and
|
|
178
|
+
* sends no tracking data — behaving exactly as `consent: false` (still serving
|
|
179
|
+
* the read-only `preConsentBehavior` winner if configured), and `grantConsent()`
|
|
180
|
+
* will not upgrade it. Set `false` to make your own consent gate authoritative.
|
|
181
|
+
*/
|
|
182
|
+
respectDoNotTrack?: boolean;
|
|
174
183
|
userId?: string;
|
|
175
184
|
/**
|
|
176
185
|
* Session ID generated server-side (from `loadAdaptiveAssignments` / `loadAdaptiveDecision`).
|
|
@@ -178,6 +187,13 @@ type SentientConfig = {
|
|
|
178
187
|
* ensuring events and goals are attributed to the same session the server used for assignment.
|
|
179
188
|
*/
|
|
180
189
|
ssrSessionId?: string;
|
|
190
|
+
/**
|
|
191
|
+
* ISO 3166-1 alpha-2 country code for the visitor. When provided (e.g. from
|
|
192
|
+
* the `CF-IPCountry` header in a Next.js server component), it is included in
|
|
193
|
+
* the session upsert so country-based segmentation works without client-side
|
|
194
|
+
* geo lookup.
|
|
195
|
+
*/
|
|
196
|
+
country?: string;
|
|
181
197
|
};
|
|
182
198
|
type AssignResult = {
|
|
183
199
|
variantId: string;
|
|
@@ -194,9 +210,24 @@ type ComponentWeightEntry = {
|
|
|
194
210
|
updatedAt: number;
|
|
195
211
|
variants: WeightEntry[];
|
|
196
212
|
};
|
|
213
|
+
type ComponentGoalOptions = {
|
|
214
|
+
/** Reward credited to the served variant (0–1). Defaults to 1. */
|
|
215
|
+
reward?: number;
|
|
216
|
+
/** Extra fields merged into the event payload. */
|
|
217
|
+
metadata?: Record<string, unknown>;
|
|
218
|
+
};
|
|
197
219
|
type SentientClient = {
|
|
198
220
|
track(event: Omit<SentientEvent, 'id' | 'sessionId' | 'timestamp' | 'timeInSession'>): void;
|
|
199
221
|
goal(name: string, metadata?: Record<string, unknown>, weight?: number, stepIndex?: number): void;
|
|
222
|
+
/**
|
|
223
|
+
* Records a conversion attributed to the variant currently served for
|
|
224
|
+
* `componentId`, so it feeds the per-variant CVR funnel. Resolves the served
|
|
225
|
+
* variant from the local assignment cache — no need to pass variantId or
|
|
226
|
+
* projectId. No-ops if the component has not been assigned yet (render its
|
|
227
|
+
* `<Adaptive>`/call `assign()` first). Prefer this over bare `goal()` for
|
|
228
|
+
* variant experiments; `goal()` is session-level only (no component attribution).
|
|
229
|
+
*/
|
|
230
|
+
componentGoal(componentId: string, goalType: string, opts?: ComponentGoalOptions): void;
|
|
200
231
|
identify(userId: string): void;
|
|
201
232
|
getAssignment(componentId: string, segment: string): Assignment | null;
|
|
202
233
|
/** Server-side variant assignment. Caches the result locally per (component, segment). */
|
|
@@ -207,6 +238,13 @@ type SentientClient = {
|
|
|
207
238
|
destroy(): void;
|
|
208
239
|
};
|
|
209
240
|
|
|
241
|
+
/**
|
|
242
|
+
* Detects whether the visitor has enabled the browser's Do Not Track signal.
|
|
243
|
+
* Checks the standard `navigator.doNotTrack`, the legacy `window.doNotTrack`
|
|
244
|
+
* (older Firefox), and `navigator.msDoNotTrack` (old IE/Edge). Returns `true`
|
|
245
|
+
* only when one is explicitly set to opt out (`'1'` or `'yes'`).
|
|
246
|
+
*/
|
|
247
|
+
declare function isDoNotTrackEnabled(): boolean;
|
|
210
248
|
/**
|
|
211
249
|
* Upgrades a pre-consent client (created with `consent: false, preConsentBehavior: 'statistical_winner'`)
|
|
212
250
|
* to a fully-tracking client. Call this from your consent management platform callback.
|
|
@@ -219,4 +257,4 @@ declare function grantConsent(apiKey?: string): void;
|
|
|
219
257
|
*/
|
|
220
258
|
declare function init(config: SentientConfig): SentientClient;
|
|
221
259
|
|
|
222
|
-
export { type AssignResult, type Assignment, type AssignmentCache, type ComponentWeightEntry, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type MicroSignalEmitter, type MicroSignalType, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type SessionConfig, type SessionManager, type WeightEntry, attachMicroSignalDetectors, grantConsent, init };
|
|
260
|
+
export { type AssignResult, type Assignment, type AssignmentCache, type ComponentGoalOptions, type ComponentWeightEntry, type ContentAddedEvent, type DOMScanner, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type MicroSignalEmitter, type MicroSignalType, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type SessionConfig, type SessionManager, type WeightEntry, attachMicroSignalDetectors, grantConsent, init, isDoNotTrackEnabled };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var G=Object.defineProperty,le=Object.defineProperties,ue=Object.getOwnPropertyDescriptor,de=Object.getOwnPropertyDescriptors,ge=Object.getOwnPropertyNames,V=Object.getOwnPropertySymbols;var q=Object.prototype.hasOwnProperty,fe=Object.prototype.propertyIsEnumerable;var Y=(e,t,n)=>t in e?G(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,R=(e,t)=>{for(var n in t||(t={}))q.call(t,n)&&Y(e,n,t[n]);if(V)for(var n of V(t))fe.call(t,n)&&Y(e,n,t[n]);return e},Q=(e,t)=>le(e,de(t));var me=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})},pe=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of ge(t))!q.call(e,o)&&o!==n&&G(e,o,{get:()=>t[o],enumerable:!(i=ue(t,o))||i.enumerable});return e};var he=e=>pe(G({},"__esModule",{value:!0}),e);var Ne={};me(Ne,{attachMicroSignalDetectors:()=>re,deriveSessionSegment:()=>ne,detectDeviceClass:()=>U,detectTimeOfDay:()=>P,detectTrafficSource:()=>L,grantConsent:()=>Me,init:()=>ce,referrerDomainFromReferer:()=>M});module.exports=he(Ne);var ye="_snt_uid";var T="_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 we(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function Ee(e){try{return localStorage.getItem(e)}catch(t){return null}}function xe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function _e(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function be(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Ie(e){try{sessionStorage.removeItem(e)}catch(t){}}function ke(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 Ce(e){try{localStorage.removeItem(e)}catch(t){}}function Te(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var De={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function X(e){var g,f,m,y,S,v;if(typeof window=="undefined")return De;let t=(g=e==null?void 0:e.cookieName)!=null?g:ye,i=((f=e==null?void 0:e.cookieTTLDays)!=null?f:365)*24*60*60,o=(v=(S=(y=(m=ve(t))!=null?m:Ee(T))!=null?y:_e(T))!=null?S:e==null?void 0:e.ssrSessionId)!=null?v:Se();we(t,o,i);let c=xe(T,o),a=ke(t),r=c?!1:be(T,o),s=!c&&!a&&!r;return{getSessionId:()=>o,isEphemeral:()=>s,destroy:()=>{o=null,Te(t),Ce(T),Ie(T)}}}var Ae={push:()=>{},flush:()=>{},destroy:()=>{}};function Oe(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let i=JSON.parse(n);return Array.isArray(i)?(localStorage.removeItem(t),i.slice(-e)):[]}catch(n){return[]}}function J(e,t,n){try{let o=[...(()=>{try{let c=localStorage.getItem(n);if(!c)return[];let a=JSON.parse(c);return Array.isArray(a)?a:[]}catch(c){return[]}})(),...e].slice(-t);localStorage.setItem(n,JSON.stringify(o))}catch(i){}}function Z(e){var k,b,A;if(typeof window=="undefined")return Ae;let t=(k=e.flushIntervalMs)!=null?k:5e3,n=(b=e.maxBatchSize)!=null?b:20,i=(A=e.maxRetrySize)!=null?A:100,o=e.ingestUrl,c=e.apiKey,a=`_snt_retry_${c.slice(0,12)}`,r=[],s=new Set,g=[],f=l=>{for(let p of l)m.delete(p),!s.has(p)&&(s.add(p),g.push(p));for(;g.length>500;){let p=g.shift();p&&s.delete(p)}},m=new Set,y=l=>{s.has(l.id)||m.has(l.id)||(m.add(l.id),r.push(l))},S=Oe(i,a);for(let l of S)y(l);let v=0,x=0,K=l=>{if(l.length===0)return;let p=JSON.stringify(l),w=l.map(I=>I.id),E;try{E=fetch(o,{method:"POST",keepalive:!0,body:p,headers:{"Content-Type":"application/json",Authorization:`Bearer ${c}`}})}catch(I){J(l,i,a);for(let z of w)m.delete(z);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6));return}let O=I=>{if(I.ok||I.status>=400&&I.status<500&&I.status!==429){f(w),x=0,v=0;return}J(l,i,a);for(let z of w)m.delete(z);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6))};E instanceof Promise?E.then(O).catch(()=>{J(l,i,a);for(let I of w)m.delete(I);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6))}):O(E)},D=typeof TextEncoder!="undefined"?new TextEncoder:null,W=l=>D?D.encode(l).length:l.length,B=l=>{let p=[],w=2;for(let E of l){let O=W(JSON.stringify(E))+1;if(p.length>0&&w+O>57344||p.length>=n)break;p.push(E),w+=O}return p},_=()=>{try{if(Date.now()<v)return;for(;r.length>0;){let l=r.filter(w=>!s.has(w.id));if(r.length=0,l.length===0)break;let p=B(l);if(p.length===0)break;p.length<l.length&&r.push(...l.slice(p.length)),K(p)}}catch(l){}},u=!0,d=null;d=setInterval(()=>{u&&_()},t);let h=()=>{document.visibilityState==="hidden"&&_()},C=()=>{_()};return document.addEventListener("visibilitychange",h),window.addEventListener("beforeunload",C),{push(l){y(l),r.length>=n&&_()},flush:_,destroy(){u=!1,d!==null&&(clearInterval(d),d=null),document.removeEventListener("visibilitychange",h),window.removeEventListener("beforeunload",C),_()}}}var H="_snt_asgn_";function F(e,t){return`${e}:${t}`}function Re(e,t){return`${H}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function ee(e){let t=e.slice(H.length),n=t.indexOf(":");if(n<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,n)),segment:decodeURIComponent(t.slice(n+1))}}catch(i){return null}}function j(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(H)&&e.push(n)}return e}catch(e){return[]}}function te(e=18e5){let t=new Map,n=o=>o.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let o of j())try{let c=localStorage.getItem(o);if(!c)continue;let a=JSON.parse(c);if(n(a)){localStorage.removeItem(o);continue}let r=ee(o);if(!r)continue;t.set(F(r.componentId,r.segment),a)}catch(c){}})(),{get(o,c){let a=t.get(F(o,c));return a?n(a)?(t.delete(F(o,c)),null):a:null},set(o,c,a){let r=F(o,c);t.set(r,a);try{localStorage.setItem(Re(o,c),JSON.stringify(a))}catch(s){}},invalidate(o){let c=`${o}:`;for(let a of[...t.keys()])a.startsWith(c)&&t.delete(a);for(let a of j()){let r=ee(a);if((r==null?void 0:r.componentId)===o)try{localStorage.removeItem(a)}catch(s){}}},clear(){t.clear();for(let o of j())try{localStorage.removeItem(o)}catch(c){}}}}function U(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 L(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(o){}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 M(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function P(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function ne(e){let t=Ue("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Ue(e,t){var c,a,r,s,g,f,m;let n=(a=(c=t==null?void 0:t.userAgent)==null?void 0:c.trim())!=null?a:"",i=(s=(r=t==null?void 0:t.referer)==null?void 0:r.trim())!=null?s:"",o=(g=t==null?void 0:t.now)!=null?g:new Date;return{sessionId:e,ephemeral:!1,utmParams:(f=t==null?void 0:t.utmParams)!=null?f:{},deviceClass:n?U(n):"desktop",trafficSource:i?L(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:M(i),timeOfDay:P(o),dayOfWeek:(m=["sun","mon","tue","wed","thu","fri","sat"][o.getDay()])!=null?m:"sun"}}function re(e,t,n){var o;let i=[];{let r=!1,s=[],g=()=>{if(r)return;let f=Date.now();for(s.push(f);s.length>0&&f-s[0]>500;)s.shift();s.length>=3&&(r=!0,e("rage_click"))};t.addEventListener("click",g),i.push(()=>t.removeEventListener("click",g))}{let c=!1,a=r=>{if(c||!(r.target instanceof Node)||!t.contains(r.target)&&t!==r.target)return;c=!0;let s=typeof window!="undefined"?window.getSelection():null,g=s?s.toString().length:0;e("text_copy",{selectionLength:g})};document.addEventListener("copy",a),i.push(()=>document.removeEventListener("copy",a))}{let c=!1,a=!1,r=null,s=()=>{r!==null&&(clearTimeout(r),r=null)},g=()=>{c||!a||(s(),r=setTimeout(()=>{!c&&a&&(c=!0,e("scroll_hesitation"))},3e3))},f=()=>{s(),g()},m=S=>{for(let v of S)a=v.intersectionRatio>.3,a?g():s()};typeof process!="undefined"&&((o=process.env)==null?void 0:o.NODE_ENV)!=="production"&&(window.__lastIOCallback=m);let y=new IntersectionObserver(m,{threshold:[.3]});y.observe(t),window.addEventListener("scroll",f,{passive:!0}),i.push(()=>{y.disconnect(),window.removeEventListener("scroll",f),s()})}{let c=!1,a=n!=null?n:Date.now(),r=()=>{if(c||document.visibilityState!=="hidden")return;let s=Date.now()-a;s<15e3&&(c=!0,e("tab_loss",{timeOnPage:s}))};document.addEventListener("visibilitychange",r),i.push(()=>document.removeEventListener("visibilitychange",r))}return()=>{for(let c of i)c()}}var se="https://api.sentient-ui.com/v1/events",$=new Map,oe=null;function ie(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var N={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Le(){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 ae(e){return e.replace(/\/events\/?$/,"")}function Me(e){if(typeof window=="undefined")return;let t=e!=null?e:oe;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=$.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:i,upgrade:o}=n;if(!o)return;let c=ce(Q(R({},i),{consent:!0}));o(c),$.set(t,{config:Q(R({},i),{consent:!0}),upgrade:null})}function Pe(e){var a;let t=ae((a=e.ingestUrl)!=null?a:se),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(r,s,g){try{let f=new URLSearchParams({componentId:r});for(let S of s!=null?s:[])f.append("variantIds[]",S);let m=await fetch(`${t}/winner?${f.toString()}`,{headers:n});return m.ok?{variantId:(await m.json()).variantId,assignmentTtlMs:0}:s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}catch(f){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},o={track:r=>i.track(r),goal:(r,s,g,f)=>i.goal(r,s,g,f),identify:r=>i.identify(r),getAssignment:(r,s)=>i.getAssignment(r,s),assign:(r,s,g,f)=>i.assign(r,s,g,f),fetchWeights:()=>i.fetchWeights(),getGraph:()=>i.getGraph(),destroy:()=>i.destroy()};function c(r){i=r}return{proxy:o,setInner:c}}function ce(e){var K,D,W,B,_;if(typeof window=="undefined")return N;if(oe=e.apiKey,e.consent===!1){if(e.preConsentBehavior==="statistical_winner"){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;let{proxy:u,setInner:d}=Pe(e);return $.set(e.apiKey,{config:e,upgrade:d}),u}return $.set(e.apiKey,{config:e,upgrade:null}),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=(K=e.ingestUrl)!=null?K:se,n=Date.now(),i=X({ssrSessionId:e.ssrSessionId}),o=te(),c=Z({ingestUrl:t,apiKey:e.apiKey}),a=ae(t),r={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},s=U((D=navigator.userAgent)!=null?D:""),g=typeof window!="undefined"?window.location.origin:void 0,f=L((W=document.referrer)!=null?W:"",g),m=(B=e.sessionSegment)!=null?B:`${s}:${f}`,y=new Map;if(e.initialAssignments)for(let[u,d]of Object.entries(e.initialAssignments))o.set(u,m,{variantId:d,assignedAt:Date.now(),segment:m,confidence:1});let S=Promise.resolve(),v=i.getSessionId();if(v){let u=M((_=document.referrer)!=null?_:""),d=R({sessionId:v,deviceClass:s,trafficSource:f,referrerDomain:u,utmParams:Le(),timeOfDay:P(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:i.isEphemeral()},e.userId?{userId:e.userId}:{});try{S=fetch(`${a}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(d),headers:r}).then(h=>{h.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(h){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:c});let x={goal(u,d={},h=1,C=0){let k=i.getSessionId();if(!k)return;let b=ie();S.then(()=>{fetch(`${a}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:k,name:u,metadata:d,weight:h,stepIndex:C,goalId:b}),headers:r}).catch(()=>{})})},identify(u){let d=i.getSessionId();d&&S.then(()=>{fetch(`${a}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:d,userId:u,ephemeral:i.isEphemeral()}),headers:r}).catch(()=>{})})},track(u){let d=i.getSessionId();if(!d)return;let h=Q(R({},u),{id:ie(),sessionId:d,timestamp:Date.now(),timeInSession:Date.now()-n});c.push(h),e.debug&&console.log("[sentient] track",h)},getAssignment(u,d){return o.get(u,d)},async assign(u,d,h,C){let k=i.getSessionId();if(!k)return null;let b=o.get(u,m);if(b&&(d!=null&&d.length||b.content!==void 0))return{variantId:b.variantId,assignmentTtlMs:0,content:b.content};let A=y.get(u);if(A)return A;let l=(async()=>{await S;try{let p={sessionId:k,componentId:u,variantIds:d};C!==void 0?p.agentDataByVariant=C:h!==void 0&&(p.agentData=h);let w=await fetch(`${a}/assign`,{method:"POST",body:JSON.stringify(p),headers:r});if(!w.ok)return null;let E=await w.json();return o.set(u,m,{variantId:E.variantId,assignedAt:Date.now(),segment:m,confidence:1,content:E.content}),E}catch(p){return null}finally{y.delete(u)}})();return y.set(u,l),l},async fetchWeights(){var u;try{let d=await fetch(`${a}/weights`,{headers:r});return d.ok?(u=(await d.json()).components)!=null?u:[]:[]}catch(d){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){c.destroy(),i.destroy(),e.debug&&console.log("[sentient] destroyed")}};if($.set(e.apiKey,{config:e,upgrade:null}),e.debug){let u=window;u.__sentient&&(u.__sentient.client=x)}return x}0&&(module.exports={attachMicroSignalDetectors,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,referrerDomainFromReferer});
|
|
1
|
+
"use strict";var Q=Object.defineProperty,fe=Object.defineProperties,me=Object.getOwnPropertyDescriptor,pe=Object.getOwnPropertyDescriptors,he=Object.getOwnPropertyNames,ee=Object.getOwnPropertySymbols;var ne=Object.prototype.hasOwnProperty,ye=Object.prototype.propertyIsEnumerable;var te=(e,t,n)=>t in e?Q(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,D=(e,t)=>{for(var n in t||(t={}))ne.call(t,n)&&te(e,n,t[n]);if(ee)for(var n of ee(t))ye.call(t,n)&&te(e,n,t[n]);return e},F=(e,t)=>fe(e,pe(t));var Se=(e,t)=>{for(var n in t)Q(e,n,{get:t[n],enumerable:!0})},ve=(e,t,n,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of he(t))!ne.call(e,s)&&s!==n&&Q(e,s,{get:()=>t[s],enumerable:!(o=me(t,s))||o.enumerable});return e};var we=e=>ve(Q({},"__esModule",{value:!0}),e);var Be={};Se(Be,{agentUaList:()=>Y,attachMicroSignalDetectors:()=>ce,deriveSessionSegment:()=>ae,detectDeviceClass:()=>L,detectTimeOfDay:()=>P,detectTrafficSource:()=>M,grantConsent:()=>Ge,init:()=>ge,isDoNotTrackEnabled:()=>Z,matchedAgentToken:()=>q,referrerDomainFromReferer:()=>N,uaTokenMatch:()=>U});module.exports=we(Be);var xe="_snt_uid";var A="_snt_uid";function Ee(){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 be(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function ke(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 _e(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function Te(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 De(e){try{sessionStorage.removeItem(e)}catch(t){}}function Ae(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 Re(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Ue={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function re(e){var g,m,p,S,x,y;if(typeof window=="undefined")return Ue;let t=(g=e==null?void 0:e.cookieName)!=null?g:xe,o=((m=e==null?void 0:e.cookieTTLDays)!=null?m:365)*24*60*60,s=(y=(x=(S=(p=be(t))!=null?p:Ie(A))!=null?S:Te(A))!=null?x:e==null?void 0:e.ssrSessionId)!=null?y:Ee();ke(t,s,o);let a=_e(A,s),c=Ae(t),r=a?!1:Ce(A,s),i=!a&&!c&&!r;return{getSessionId:()=>s,isEphemeral:()=>i,destroy:()=>{s=null,Re(t),Oe(A),De(A)}}}var Le={push:()=>{},flush:()=>{},destroy:()=>{}};function Me(e,t){try{let n=localStorage.getItem(t);if(!n)return[];let o=JSON.parse(n);return Array.isArray(o)?(localStorage.removeItem(t),o.slice(-e)):[]}catch(n){return[]}}function J(e,t,n){try{let s=[...(()=>{try{let a=localStorage.getItem(n);if(!a)return[];let c=JSON.parse(a);return Array.isArray(c)?c:[]}catch(a){return[]}})(),...e].slice(-t);localStorage.setItem(n,JSON.stringify(s))}catch(o){}}function ie(e){var h,I,b;if(typeof window=="undefined")return Le;let t=(h=e.flushIntervalMs)!=null?h:5e3,n=(I=e.maxBatchSize)!=null?I:20,o=(b=e.maxRetrySize)!=null?b:100,s=e.ingestUrl,a=e.apiKey,c=`_snt_retry_${a.slice(0,12)}`,r=[],i=new Set,g=[],m=l=>{for(let f of l)p.delete(f),!i.has(f)&&(i.add(f),g.push(f));for(;g.length>500;){let f=g.shift();f&&i.delete(f)}},p=new Set,S=l=>{i.has(l.id)||p.has(l.id)||(p.add(l.id),r.push(l))},x=Me(o,c);for(let l of x)S(l);let y=0,k=0,K=l=>{if(l.length===0)return;let f=JSON.stringify(l),v=l.map(w=>w.id),E;try{E=fetch(s,{method:"POST",keepalive:!0,body:f,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(w){J(l,o,c);for(let j of v)p.delete(j);k++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6));return}let T=w=>{if(w.ok||w.status>=400&&w.status<500&&w.status!==429){m(v),k=0,y=0;return}J(l,o,c);for(let j of v)p.delete(j);k++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6))};E instanceof Promise?E.then(T).catch(()=>{J(l,o,c);for(let w of v)p.delete(w);k++,y=Date.now()+Math.min(6e4,1e3*2**Math.min(k,6))}):T(E)},O=typeof TextEncoder!="undefined"?new TextEncoder:null,B=l=>O?O.encode(l).length:l.length,W=l=>{let f=[],v=2;for(let E of l){let T=B(JSON.stringify(E))+1;if(f.length>0&&v+T>57344||f.length>=n)break;f.push(E),v+=T}return f},_=()=>{try{if(Date.now()<y)return;for(;r.length>0;){let l=r.filter(v=>!i.has(v.id));if(r.length=0,l.length===0)break;let f=W(l);if(f.length===0)break;f.length<l.length&&r.push(...l.slice(f.length)),K(f)}}catch(l){}},R=!0,C=null;C=setInterval(()=>{R&&_()},t);let d=()=>{document.visibilityState==="hidden"&&_()},u=()=>{_()};return document.addEventListener("visibilitychange",d),window.addEventListener("beforeunload",u),{push(l){S(l),r.length>=n&&_()},flush:_,destroy(){R=!1,C!==null&&(clearInterval(C),C=null),document.removeEventListener("visibilitychange",d),window.removeEventListener("beforeunload",u),_()}}}var V="_snt_asgn_";function z(e,t){return`${e}:${t}`}function Ne(e,t){return`${V}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function se(e){let t=e.slice(V.length),n=t.indexOf(":");if(n<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,n)),segment:decodeURIComponent(t.slice(n+1))}}catch(o){return null}}function H(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(V)&&e.push(n)}return e}catch(e){return[]}}function oe(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of H())try{let a=localStorage.getItem(s);if(!a)continue;let c=JSON.parse(a);if(n(c)){localStorage.removeItem(s);continue}let r=se(s);if(!r)continue;t.set(z(r.componentId,r.segment),c)}catch(a){}})(),{get(s,a){let c=t.get(z(s,a));return c?n(c)?(t.delete(z(s,a)),null):c:null},set(s,a,c){let r=z(s,a);t.set(r,c);try{localStorage.setItem(Ne(s,a),JSON.stringify(c))}catch(i){}},invalidate(s){let a=`${s}:`;for(let c of[...t.keys()])c.startsWith(a)&&t.delete(c);for(let c of H()){let r=se(c);if((r==null?void 0:r.componentId)===s)try{localStorage.removeItem(c)}catch(i){}}},clear(){t.clear();for(let s of H())try{localStorage.removeItem(s)}catch(a){}}}}var Y=["GPTBot","ChatGPT-User","OAI-SearchBot","ClaudeBot","Claude-User","Claude-SearchBot","PerplexityBot","Perplexity-User","Google-Extended","Applebot-Extended","Meta-ExternalAgent","Bytespider","CCBot","Amazonbot","cohere-ai","Diffbot"];function U(e){return q(e)!==null}function q(e){var n;if(!e)return null;let t=e.toLowerCase();return(n=Y.find(o=>t.includes(o.toLowerCase())))!=null?n:null}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 M(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 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 N(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function P(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function ae(e){let t=Pe("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Pe(e,t){var a,c,r,i,g,m,p;let n=(c=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?c:"",o=(i=(r=t==null?void 0:t.referer)==null?void 0:r.trim())!=null?i:"",s=(g=t==null?void 0:t.now)!=null?g:new Date;return{sessionId:e,ephemeral:!1,utmParams:(m=t==null?void 0:t.utmParams)!=null?m:{},deviceClass:n?L(n):"desktop",trafficSource:o?M(o,t==null?void 0:t.appOrigin):"direct",referrerDomain:N(o),timeOfDay:P(s),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?p:"sun",automation:(t==null?void 0:t.webdriver)===!0||U(n)}}function ce(e,t,n){var s;let o=[];{let r=!1,i=[],g=()=>{if(r)return;let m=Date.now();for(i.push(m);i.length>0&&m-i[0]>500;)i.shift();i.length>=3&&(r=!0,e("rage_click"))};t.addEventListener("click",g),o.push(()=>t.removeEventListener("click",g))}{let a=!1,c=r=>{if(a||!(r.target instanceof Node)||!t.contains(r.target)&&t!==r.target)return;a=!0;let i=typeof window!="undefined"?window.getSelection():null,g=i?i.toString().length:0;e("text_copy",{selectionLength:g})};document.addEventListener("copy",c),o.push(()=>document.removeEventListener("copy",c))}{let a=!1,c=!1,r=null,i=()=>{r!==null&&(clearTimeout(r),r=null)},g=()=>{a||!c||(i(),r=setTimeout(()=>{!a&&c&&(a=!0,e("scroll_hesitation"))},3e3))},m=()=>{i(),g()},p=x=>{for(let y of x)c=y.intersectionRatio>.3,c?g():i()};typeof process!="undefined"&&((s=process.env)==null?void 0:s.NODE_ENV)!=="production"&&(window.__lastIOCallback=p);let S=new IntersectionObserver(p,{threshold:[.3]});S.observe(t),window.addEventListener("scroll",m,{passive:!0}),o.push(()=>{S.disconnect(),window.removeEventListener("scroll",m),i()})}{let a=!1,c=n!=null?n:Date.now(),r=()=>{if(a||document.visibilityState!=="hidden")return;let i=Date.now()-c;i<15e3&&(a=!0,e("tab_loss",{timeOnPage:i}))};document.addEventListener("visibilitychange",r),o.push(()=>document.removeEventListener("visibilitychange",r))}return()=>{for(let a of o)a()}}var le="https://api.sentient-ui.com/v1/events",G=new Map,de=null;function X(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var $={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function $e(){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 ue(e){return e.replace(/\/events\/?$/,"")}function Z(){return[typeof navigator!="undefined"?navigator.doNotTrack:void 0,typeof window!="undefined"?window.doNotTrack:void 0,typeof navigator!="undefined"?navigator.msDoNotTrack:void 0].some(t=>t==="1"||t==="yes")}function Ge(e){if(typeof window=="undefined")return;let t=e!=null?e:de;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let n=G.get(t);if(!n){console.warn("[sentient] grantConsent() called before init()");return}let{config:o,upgrade:s}=n;if(!s||o.respectDoNotTrack!==!1&&Z())return;let a=ge(F(D({},o),{consent:!0}));s(a),G.set(t,{config:F(D({},o),{consent:!0}),upgrade:null})}function Ke(e){var c;let t=ue((c=e.ingestUrl)!=null?c:le),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},o={track:()=>{},goal:()=>{},componentGoal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(r,i,g){try{let m=new URLSearchParams({componentId:r});for(let x of i!=null?i:[])m.append("variantIds[]",x);let p=await fetch(`${t}/winner?${m.toString()}`,{headers:n});return p.ok?{variantId:(await p.json()).variantId,assignmentTtlMs:0}:i!=null&&i[0]?{variantId:i[0],assignmentTtlMs:0}:null}catch(m){return i!=null&&i[0]?{variantId:i[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},s={track:r=>o.track(r),goal:(r,i,g,m)=>o.goal(r,i,g,m),componentGoal:(r,i,g)=>o.componentGoal(r,i,g),identify:r=>o.identify(r),getAssignment:(r,i)=>o.getAssignment(r,i),assign:(r,i,g,m)=>o.assign(r,i,g,m),fetchWeights:()=>o.fetchWeights(),getGraph:()=>o.getGraph(),destroy:()=>o.destroy()};function a(r){o=r}return{proxy:s,setInner:a}}function ge(e){var O,B,W,_,R,C;if(typeof window=="undefined")return $;de=e.apiKey;let t=e.respectDoNotTrack!==!1&&Z();if(e.consent===!1||t){if(e.preConsentBehavior==="statistical_winner"){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."),$;let{proxy:d,setInner:u}=Ke(e);return G.set(e.apiKey,{config:e,upgrade:t?null:u}),d}return G.set(e.apiKey,{config:e,upgrade:null}),$}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 with an empty ingestUrl. SDK disabled."),$;let n=(O=e.ingestUrl)!=null?O:le,o=Date.now(),s=re({ssrSessionId:e.ssrSessionId}),a=oe(),c=ie({ingestUrl:n,apiKey:e.apiKey}),r=ue(n),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},g=L((B=navigator.userAgent)!=null?B:""),m=typeof window!="undefined"?window.location.origin:void 0,p=M((W=document.referrer)!=null?W:"",m),S=(_=e.sessionSegment)!=null?_:`${g}:${p}`,x=new Map;if(e.initialAssignments)for(let[d,u]of Object.entries(e.initialAssignments))a.set(d,S,{variantId:u,assignedAt:Date.now(),segment:S,confidence:1});let y=Promise.resolve(),k=s.getSessionId();if(k){let d=N((R=document.referrer)!=null?R:""),u=D(D({sessionId:k,deviceClass:g,trafficSource:p,referrerDomain:d,utmParams:$e(),timeOfDay:P(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:s.isEphemeral(),automation:typeof navigator!="undefined"&&navigator.webdriver===!0||U((C=navigator.userAgent)!=null?C:"")},e.userId?{userId:e.userId}:{}),e.country?{country:e.country}:{});try{y=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(u),headers:i}).then(h=>{h.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(h){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:c});let K={goal(d,u={},h=1,I=0){let b=s.getSessionId();if(!b)return;let l=X();y.then(()=>{fetch(`${r}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:b,name:d,metadata:u,weight:h,stepIndex:I,goalId:l}),headers:i}).catch(()=>{})})},componentGoal(d,u,h){var f,v;let I=s.getSessionId();if(!I)return;let b=a.get(d,S);if(!b){e.debug&&console.warn(`[sentient] componentGoal("${d}"): no assignment yet \u2014 render its <Adaptive> or call assign() before recording a goal.`);return}let l={id:X(),sessionId:I,projectId:e.apiKey,componentId:d,variantId:b.variantId,eventType:"goal_achieved",goalType:u,payload:D({reward:(f=h==null?void 0:h.reward)!=null?f:1},(v=h==null?void 0:h.metadata)!=null?v:{}),timestamp:Date.now(),timeInSession:Date.now()-o};e.debug&&console.log("[sentient] componentGoal",l),y.then(()=>c.push(l))},identify(d){let u=s.getSessionId();u&&y.then(()=>{fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:u,userId:d,ephemeral:s.isEphemeral()}),headers:i}).catch(()=>{})})},track(d){let u=s.getSessionId();if(!u)return;let h=F(D({},d),{id:X(),sessionId:u,timestamp:Date.now(),timeInSession:Date.now()-o});e.debug&&console.log("[sentient] track",h),y.then(()=>c.push(h))},getAssignment(d,u){return a.get(d,u)},async assign(d,u,h,I){let b=s.getSessionId();if(!b)return null;let l=a.get(d,S);if(l&&(u!=null&&u.length||l.content!==void 0))return{variantId:l.variantId,assignmentTtlMs:0,content:l.content};let f=x.get(d);if(f)return f;let v=(async()=>{await y;try{let E={sessionId:b,componentId:d,variantIds:u};I!==void 0?E.agentDataByVariant=I:h!==void 0&&(E.agentData=h);let T=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify(E),headers:i});if(!T.ok)return null;let w=await T.json();return a.set(d,S,{variantId:w.variantId,assignedAt:Date.now(),segment:S,confidence:1,content:w.content}),w}catch(E){return null}finally{x.delete(d)}})();return x.set(d,v),v},async fetchWeights(){var d;try{let u=await fetch(`${r}/weights`,{headers:i});return u.ok?(d=(await u.json()).components)!=null?d:[]:[]}catch(u){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){c.destroy(),s.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(G.set(e.apiKey,{config:e,upgrade:null}),e.debug){let d=window;d.__sentient&&(d.__sentient.client=K)}return K}0&&(module.exports={agentUaList,attachMicroSignalDetectors,deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,isDoNotTrackEnabled,matchedAgentToken,referrerDomainFromReferer,uaTokenMatch});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as i,b as j,c as k,d as l}from"./chunk-6PD6FNO7.mjs";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-CFXMEZCZ.mjs";export{a as agentUaList,i as attachMicroSignalDetectors,h as deriveSessionSegment,d as detectDeviceClass,g as detectTimeOfDay,e as detectTrafficSource,k as grantConsent,l as init,j as isDoNotTrackEnabled,c as matchedAgentToken,f as referrerDomainFromReferer,b as uaTokenMatch};
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Session metadata helpers (browser + Node). No DOM APIs. */
|
|
2
|
+
/**
|
|
3
|
+
* Known AI-agent / crawler user-agent tokens. Matched case-insensitively as
|
|
4
|
+
* substrings. This is maintained data — bot lists move monthly. Used both to
|
|
5
|
+
* flag automation on sessions (agentic browsers that leak a token) and by the
|
|
6
|
+
* server middleware / agent-feed route to identify crawler HTTP reads.
|
|
7
|
+
*/
|
|
8
|
+
declare const agentUaList: readonly string[];
|
|
9
|
+
/** True when the user-agent contains a known AI-agent / crawler token. */
|
|
10
|
+
declare function uaTokenMatch(userAgent: string): boolean;
|
|
11
|
+
/** The first known agent token found in the user-agent, or null. */
|
|
12
|
+
declare function matchedAgentToken(userAgent: string): string | null;
|
|
13
|
+
declare function detectDeviceClass(userAgent: string): string;
|
|
14
|
+
declare function detectTrafficSource(referrer: string, appOrigin?: string): string;
|
|
15
|
+
declare function referrerDomainFromReferer(referrer: string): string | null;
|
|
16
|
+
declare function detectTimeOfDay(d: Date): string;
|
|
17
|
+
type SessionUpsertPayload = {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
ephemeral: boolean;
|
|
20
|
+
utmParams: Record<string, string>;
|
|
21
|
+
deviceClass: string;
|
|
22
|
+
trafficSource: string;
|
|
23
|
+
referrerDomain: string | null;
|
|
24
|
+
timeOfDay: string;
|
|
25
|
+
dayOfWeek: string;
|
|
26
|
+
/**
|
|
27
|
+
* True when this session is likely driven by automation — either
|
|
28
|
+
* `navigator.webdriver` was set, or the user-agent carried a known agent
|
|
29
|
+
* token. Probabilistic: a flag for metrics + bandit exclusion, never a gate.
|
|
30
|
+
*/
|
|
31
|
+
automation: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** Bandit segment key: `<device_class>:<traffic_source>`. */
|
|
34
|
+
declare function deriveSessionSegment(opts?: {
|
|
35
|
+
userAgent?: string;
|
|
36
|
+
referer?: string;
|
|
37
|
+
appOrigin?: string;
|
|
38
|
+
}): string;
|
|
39
|
+
/**
|
|
40
|
+
* Builds a session upsert body aligned with the browser SDK so SSR assign uses
|
|
41
|
+
* the same segment key (`device:source`) as the client after hydration.
|
|
42
|
+
*/
|
|
43
|
+
declare function buildSessionUpsertPayload(sessionId: string, opts?: {
|
|
44
|
+
userAgent?: string;
|
|
45
|
+
referer?: string;
|
|
46
|
+
appOrigin?: string;
|
|
47
|
+
utmParams?: Record<string, string>;
|
|
48
|
+
now?: Date;
|
|
49
|
+
/** `navigator.webdriver` value from the browser, when available. */
|
|
50
|
+
webdriver?: boolean;
|
|
51
|
+
}): SessionUpsertPayload;
|
|
52
|
+
|
|
53
|
+
export { type SessionUpsertPayload as S, agentUaList as a, buildSessionUpsertPayload as b, detectDeviceClass as c, deriveSessionSegment as d, detectTimeOfDay as e, detectTrafficSource as f, matchedAgentToken as m, referrerDomainFromReferer as r, uaTokenMatch as u };
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Session metadata helpers (browser + Node). No DOM APIs. */
|
|
2
|
+
/**
|
|
3
|
+
* Known AI-agent / crawler user-agent tokens. Matched case-insensitively as
|
|
4
|
+
* substrings. This is maintained data — bot lists move monthly. Used both to
|
|
5
|
+
* flag automation on sessions (agentic browsers that leak a token) and by the
|
|
6
|
+
* server middleware / agent-feed route to identify crawler HTTP reads.
|
|
7
|
+
*/
|
|
8
|
+
declare const agentUaList: readonly string[];
|
|
9
|
+
/** True when the user-agent contains a known AI-agent / crawler token. */
|
|
10
|
+
declare function uaTokenMatch(userAgent: string): boolean;
|
|
11
|
+
/** The first known agent token found in the user-agent, or null. */
|
|
12
|
+
declare function matchedAgentToken(userAgent: string): string | null;
|
|
13
|
+
declare function detectDeviceClass(userAgent: string): string;
|
|
14
|
+
declare function detectTrafficSource(referrer: string, appOrigin?: string): string;
|
|
15
|
+
declare function referrerDomainFromReferer(referrer: string): string | null;
|
|
16
|
+
declare function detectTimeOfDay(d: Date): string;
|
|
17
|
+
type SessionUpsertPayload = {
|
|
18
|
+
sessionId: string;
|
|
19
|
+
ephemeral: boolean;
|
|
20
|
+
utmParams: Record<string, string>;
|
|
21
|
+
deviceClass: string;
|
|
22
|
+
trafficSource: string;
|
|
23
|
+
referrerDomain: string | null;
|
|
24
|
+
timeOfDay: string;
|
|
25
|
+
dayOfWeek: string;
|
|
26
|
+
/**
|
|
27
|
+
* True when this session is likely driven by automation — either
|
|
28
|
+
* `navigator.webdriver` was set, or the user-agent carried a known agent
|
|
29
|
+
* token. Probabilistic: a flag for metrics + bandit exclusion, never a gate.
|
|
30
|
+
*/
|
|
31
|
+
automation: boolean;
|
|
32
|
+
};
|
|
33
|
+
/** Bandit segment key: `<device_class>:<traffic_source>`. */
|
|
34
|
+
declare function deriveSessionSegment(opts?: {
|
|
35
|
+
userAgent?: string;
|
|
36
|
+
referer?: string;
|
|
37
|
+
appOrigin?: string;
|
|
38
|
+
}): string;
|
|
39
|
+
/**
|
|
40
|
+
* Builds a session upsert body aligned with the browser SDK so SSR assign uses
|
|
41
|
+
* the same segment key (`device:source`) as the client after hydration.
|
|
42
|
+
*/
|
|
43
|
+
declare function buildSessionUpsertPayload(sessionId: string, opts?: {
|
|
44
|
+
userAgent?: string;
|
|
45
|
+
referer?: string;
|
|
46
|
+
appOrigin?: string;
|
|
47
|
+
utmParams?: Record<string, string>;
|
|
48
|
+
now?: Date;
|
|
49
|
+
/** `navigator.webdriver` value from the browser, when available. */
|
|
50
|
+
webdriver?: boolean;
|
|
51
|
+
}): SessionUpsertPayload;
|
|
52
|
+
|
|
53
|
+
export { type SessionUpsertPayload as S, agentUaList as a, buildSessionUpsertPayload as b, detectDeviceClass as c, deriveSessionSegment as d, detectTimeOfDay as e, detectTrafficSource as f, matchedAgentToken as m, referrerDomainFromReferer as r, uaTokenMatch as u };
|
package/package.json
CHANGED
package/dist/chunk-NXCIN4O2.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{a as R,b as K,c as B,d as G,e as Q,f as F}from"./chunk-QCYVBCUV.mjs";var ne="_snt_uid";var T="_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 ie(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function re(e,t,a){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${a}; SameSite=strict; path=/`}catch(r){}}function oe(e){try{return localStorage.getItem(e)}catch(t){return null}}function ae(e,t){try{return localStorage.setItem(e,t),!0}catch(a){return!1}}function ce(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function le(e,t){try{return sessionStorage.setItem(e,t),!0}catch(a){return!1}}function de(e){try{sessionStorage.removeItem(e)}catch(t){}}function ue(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 ge(e){try{localStorage.removeItem(e)}catch(t){}}function pe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var fe={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function H(e){var p,f,m,y,S,v;if(typeof window=="undefined")return fe;let t=(p=e==null?void 0:e.cookieName)!=null?p:ne,r=((f=e==null?void 0:e.cookieTTLDays)!=null?f:365)*24*60*60,c=(v=(S=(y=(m=ie(t))!=null?m:oe(T))!=null?y:ce(T))!=null?S:e==null?void 0:e.ssrSessionId)!=null?v:se();re(t,c,r);let o=ae(T,c),i=ue(t),n=o?!1:le(T,c),s=!o&&!i&&!n;return{getSessionId:()=>c,isEphemeral:()=>s,destroy:()=>{c=null,pe(t),ge(T),de(T)}}}var me={push:()=>{},flush:()=>{},destroy:()=>{}};function he(e,t){try{let a=localStorage.getItem(t);if(!a)return[];let r=JSON.parse(a);return Array.isArray(r)?(localStorage.removeItem(t),r.slice(-e)):[]}catch(a){return[]}}function z(e,t,a){try{let c=[...(()=>{try{let o=localStorage.getItem(a);if(!o)return[];let i=JSON.parse(o);return Array.isArray(i)?i:[]}catch(o){return[]}})(),...e].slice(-t);localStorage.setItem(a,JSON.stringify(c))}catch(r){}}function V(e){var k,_,D;if(typeof window=="undefined")return me;let t=(k=e.flushIntervalMs)!=null?k:5e3,a=(_=e.maxBatchSize)!=null?_:20,r=(D=e.maxRetrySize)!=null?D:100,c=e.ingestUrl,o=e.apiKey,i=`_snt_retry_${o.slice(0,12)}`,n=[],s=new Set,p=[],f=l=>{for(let g of l)m.delete(g),!s.has(g)&&(s.add(g),p.push(g));for(;p.length>500;){let g=p.shift();g&&s.delete(g)}},m=new Set,y=l=>{s.has(l.id)||m.has(l.id)||(m.add(l.id),n.push(l))},S=he(r,i);for(let l of S)y(l);let v=0,x=0,L=l=>{if(l.length===0)return;let g=JSON.stringify(l),w=l.map(b=>b.id),E;try{E=fetch(c,{method:"POST",keepalive:!0,body:g,headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`}})}catch(b){z(l,r,i);for(let W of w)m.delete(W);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6));return}let O=b=>{if(b.ok||b.status>=400&&b.status<500&&b.status!==429){f(w),x=0,v=0;return}z(l,r,i);for(let W of w)m.delete(W);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6))};E instanceof Promise?E.then(O).catch(()=>{z(l,r,i);for(let b of w)m.delete(b);x++,v=Date.now()+Math.min(6e4,1e3*2**Math.min(x,6))}):O(E)},A=typeof TextEncoder!="undefined"?new TextEncoder:null,N=l=>A?A.encode(l).length:l.length,$=l=>{let g=[],w=2;for(let E of l){let O=N(JSON.stringify(E))+1;if(g.length>0&&w+O>57344||g.length>=a)break;g.push(E),w+=O}return g},I=()=>{try{if(Date.now()<v)return;for(;n.length>0;){let l=n.filter(w=>!s.has(w.id));if(n.length=0,l.length===0)break;let g=$(l);if(g.length===0)break;g.length<l.length&&n.push(...l.slice(g.length)),L(g)}}catch(l){}},d=!0,u=null;u=setInterval(()=>{d&&I()},t);let h=()=>{document.visibilityState==="hidden"&&I()},C=()=>{I()};return document.addEventListener("visibilitychange",h),window.addEventListener("beforeunload",C),{push(l){y(l),n.length>=a&&I()},flush:I,destroy(){d=!1,u!==null&&(clearInterval(u),u=null),document.removeEventListener("visibilitychange",h),window.removeEventListener("beforeunload",C),I()}}}var j="_snt_asgn_";function P(e,t){return`${e}:${t}`}function ye(e,t){return`${j}${encodeURIComponent(e)}:${encodeURIComponent(t)}`}function Y(e){let t=e.slice(j.length),a=t.indexOf(":");if(a<0)return null;try{return{componentId:decodeURIComponent(t.slice(0,a)),segment:decodeURIComponent(t.slice(a+1))}}catch(r){return null}}function J(){try{let e=[];for(let t=0;t<localStorage.length;t++){let a=localStorage.key(t);a!=null&&a.startsWith(j)&&e.push(a)}return e}catch(e){return[]}}function q(e=18e5){let t=new Map,a=c=>c.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let c of J())try{let o=localStorage.getItem(c);if(!o)continue;let i=JSON.parse(o);if(a(i)){localStorage.removeItem(c);continue}let n=Y(c);if(!n)continue;t.set(P(n.componentId,n.segment),i)}catch(o){}})(),{get(c,o){let i=t.get(P(c,o));return i?a(i)?(t.delete(P(c,o)),null):i:null},set(c,o,i){let n=P(c,o);t.set(n,i);try{localStorage.setItem(ye(c,o),JSON.stringify(i))}catch(s){}},invalidate(c){let o=`${c}:`;for(let i of[...t.keys()])i.startsWith(o)&&t.delete(i);for(let i of J()){let n=Y(i);if((n==null?void 0:n.componentId)===c)try{localStorage.removeItem(i)}catch(s){}}},clear(){t.clear();for(let c of J())try{localStorage.removeItem(c)}catch(o){}}}}function Se(e,t,a){var c;let r=[];{let n=!1,s=[],p=()=>{if(n)return;let f=Date.now();for(s.push(f);s.length>0&&f-s[0]>500;)s.shift();s.length>=3&&(n=!0,e("rage_click"))};t.addEventListener("click",p),r.push(()=>t.removeEventListener("click",p))}{let o=!1,i=n=>{if(o||!(n.target instanceof Node)||!t.contains(n.target)&&t!==n.target)return;o=!0;let s=typeof window!="undefined"?window.getSelection():null,p=s?s.toString().length:0;e("text_copy",{selectionLength:p})};document.addEventListener("copy",i),r.push(()=>document.removeEventListener("copy",i))}{let o=!1,i=!1,n=null,s=()=>{n!==null&&(clearTimeout(n),n=null)},p=()=>{o||!i||(s(),n=setTimeout(()=>{!o&&i&&(o=!0,e("scroll_hesitation"))},3e3))},f=()=>{s(),p()},m=S=>{for(let v of S)i=v.intersectionRatio>.3,i?p():s()};typeof process!="undefined"&&((c=process.env)==null?void 0:c.NODE_ENV)!=="production"&&(window.__lastIOCallback=m);let y=new IntersectionObserver(m,{threshold:[.3]});y.observe(t),window.addEventListener("scroll",f,{passive:!0}),r.push(()=>{y.disconnect(),window.removeEventListener("scroll",f),s()})}{let o=!1,i=a!=null?a:Date.now(),n=()=>{if(o||document.visibilityState!=="hidden")return;let s=Date.now()-i;s<15e3&&(o=!0,e("tab_loss",{timeOnPage:s}))};document.addEventListener("visibilitychange",n),r.push(()=>document.removeEventListener("visibilitychange",n))}return()=>{for(let o of r)o()}}var Z="https://api.sentient-ui.com/v1/events",M=new Map,ee=null;function X(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}var U={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),fetchWeights:()=>Promise.resolve([]),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function ve(){try{let e={},t=new URLSearchParams(window.location.search);for(let[a,r]of t)a.startsWith("utm_")&&(e[a]=r);return e}catch(e){return{}}}function te(e){return e.replace(/\/events\/?$/,"")}function Oe(e){if(typeof window=="undefined")return;let t=e!=null?e:ee;if(!t){console.warn("[sentient] grantConsent() called before init()");return}let a=M.get(t);if(!a){console.warn("[sentient] grantConsent() called before init()");return}let{config:r,upgrade:c}=a;if(!c)return;let o=Ee(K(R({},r),{consent:!0}));c(o),M.set(t,{config:K(R({},r),{consent:!0}),upgrade:null})}function we(e){var i;let t=te((i=e.ingestUrl)!=null?i:Z),a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},r={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,fetchWeights:()=>Promise.resolve([]),async assign(n,s,p){try{let f=new URLSearchParams({componentId:n});for(let S of s!=null?s:[])f.append("variantIds[]",S);let m=await fetch(`${t}/winner?${f.toString()}`,{headers:a});return m.ok?{variantId:(await m.json()).variantId,assignmentTtlMs:0}:s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}catch(f){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}},c={track:n=>r.track(n),goal:(n,s,p,f)=>r.goal(n,s,p,f),identify:n=>r.identify(n),getAssignment:(n,s)=>r.getAssignment(n,s),assign:(n,s,p,f)=>r.assign(n,s,p,f),fetchWeights:()=>r.fetchWeights(),getGraph:()=>r.getGraph(),destroy:()=>r.destroy()};function o(n){r=n}return{proxy:c,setInner:o}}function Ee(e){var L,A,N,$,I;if(typeof window=="undefined")return U;if(ee=e.apiKey,e.consent===!1){if(e.preConsentBehavior==="statistical_winner"){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."),U;let{proxy:d,setInner:u}=we(e);return M.set(e.apiKey,{config:e,upgrade:u}),d}return M.set(e.apiKey,{config:e,upgrade:null}),U}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."),U;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),U;let t=(L=e.ingestUrl)!=null?L:Z,a=Date.now(),r=H({ssrSessionId:e.ssrSessionId}),c=q(),o=V({ingestUrl:t,apiKey:e.apiKey}),i=te(t),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},s=B((A=navigator.userAgent)!=null?A:""),p=typeof window!="undefined"?window.location.origin:void 0,f=G((N=document.referrer)!=null?N:"",p),m=($=e.sessionSegment)!=null?$:`${s}:${f}`,y=new Map;if(e.initialAssignments)for(let[d,u]of Object.entries(e.initialAssignments))c.set(d,m,{variantId:u,assignedAt:Date.now(),segment:m,confidence:1});let S=Promise.resolve(),v=r.getSessionId();if(v){let d=Q((I=document.referrer)!=null?I:""),u=R({sessionId:v,deviceClass:s,trafficSource:f,referrerDomain:d,utmParams:ve(),timeOfDay:F(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:r.isEphemeral()},e.userId?{userId:e.userId}:{});try{S=fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(u),headers:n}).then(h=>{h.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentient-ui.com/pricing")}).catch(()=>{})}catch(h){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let x={goal(d,u={},h=1,C=0){let k=r.getSessionId();if(!k)return;let _=X();S.then(()=>{fetch(`${i}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:k,name:d,metadata:u,weight:h,stepIndex:C,goalId:_}),headers:n}).catch(()=>{})})},identify(d){let u=r.getSessionId();u&&S.then(()=>{fetch(`${i}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:u,userId:d,ephemeral:r.isEphemeral()}),headers:n}).catch(()=>{})})},track(d){let u=r.getSessionId();if(!u)return;let h=K(R({},d),{id:X(),sessionId:u,timestamp:Date.now(),timeInSession:Date.now()-a});o.push(h),e.debug&&console.log("[sentient] track",h)},getAssignment(d,u){return c.get(d,u)},async assign(d,u,h,C){let k=r.getSessionId();if(!k)return null;let _=c.get(d,m);if(_&&(u!=null&&u.length||_.content!==void 0))return{variantId:_.variantId,assignmentTtlMs:0,content:_.content};let D=y.get(d);if(D)return D;let l=(async()=>{await S;try{let g={sessionId:k,componentId:d,variantIds:u};C!==void 0?g.agentDataByVariant=C:h!==void 0&&(g.agentData=h);let w=await fetch(`${i}/assign`,{method:"POST",body:JSON.stringify(g),headers:n});if(!w.ok)return null;let E=await w.json();return c.set(d,m,{variantId:E.variantId,assignedAt:Date.now(),segment:m,confidence:1,content:E.content}),E}catch(g){return null}finally{y.delete(d)}})();return y.set(d,l),l},async fetchWeights(){var d;try{let u=await fetch(`${i}/weights`,{headers:n});return u.ok?(d=(await u.json()).components)!=null?d:[]:[]}catch(u){return[]}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){o.destroy(),r.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(M.set(e.apiKey,{config:e,upgrade:null}),e.debug){let d=window;d.__sentient&&(d.__sentient.client=x)}return x}export{Se as a,Oe as b,Ee as c};
|
package/dist/chunk-QCYVBCUV.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var m=Object.defineProperty,h=Object.defineProperties;var y=Object.getOwnPropertyDescriptors;var d=Object.getOwnPropertySymbols;var b=Object.prototype.hasOwnProperty,k=Object.prototype.propertyIsEnumerable;var l=(r,e,t)=>e in r?m(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t,P=(r,e)=>{for(var t in e||(e={}))b.call(e,t)&&l(r,t,e[t]);if(d)for(var t of d(e))k.call(e,t)&&l(r,t,e[t]);return r},U=(r,e)=>h(r,y(e));function w(r){let e=r.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(e)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(e)?"mobile":"desktop"}function D(r,e){if(!r)return"direct";try{let t=new URL(r);if(e)try{if(new URL(e).host===t.host)return"direct"}catch(i){}let n=t.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(n)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(n)?"social":"referral"}catch(t){return"direct"}}function S(r){if(!r)return null;try{return new URL(r).hostname}catch(e){return null}}function x(r){let e=r.getHours();return e<6?"night":e<12?"morning":e<18?"afternoon":"evening"}function C(r){let e=O("__segment__",r);return`${e.deviceClass}:${e.trafficSource}`}function O(r,e){var s,a,o,c,u,f,g;let t=(a=(s=e==null?void 0:e.userAgent)==null?void 0:s.trim())!=null?a:"",n=(c=(o=e==null?void 0:e.referer)==null?void 0:o.trim())!=null?c:"",i=(u=e==null?void 0:e.now)!=null?u:new Date;return{sessionId:r,ephemeral:!1,utmParams:(f=e==null?void 0:e.utmParams)!=null?f:{},deviceClass:t?w(t):"desktop",trafficSource:n?D(n,e==null?void 0:e.appOrigin):"direct",referrerDomain:S(n),timeOfDay:x(i),dayOfWeek:(g=["sun","mon","tue","wed","thu","fri","sat"][i.getDay()])!=null?g:"sun"}}export{P as a,U as b,w as c,D as d,S as e,x as f,C as g,O as h};
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/** Session metadata helpers (browser + Node). No DOM APIs. */
|
|
2
|
-
declare function detectDeviceClass(userAgent: string): string;
|
|
3
|
-
declare function detectTrafficSource(referrer: string, appOrigin?: string): string;
|
|
4
|
-
declare function referrerDomainFromReferer(referrer: string): string | null;
|
|
5
|
-
declare function detectTimeOfDay(d: Date): string;
|
|
6
|
-
type SessionUpsertPayload = {
|
|
7
|
-
sessionId: string;
|
|
8
|
-
ephemeral: boolean;
|
|
9
|
-
utmParams: Record<string, string>;
|
|
10
|
-
deviceClass: string;
|
|
11
|
-
trafficSource: string;
|
|
12
|
-
referrerDomain: string | null;
|
|
13
|
-
timeOfDay: string;
|
|
14
|
-
dayOfWeek: string;
|
|
15
|
-
};
|
|
16
|
-
/** Bandit segment key: `<device_class>:<traffic_source>`. */
|
|
17
|
-
declare function deriveSessionSegment(opts?: {
|
|
18
|
-
userAgent?: string;
|
|
19
|
-
referer?: string;
|
|
20
|
-
appOrigin?: string;
|
|
21
|
-
}): string;
|
|
22
|
-
/**
|
|
23
|
-
* Builds a session upsert body aligned with the browser SDK so SSR assign uses
|
|
24
|
-
* the same segment key (`device:source`) as the client after hydration.
|
|
25
|
-
*/
|
|
26
|
-
declare function buildSessionUpsertPayload(sessionId: string, opts?: {
|
|
27
|
-
userAgent?: string;
|
|
28
|
-
referer?: string;
|
|
29
|
-
appOrigin?: string;
|
|
30
|
-
utmParams?: Record<string, string>;
|
|
31
|
-
now?: Date;
|
|
32
|
-
}): SessionUpsertPayload;
|
|
33
|
-
|
|
34
|
-
export { type SessionUpsertPayload as S, detectDeviceClass as a, buildSessionUpsertPayload as b, detectTimeOfDay as c, deriveSessionSegment as d, detectTrafficSource as e, referrerDomainFromReferer as r };
|
|
@@ -1,34 +0,0 @@
|
|
|
1
|
-
/** Session metadata helpers (browser + Node). No DOM APIs. */
|
|
2
|
-
declare function detectDeviceClass(userAgent: string): string;
|
|
3
|
-
declare function detectTrafficSource(referrer: string, appOrigin?: string): string;
|
|
4
|
-
declare function referrerDomainFromReferer(referrer: string): string | null;
|
|
5
|
-
declare function detectTimeOfDay(d: Date): string;
|
|
6
|
-
type SessionUpsertPayload = {
|
|
7
|
-
sessionId: string;
|
|
8
|
-
ephemeral: boolean;
|
|
9
|
-
utmParams: Record<string, string>;
|
|
10
|
-
deviceClass: string;
|
|
11
|
-
trafficSource: string;
|
|
12
|
-
referrerDomain: string | null;
|
|
13
|
-
timeOfDay: string;
|
|
14
|
-
dayOfWeek: string;
|
|
15
|
-
};
|
|
16
|
-
/** Bandit segment key: `<device_class>:<traffic_source>`. */
|
|
17
|
-
declare function deriveSessionSegment(opts?: {
|
|
18
|
-
userAgent?: string;
|
|
19
|
-
referer?: string;
|
|
20
|
-
appOrigin?: string;
|
|
21
|
-
}): string;
|
|
22
|
-
/**
|
|
23
|
-
* Builds a session upsert body aligned with the browser SDK so SSR assign uses
|
|
24
|
-
* the same segment key (`device:source`) as the client after hydration.
|
|
25
|
-
*/
|
|
26
|
-
declare function buildSessionUpsertPayload(sessionId: string, opts?: {
|
|
27
|
-
userAgent?: string;
|
|
28
|
-
referer?: string;
|
|
29
|
-
appOrigin?: string;
|
|
30
|
-
utmParams?: Record<string, string>;
|
|
31
|
-
now?: Date;
|
|
32
|
-
}): SessionUpsertPayload;
|
|
33
|
-
|
|
34
|
-
export { type SessionUpsertPayload as S, detectDeviceClass as a, buildSessionUpsertPayload as b, detectTimeOfDay as c, deriveSessionSegment as d, detectTrafficSource as e, referrerDomainFromReferer as r };
|