@sentientui/core 0.3.0 → 0.4.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 +97 -31
- package/dist/chunk-CJD3GMCD.mjs +1 -0
- package/dist/index-graph.js +1 -1
- package/dist/index-graph.mjs +1 -1
- package/dist/index.d.cts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
- package/dist/chunk-HWKW5O3R.mjs +0 -1
package/README.md
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
# @sentientui/core
|
|
2
2
|
|
|
3
|
-
Framework-agnostic JavaScript SDK for [SentientUI](https://
|
|
3
|
+
Framework-agnostic JavaScript SDK for [SentientUI](https://sentient-ui.com) — a Thompson Sampling bandit + persona/portrait engine that automatically surfaces the best-performing variant for each visitor. Learning runs on the SentientUI hosted API.
|
|
4
|
+
|
|
5
|
+
> Most users should install **`@sentientui/react`** instead — it bundles this package and adds the SSR-safe `<AdaptiveRoot>`, `<Adaptive>`, and hooks. Use `@sentientui/core` directly only if you are not building with React.
|
|
4
6
|
|
|
5
7
|
## Installation
|
|
6
8
|
|
|
@@ -14,69 +16,133 @@ npm install @sentientui/core
|
|
|
14
16
|
import { init } from '@sentientui/core';
|
|
15
17
|
|
|
16
18
|
const client = init({
|
|
17
|
-
apiKey: 'pk_your_key',
|
|
18
|
-
context: 'saas',
|
|
19
|
+
apiKey: 'pk_your_key', // from app.sentient-ui.com → Settings
|
|
20
|
+
context: 'saas', // 'landing' | 'ecommerce' | 'saas' | 'marketplace'
|
|
19
21
|
});
|
|
20
22
|
|
|
21
|
-
// Get a variant assignment for a component
|
|
22
|
-
const result = await client.assign('
|
|
23
|
-
console.log(result?.variantId);
|
|
23
|
+
// Get a variant assignment for a component (returns null during SSR)
|
|
24
|
+
const result = await client.assign('hero_headline', ['control', 'variant_b']);
|
|
25
|
+
console.log(result?.variantId); // e.g. 'variant_b'
|
|
26
|
+
console.log(result?.content); // managed text content if the variant is WYSIWYG-managed
|
|
27
|
+
|
|
28
|
+
// Fire a goal (reward) when the visitor converts
|
|
29
|
+
client.goal('trial_started', { plan: 'pro' });
|
|
24
30
|
|
|
25
|
-
//
|
|
31
|
+
// Or record a custom event
|
|
26
32
|
client.track({
|
|
27
|
-
|
|
28
|
-
componentId: 'hero-headline',
|
|
33
|
+
componentId: 'hero_headline',
|
|
29
34
|
variantId: result?.variantId ?? 'control',
|
|
30
35
|
eventType: 'click',
|
|
31
36
|
});
|
|
32
37
|
```
|
|
33
38
|
|
|
34
|
-
|
|
39
|
+
`init()` returns a no-op client during SSR (`typeof window === 'undefined'`), when `consent` is `false`, or when `apiKey` does not start with `pk_`. The hosted ingest URL (`https://sentient-api.fly.dev/v1/events`) is built in — no URL configuration required.
|
|
35
40
|
|
|
36
|
-
|
|
41
|
+
## API
|
|
37
42
|
|
|
38
|
-
|
|
43
|
+
### `init(config)` → `SentientClient`
|
|
39
44
|
|
|
40
45
|
| Option | Type | Description |
|
|
41
46
|
|--------|------|-------------|
|
|
42
|
-
| `apiKey` | `string` |
|
|
43
|
-
| `context` | `
|
|
44
|
-
| `
|
|
45
|
-
| `
|
|
46
|
-
| `
|
|
47
|
-
| `
|
|
47
|
+
| `apiKey` | `string` | Public API key (`pk_…`) from the SentientUI dashboard. |
|
|
48
|
+
| `context` | `'landing' \| 'ecommerce' \| 'saas' \| 'marketplace'` | Type of product. Used for segment weighting and analytics grouping. |
|
|
49
|
+
| `consent` | `boolean` *(default `true`)* | When `false`, returns a no-op client (no cookies, no events). |
|
|
50
|
+
| `initialAssignments` | `Record<string, string>` | SSR-preloaded assignments. Seeds the cache so `assign()` returns immediately for listed components. |
|
|
51
|
+
| `sessionSegment` | `string` | Segment from SSR (`device:source`). Must match the value used in `preloadAssignments`. |
|
|
52
|
+
| `userId` | `string` | Optional cross-session identity. Persists portraits across sessions for the same user. |
|
|
53
|
+
| `debug` | `boolean` | Logs events to the console and exposes `window.__sentient`. |
|
|
48
54
|
|
|
49
|
-
### `client.assign(componentId, variantIds?)`
|
|
55
|
+
### `client.assign(componentId, variantIds?)` → `Promise<AssignResult | null>`
|
|
50
56
|
|
|
51
|
-
|
|
57
|
+
Asks the hosted bandit for a variant. Cached locally per `(componentId, segment)` — repeat calls hit the cache. Returns `null` during SSR or when the session has no ID.
|
|
58
|
+
|
|
59
|
+
```ts
|
|
60
|
+
type AssignResult = {
|
|
61
|
+
variantId: string;
|
|
62
|
+
assignmentTtlMs: number;
|
|
63
|
+
content?: string; // populated when the variant is dashboard-managed (WYSIWYG)
|
|
64
|
+
};
|
|
65
|
+
```
|
|
52
66
|
|
|
53
67
|
### `client.track(event)`
|
|
54
68
|
|
|
55
|
-
Queues an event for ingest.
|
|
69
|
+
Queues an event for batched ingest. Events flush every 5 s and on `visibilitychange` / page unload (via `fetch` with `keepalive: true`).
|
|
70
|
+
|
|
71
|
+
### `client.goal(name, metadata?)`
|
|
72
|
+
|
|
73
|
+
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>`.
|
|
74
|
+
|
|
75
|
+
### `client.identify(userId)`
|
|
76
|
+
|
|
77
|
+
Attaches a stable user ID to the session. Portraits and cluster assignment carry forward across future sessions for the same `userId`.
|
|
56
78
|
|
|
57
79
|
### `client.getAssignment(componentId, segment)`
|
|
58
80
|
|
|
59
|
-
Synchronously returns the cached assignment
|
|
81
|
+
Synchronously returns the cached assignment, or `null` if not yet assigned. Use when you need a non-async lookup.
|
|
82
|
+
|
|
83
|
+
### `client.getGraph()`
|
|
84
|
+
|
|
85
|
+
Returns the current `GraphSnapshot` (page nodes captured by the optional graph scanner — see `@sentientui/core/graph`).
|
|
60
86
|
|
|
61
87
|
### `client.destroy()`
|
|
62
88
|
|
|
63
|
-
Flushes the event queue and clears
|
|
89
|
+
Flushes the event queue and clears session state. Call on page unload if you need a synchronous teardown (the SDK already handles `visibilitychange` automatically).
|
|
64
90
|
|
|
65
91
|
## SSR helpers
|
|
66
92
|
|
|
67
93
|
```ts
|
|
68
94
|
import { preloadAssignments, readSessionCookie } from '@sentientui/core';
|
|
69
95
|
|
|
70
|
-
// In your server loader / getServerSideProps / Server Component
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
96
|
+
// In your server loader / getServerSideProps / Server Component.
|
|
97
|
+
// `cookies` must expose `get(name)` — Next.js `req.cookies`, `headers().cookies()`, or any
|
|
98
|
+
// object with the same shape.
|
|
99
|
+
const sessionId = readSessionCookie(cookies) ?? crypto.randomUUID();
|
|
100
|
+
|
|
101
|
+
const initialAssignments = await preloadAssignments(
|
|
102
|
+
[
|
|
103
|
+
{ id: 'hero_headline', variantIds: ['control', 'variant_b'] },
|
|
104
|
+
{ id: 'pricing_cta', variantIds: ['monthly', 'annual_first'] },
|
|
105
|
+
],
|
|
106
|
+
sessionId,
|
|
107
|
+
{
|
|
108
|
+
apiKey: process.env.SENTIENT_API_KEY!,
|
|
109
|
+
baseUrl: 'https://sentient-api.fly.dev/v1',
|
|
110
|
+
origin: process.env.APP_ORIGIN, // must be in the project's allowed origins
|
|
111
|
+
userAgent, // from request headers, aligns segment with the client
|
|
112
|
+
referer,
|
|
113
|
+
},
|
|
114
|
+
);
|
|
77
115
|
```
|
|
78
116
|
|
|
79
|
-
Pass `initialAssignments` and `sessionSegment` to `init()` on the client to prevent hydration mismatches.
|
|
117
|
+
Pass `initialAssignments` and the same `sessionSegment` to `init()` on the client to prevent hydration mismatches.
|
|
118
|
+
|
|
119
|
+
For pages with a section layout, use `preloadDecisions` instead — same options, plus a `sections: string[]` request field. The return value carries both `assignments` and `layoutOrder`.
|
|
120
|
+
|
|
121
|
+
## Optional: graph mode
|
|
122
|
+
|
|
123
|
+
`@sentientui/core/graph` is a separate, tree-shakable entry that activates the DOM scanner and graph sync (component-to-component edges + 2-hop reward propagation). Import it once, on the client, after `init()`:
|
|
124
|
+
|
|
125
|
+
```ts
|
|
126
|
+
import('@sentientui/core/graph');
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
The lean bundle stays under 8 KB gzip; graph adds roughly another 8 KB.
|
|
130
|
+
|
|
131
|
+
## Local overrides (development)
|
|
132
|
+
|
|
133
|
+
```
|
|
134
|
+
# URL parameter (stackable)
|
|
135
|
+
https://yourapp.com?sentient_variant=hero_cta:variant_a
|
|
136
|
+
|
|
137
|
+
# Or before SDK init:
|
|
138
|
+
window.__sentient_overrides = { hero_cta: 'variant_a' };
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
Overrides bypass the bandit entirely — no events recorded.
|
|
142
|
+
|
|
143
|
+
## Docs
|
|
144
|
+
|
|
145
|
+
Full reference: [sentient-ui.com/docs](https://sentient-ui.com/docs).
|
|
80
146
|
|
|
81
147
|
## License
|
|
82
148
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var ie=Object.defineProperty,oe=Object.defineProperties;var ae=Object.getOwnPropertyDescriptors;var V=Object.getOwnPropertySymbols;var ce=Object.prototype.hasOwnProperty,ue=Object.prototype.propertyIsEnumerable;var X=(e,t,n)=>t in e?ie(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))ce.call(t,n)&&X(e,n,t[n]);if(V)for(var n of V(t))ue.call(t,n)&&X(e,n,t[n]);return e},U=(e,t)=>oe(e,ae(t));var de="_snt_uid";var k="_snt_uid";function le(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function ge(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function me(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(o){}}function fe(e){try{return localStorage.getItem(e)}catch(t){return null}}function pe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ye(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function he(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Se(e){try{sessionStorage.removeItem(e)}catch(t){}}function ve(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 we(e){try{localStorage.removeItem(e)}catch(t){}}function xe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Ae={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function Z(e){var d,l,f,h,S;if(typeof window=="undefined")return Ae;let t=(d=e==null?void 0:e.cookieName)!=null?d:de,o=((l=e==null?void 0:e.cookieTTLDays)!=null?l:365)*24*60*60,s=(S=(h=(f=ge(t))!=null?f:fe(k))!=null?h:ye(k))!=null?S:le();me(t,s,o);let i=pe(k,s),r=ve(t),a=i?!1:he(k,s),u=!i&&!r&&!a;return{getSessionId:()=>s,isEphemeral:()=>u,destroy:()=>{s=null,xe(t),we(k),Se(k)}}}var L="_snt_retry";var be={push:()=>{},flush:()=>{},destroy:()=>{}};function Ie(e){try{let t=localStorage.getItem(L);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(L),n.slice(-e)):[]}catch(t){return[]}}function W(e,t){try{let o=[...(()=>{try{let s=localStorage.getItem(L);if(!s)return[];let i=JSON.parse(s);return Array.isArray(i)?i:[]}catch(s){return[]}})(),...e].slice(-t);localStorage.setItem(L,JSON.stringify(o))}catch(n){}}function ee(e){var I,E,D;if(typeof window=="undefined")return be;let t=(I=e.flushIntervalMs)!=null?I:5e3,n=(E=e.maxBatchSize)!=null?E:20,o=(D=e.maxRetrySize)!=null?D:100,s=e.ingestUrl,i=e.apiKey,r=[],a=new Set,u=[],d=c=>{for(let p of c)l.delete(p),!a.has(p)&&(a.add(p),u.push(p));for(;u.length>500;){let p=u.shift();p&&a.delete(p)}},l=new Set,f=c=>{a.has(c.id)||l.has(c.id)||(l.add(c.id),r.push(c))},h=Ie(o);for(let c of h)f(c);let S=0,v=0,P=c=>{if(c.length===0)return;let p=JSON.stringify(c),x=c.map(A=>A.id),b;try{b=fetch(s,{method:"POST",keepalive:!0,body:p,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}})}catch(A){W(c,o);for(let z of x)l.delete(z);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6));return}let O=A=>{if(A.ok||A.status>=400&&A.status<500&&A.status!==429){d(x),v=0,S=0;return}W(c,o);for(let z of x)l.delete(z);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))};b instanceof Promise?b.then(O).catch(()=>{W(c,o);for(let A of x)l.delete(A);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))}):O(b)},C=typeof TextEncoder!="undefined"?new TextEncoder:null,M=c=>C?C.encode(c).length:c.length,$=c=>{let p=[],x=2;for(let b of c){let O=M(JSON.stringify(b))+1;if(p.length>0&&x+O>57344||p.length>=n)break;p.push(b),x+=O}return p},w=()=>{try{if(Date.now()<S)return;for(;r.length>0;){let c=r.filter(x=>!a.has(x.id));if(r.length=0,c.length===0)break;let p=$(c);if(p.length===0)break;p.length<c.length&&r.push(...c.slice(p.length)),P(p)}}catch(c){}},g=!0,m=null;m=setInterval(()=>{g&&w()},t);let y=()=>{document.visibilityState==="hidden"&&w()},T=()=>{w()};return document.addEventListener("visibilitychange",y),window.addEventListener("beforeunload",T),{push(c){f(c),r.length>=n&&w()},flush:w,destroy(){g=!1,m!==null&&(clearInterval(m),m=null),document.removeEventListener("visibilitychange",y),window.removeEventListener("beforeunload",T),w()}}}var N="_snt_asgn_";function K(e,t){return`${e}:${t}`}function Ee(e,t){return`${N}${e}_${t}`}function Y(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(N)&&e.push(n)}return e}catch(e){return[]}}function te(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of Y())try{let i=localStorage.getItem(s);if(!i)continue;let r=JSON.parse(i);if(n(r)){localStorage.removeItem(s);continue}let a=s.slice(N.length),u=a.lastIndexOf("_");if(u<0)continue;let d=a.slice(0,u),l=a.slice(u+1);t.set(K(d,l),r)}catch(i){}})(),{get(s,i){let r=t.get(K(s,i));return r?n(r)?(t.delete(K(s,i)),null):r:null},set(s,i,r){let a=K(s,i);t.set(a,r);try{localStorage.setItem(Ee(s,i),JSON.stringify(r))}catch(u){}},invalidate(s){let i=`${s}:`;for(let r of[...t.keys()])r.startsWith(i)&&t.delete(r);for(let r of Y()){let a=r.slice(N.length),u=a.lastIndexOf("_");if(u<0)continue;if(a.slice(0,u)===s)try{localStorage.removeItem(r)}catch(l){}}},clear(){t.clear();for(let s of Y())try{localStorage.removeItem(s)}catch(i){}}}}function B(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 G(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 Q(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function J(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function _e(e){let t=j("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function j(e,t){var i,r,a,u,d,l,f;let n=(r=(i=t==null?void 0:t.userAgent)==null?void 0:i.trim())!=null?r:"",o=(u=(a=t==null?void 0:t.referer)==null?void 0:a.trim())!=null?u:"",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?B(n):"desktop",trafficSource:o?G(o,t==null?void 0:t.appOrigin):"direct",referrerDomain:Q(o),timeOfDay:J(s),dayOfWeek:(f=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?f:"sun"}}var ne=1500;function F(e,t,n){let o=new AbortController,s=setTimeout(()=>o.abort(),n);return fetch(e,U(_({},t),{signal:o.signal})).finally(()=>clearTimeout(s))}async function ke(e,t,n){var u;let o=(u=n.timeoutMs)!=null?u:ne,s={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(s.Origin=n.origin);let i=j(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await F(`${n.baseUrl}/sessions`,{method:"POST",headers:s,body:JSON.stringify(i)},o)).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(d){}let r=await Promise.allSettled(e.map(async({id:d,variantIds:l})=>{let f=await F(`${n.baseUrl}/assign`,{method:"POST",headers:s,body:JSON.stringify({sessionId:t,componentId:d,variantIds:l})},o);if(!f.ok)return null;let h=await f.json();return{id:d,variantId:h.variantId}})),a={};for(let d of r)d.status==="fulfilled"&&d.value&&(a[d.value.id]=d.value.variantId);return a}function Ce(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}async function Te(e,t,n){var a;let o=(a=n.timeoutMs)!=null?a:ne,s={layoutOrder:e.sections,assignments:{},persona:"unknown",confidence:0},i={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(i.Origin=n.origin);let r=j(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await F(`${n.baseUrl}/sessions`,{method:"POST",headers:i,body:JSON.stringify(r)},o)}catch(u){}try{let u=await F(`${n.baseUrl}/decide`,{method:"POST",headers:i,body:JSON.stringify({sessionId:t,sections:e.sections.map(d=>({id:d})),components:e.components})},o);return u.ok?await u.json():s}catch(u){return s}}var re="https://sentient-api.fly.dev/v1/events",q=null,H=null;function De(){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 R={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Oe(){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 se(e){return e.replace(/\/events\/?$/,"")}function ze(){if(typeof window=="undefined")return;if(!q){console.warn("[sentient] grantConsent() called before init()");return}let e=H;H=null;let t=Re(U(_({},q),{consent:!0}));e==null||e(t)}function Ue(e){var s;let t=se((s=e.ingestUrl)!=null?s:re),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},o={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,async assign(i,r,a){try{let u=new URLSearchParams({componentId:i});for(let f of r!=null?r:[])u.append("variantIds[]",f);let d=await fetch(`${t}/winner?${u.toString()}`,{headers:n});return d.ok?{variantId:(await d.json()).variantId,assignmentTtlMs:0}:r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}catch(u){return r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};return H=i=>{o=i},{track:i=>o.track(i),goal:(i,r)=>o.goal(i,r),identify:i=>o.identify(i),getAssignment:(i,r)=>o.getAssignment(i,r),assign:(i,r,a)=>o.assign(i,r,a),getGraph:()=>o.getGraph(),destroy:()=>o.destroy()}}function Re(e){var P,C,M,$,w;if(typeof window=="undefined")return R;if(q=e,e.consent===!1)return e.preConsentBehavior==="statistical_winner"?!e.apiKey||!e.apiKey.startsWith("pk_")?(console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),R):Ue(e):R;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."),R;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),R;let t=(P=e.ingestUrl)!=null?P:re,n=Date.now(),o=Z(),s=te(),i=ee({ingestUrl:t,apiKey:e.apiKey}),r=se(t),a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u=B((C=navigator.userAgent)!=null?C:""),d=typeof window!="undefined"?window.location.origin:void 0,l=G((M=document.referrer)!=null?M:"",d),f=($=e.sessionSegment)!=null?$:`${u}:${l}`;if(e.initialAssignments)for(let[g,m]of Object.entries(e.initialAssignments))s.set(g,f,{variantId:m,assignedAt:Date.now(),segment:f,confidence:1});let h=Promise.resolve(),S=o.getSessionId();if(S){let g=Q((w=document.referrer)!=null?w:""),m=_({sessionId:S,deviceClass:u,trafficSource:l,referrerDomain:g,utmParams:Oe(),timeOfDay:J(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:o.isEphemeral()},e.userId?{userId:e.userId}:{});try{h=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(m),headers:a}).then(y=>{y.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(y){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:i});let v={goal(g,m={}){let y=o.getSessionId();y&&h.then(()=>{fetch(`${r}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,name:g,metadata:m}),headers:a}).catch(()=>{})})},identify(g){let m=o.getSessionId();m&&h.then(()=>{fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:m,userId:g,ephemeral:o.isEphemeral()}),headers:a}).catch(()=>{})})},track(g){let m=o.getSessionId();if(!m)return;let y=U(_({},g),{id:De(),sessionId:m,timestamp:Date.now(),timeInSession:Date.now()-n});i.push(y),e.debug&&console.log("[sentient] track",y)},getAssignment(g,m){return s.get(g,m)},async assign(g,m,y){let T=o.getSessionId();if(!T)return null;let I=s.get(g,f);if(I)return{variantId:I.variantId,assignmentTtlMs:0,content:I.content};await h;try{let E={sessionId:T,componentId:g,variantIds:m};y!==void 0&&(E.agentData=y);let D=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify(E),headers:a});if(!D.ok)return null;let c=await D.json();return s.set(g,f,{variantId:c.variantId,assignedAt:Date.now(),segment:f,confidence:1,content:c.content}),c}catch(E){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){i.destroy(),o.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let g=window;g.__sentient&&(g.__sentient.client=v)}return v}export{_ as a,U as b,B as c,G as d,Q as e,J as f,_e as g,ke as h,Ce as i,Te as j,ze as k,Re as l};
|
package/dist/index-graph.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var $=Object.defineProperty,de=Object.defineProperties,ue=Object.getOwnPropertyDescriptor,ge=Object.getOwnPropertyDescriptors,le=Object.getOwnPropertyNames,X=Object.getOwnPropertySymbols;var ee=Object.prototype.hasOwnProperty,pe=Object.prototype.propertyIsEnumerable;var Z=(e,t,n)=>t in e?$(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))ee.call(t,n)&&Z(e,n,t[n]);if(X)for(var n of X(t))pe.call(t,n)&&Z(e,n,t[n]);return e},L=(e,t)=>de(e,ge(t));var me=(e,t)=>{for(var n in t)$(e,n,{get:t[n],enumerable:!0})},fe=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let o of le(t))!ee.call(e,o)&&o!==n&&$(e,o,{get:()=>t[o],enumerable:!(a=ue(t,o))||a.enumerable});return e};var he=e=>fe($({},"__esModule",{value:!0}),e);var nt={};me(nt,{deriveSessionSegment:()=>z,detectDeviceClass:()=>k,detectTimeOfDay:()=>R,detectTrafficSource:()=>N,init:()=>tt,preloadAssignments:()=>q,readSessionCookie:()=>W,referrerDomainFromReferer:()=>D});module.exports=he(nt);var ye="_snt_uid";var O="_snt_uid";function Se(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function ve(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function Ie(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(a){}}function Ee(e){try{return localStorage.getItem(e)}catch(t){return null}}function we(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function be(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function Ce(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Ae(e){try{sessionStorage.removeItem(e)}catch(t){}}function _e(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function Te(e){try{localStorage.removeItem(e)}catch(t){}}function xe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Oe={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function te(e){var d,g,l,m,u;if(typeof window=="undefined")return Oe;let t=(d=e==null?void 0:e.cookieName)!=null?d:ye,a=((g=e==null?void 0:e.cookieTTLDays)!=null?g:365)*24*60*60,o=(u=(m=(l=ve(t))!=null?l:Ee(O))!=null?m:be(O))!=null?u:Se();Ie(t,o,a);let i=we(O,o),r=_e(t),s=i?!1:Ce(O,o),c=!i&&!r&&!s;return{getSessionId:()=>o,isEphemeral:()=>c,destroy:()=>{o=null,xe(t),Te(O),Ae(O)}}}var K="_snt_retry";var ke={push:()=>{},flush:()=>{},destroy:()=>{}};function Ne(e){try{let t=localStorage.getItem(K);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(K),n.slice(-e)):[]}catch(t){return[]}}function F(e,t){try{let a=[...(()=>{try{let o=localStorage.getItem(K);if(!o)return[];let i=JSON.parse(o);return Array.isArray(i)?i:[]}catch(o){return[]}})(),...e].slice(-t);localStorage.setItem(K,JSON.stringify(a))}catch(n){}}function ne(e){var v,P,T;if(typeof window=="undefined")return ke;let t=(v=e.flushIntervalMs)!=null?v:5e3,n=(P=e.maxBatchSize)!=null?P:20,a=(T=e.maxRetrySize)!=null?T:100,o=e.ingestUrl,i=e.apiKey,r=[],s=new Set,c=[],d=p=>{for(let S of p)s.has(S)||(s.add(S),c.push(S));for(;c.length>500;){let S=c.shift();S&&s.delete(S)}},g=new Set,l=p=>{s.has(p.id)||g.has(p.id)||(g.add(p.id),r.push(p))},m=Ne(a);for(let p of m)l(p);let u=0,f=0,E=p=>{if(p.length===0)return;let S=JSON.stringify(p),x=p.map(A=>A.id),C;try{C=fetch(o,{method:"POST",keepalive:!0,body:S,headers:{"Content-Type":"application/json",Authorization:`Bearer ${i}`}})}catch(A){F(p,a),f++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6));return}let M=A=>{if(A.ok||A.status>=400&&A.status<500&&A.status!==429){d(x),f=0,u=0;return}F(p,a),f++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6))};C instanceof Promise?C.then(M).catch(()=>{F(p,a),f++,u=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6))}):M(C)},w=p=>{let S=[],x=2;for(let C of p){let M=JSON.stringify(C).length+1;if(S.length>0&&x+M>57344||S.length>=n)break;S.push(C),x+=M}return S},I=()=>{try{if(Date.now()<u)return;for(;r.length>0;){let p=r.filter(x=>!s.has(x.id));if(r.length=0,p.length===0)break;let S=w(p);if(S.length===0)break;S.length<p.length&&r.push(...p.slice(S.length)),E(S)}}catch(p){}},U=!0,b=null;b=setInterval(()=>{U&&I()},t);let h=()=>{document.visibilityState==="hidden"&&I()},y=()=>{I()};return document.addEventListener("visibilitychange",h),window.addEventListener("beforeunload",y),{push(p){l(p),r.length>=n&&I()},flush:I,destroy(){U=!1,b!==null&&(clearInterval(b),b=null),document.removeEventListener("visibilitychange",h),window.removeEventListener("beforeunload",y),I()}}}var B="_snt_asgn_";function G(e,t){return`${e}:${t}`}function De(e,t){return`${B}${e}_${t}`}function J(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(B)&&e.push(n)}return e}catch(e){return[]}}function re(e=18e5){let t=new Map,n=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(n(r)){localStorage.removeItem(o);continue}let s=o.slice(B.length),c=s.lastIndexOf("_");if(c<0)continue;let d=s.slice(0,c),g=s.slice(c+1);t.set(G(d,g),r)}catch(i){}})(),{get(o,i){let r=t.get(G(o,i));return r?n(r)?(t.delete(G(o,i)),null):r:null},set(o,i,r){let s=G(o,i);t.set(s,r);try{localStorage.setItem(De(o,i),JSON.stringify(r))}catch(c){}},invalidate(o){let i=`${o}:`;for(let r of[...t.keys()])r.startsWith(i)&&t.delete(r);for(let r of J()){let s=r.slice(B.length),c=s.lastIndexOf("_");if(c<0)continue;if(s.slice(0,c)===o)try{localStorage.removeItem(r)}catch(g){}}},clear(){t.clear();for(let o of J())try{localStorage.removeItem(o)}catch(i){}}}}function k(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function N(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 a=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(a)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(a)?"social":"referral"}catch(n){return"direct"}}function D(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function R(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function z(e){let t=Q("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Q(e,t){var i,r,s,c,d,g,l;let n=(r=(i=t==null?void 0:t.userAgent)==null?void 0:i.trim())!=null?r:"",a=(c=(s=t==null?void 0:t.referer)==null?void 0:s.trim())!=null?c:"",o=(d=t==null?void 0:t.now)!=null?d:new Date;return{sessionId:e,ephemeral:!1,utmParams:(g=t==null?void 0:t.utmParams)!=null?g:{},deviceClass:n?k(n):"desktop",trafficSource:a?N(a,t==null?void 0:t.appOrigin):"direct",referrerDomain:D(a),timeOfDay:R(o),dayOfWeek:(l=["sun","mon","tue","wed","thu","fri","sat"][o.getDay()])!=null?l:"sun"}}async function q(e,t,n){let a={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(a.Origin=n.origin);let o=Q(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:a,body:JSON.stringify(o)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(s){}let i=await Promise.allSettled(e.map(async({id:s,variantIds:c})=>{let d=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:a,body:JSON.stringify({sessionId:t,componentId:s,variantIds:c})});if(!d.ok)return null;let g=await d.json();return{id:s,variantId:g.variantId}})),r={};for(let s of i)s.status==="fulfilled"&&s.value&&(r[s.value.id]=s.value.variantId);return r}function W(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}var Re="https://sentient-api.fly.dev/v1/events";function Ue(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var j={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Pe(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,a]of t)n.startsWith("utm_")&&(e[n]=a);return e}catch(e){return{}}}function Me(e){return e.replace(/\/events\/?$/,"")}function se(e){var E,w,I,U,b;if(typeof window=="undefined"||e.consent===!1)return j;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."),j;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),j;let t=(E=e.ingestUrl)!=null?E:Re,n=Date.now(),a=te(),o=re(),i=ne({ingestUrl:t,apiKey:e.apiKey}),r=Me(t),s={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c=k((w=navigator.userAgent)!=null?w:""),d=typeof window!="undefined"?window.location.origin:void 0,g=N((I=document.referrer)!=null?I:"",d),l=(U=e.sessionSegment)!=null?U:`${c}:${g}`;if(e.initialAssignments)for(let[h,y]of Object.entries(e.initialAssignments))o.set(h,l,{variantId:y,assignedAt:Date.now(),segment:l,confidence:1});let m=Promise.resolve(),u=a.getSessionId();if(u){let h=D((b=document.referrer)!=null?b:""),y=_({sessionId:u,deviceClass:c,trafficSource:g,referrerDomain:h,utmParams:Pe(),timeOfDay:R(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:a.isEphemeral()},e.userId?{userId:e.userId}:{});try{m=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(y),headers:s}).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 sentientui.dev/pricing")}).catch(()=>{})}catch(v){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:i});let f={goal(h,y={}){let v=a.getSessionId();v&&m.then(()=>{fetch(`${r}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:v,name:h,metadata:y}),headers:s}).catch(()=>{})})},identify(h){let y=a.getSessionId();y&&m.then(()=>{fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,userId:h,ephemeral:a.isEphemeral()}),headers:s}).catch(()=>{})})},track(h){let y=a.getSessionId();if(!y)return;let v=L(_({},h),{id:Ue(),sessionId:y,timestamp:Date.now(),timeInSession:Date.now()-n});i.push(v),e.debug&&console.log("[sentient] track",v)},getAssignment(h,y){return o.get(h,y)},async assign(h,y){let v=a.getSessionId();if(!v)return null;let P=o.get(h,l);if(P)return{variantId:P.variantId,assignmentTtlMs:0};await m;try{let T=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify({sessionId:v,componentId:h,variantIds:y}),headers:s});if(!T.ok)return null;let p=await T.json();return o.set(h,l,{variantId:p.variantId,assignedAt:Date.now(),segment:l,confidence:1}),p}catch(T){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){i.destroy(),a.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let h=window;h.__sentient&&(h.__sentient.client=f)}return f}var $e=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Le="h1, h2, h3",Ke={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function Y(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function Ge(e){var t,n,a;try{let o=e;for(let i of Object.keys(o)){if(!i.startsWith("__reactFiber")&&!i.startsWith("__reactInternalInstance"))continue;let r=o[i],s=(a=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?a:(n=r==null?void 0:r.type)==null?void 0:n.name;if(s&&s.length>1)return s}}catch(o){}}function Be(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function je(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function Fe(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function Je(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function H(e,t){var a,o,i;let n=e.querySelector(Le);return{componentId:Fe(e),semanticType:je(e),ariaLabel:(a=e.getAttribute("aria-label"))!=null?a:void 0,headingText:(i=(o=n==null?void 0:n.textContent)==null?void 0:o.trim())!=null?i:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:Je(e),reactComponentName:Ge(e),dataAttributes:Be(e)}}function oe(e){var i;let t=[],n=new Set,a="__root__",o=new Map;for(let[r,s]of e){let c=r.parentElement,d=a;for(;c;){if(e.has(c)){d=e.get(c);let l=e.get(r),m=`${d}->${l}`;!n.has(m)&&d!==l&&(n.add(m),t.push({fromComponentId:d,toComponentId:l,weight:.6}));break}c=c.parentElement}let g=(i=o.get(d))!=null?i:[];g.push(r),o.set(d,g)}for(let r of o.values())if(!(r.length<2))for(let s=0;s<r.length;s++)for(let c=s+1;c<r.length;c++){let d=e.get(r[s]),g=e.get(r[c]);if(d===g)continue;let l=`${d}->${g}::sib`,m=`${g}->${d}::sib`;n.has(l)||(n.add(l),t.push({fromComponentId:d,toComponentId:g,weight:.3})),n.has(m)||(n.add(m),t.push({fromComponentId:g,toComponentId:d,weight:.3}))}return t}function ze(e){let t=[],n=new Set,a=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let s=H(r,e);t.push(s),a.set(r,s.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(r=>{if(!(r instanceof Element)||n.has(r))return;let s=r.hasAttribute("aria-label"),c=r.hasAttribute("data-sentient-id");if(!s&&!c)return;n.add(r);let d=H(r,e);t.push(d),a.set(r,d.componentId)}),{nodes:t,edges:oe(a)}}function ie(){if(typeof window=="undefined")return Ke;let e=null,t=0,n=null,a=s=>{try{let c=window.getComputedStyle(s),d=parseFloat(c.fontSize)||12,g=parseFloat(c.zIndex)||0,l=s.getBoundingClientRect(),m=Math.max(l.top,0),u=window.innerHeight||1,f=1/(m/u+1),E=Y(d,12,48)*.4+Y(f,0,1)*.4+Y(g,0,100)*.2;return Math.max(0,Math.min(1,E))}catch(c){return .5}};return{scan:()=>new Promise(s=>{let c=()=>{let{nodes:d,edges:g}=ze(a);s({nodes:d,edges:g,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(d){c()}}),observe:s=>{n=s;try{e=new MutationObserver(c=>{let d=[],g=new Map;for(let l of c)l.type==="childList"&&l.addedNodes.forEach(m=>{if(!(m instanceof Element)||!$e.has(m.tagName))return;let u=m.hasAttribute("data-sentient-id"),f=m.hasAttribute("aria-label");if(!u&&!f)return;let E=H(m,a);d.push(E),g.set(m,E.componentId)});d.length>0&&n&&n({nodes:d,edges:oe(g),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:a,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(s){}t=0,n=null}}}var V="_snt_graph_nodes",ae="_snt_graph_edges",Qe={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function qe(e){var t;return(t=Qe[e])!=null?t:[]}function We(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function Ye(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var He=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function Ve(e){return He.has(e)?e:"generic"}function Xe(e,t,n){let a=`${e}:${t}:${n.join(",")}`,o=5381;for(let i=0;i<a.length;i++)o=(o<<5)+o+a.charCodeAt(i)&4294967295;return(o>>>0).toString(16).padStart(8,"0")}function ce(e){let t=new Map,n=new Map,a=()=>{typeof window!="undefined"&&Ye(V,[...t.values()])},o=i=>{var r;try{let s=JSON.parse(i);t.clear();for(let c of(r=s.pageNodes)!=null?r:[])t.set(c.componentId,c)}catch(s){}};if(typeof window!="undefined"){let i=We(V,[]);for(let r of i)t.set(r.componentId,r);try{localStorage.removeItem(ae)}catch(r){}}return{addPageNode(i){t.set(i.componentId,i),a()},addStructuralEdge(i){let r=`${i.fromComponentId}->${i.toComponentId}`;n.set(r,i)},syncOnce(){var r,s;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let i=[...t.values()];if(i.length!==0)try{let c=new Map;for(let u of i){let f=(r=c.get(u.semanticType))!=null?r:[];f.push(u),c.set(u.semanticType,f)}let d=[],g=new Set;for(let u of i)for(let f of qe(u.semanticType)){let E=(s=c.get(f))!=null?s:[];for(let w of E){if(w.componentId===u.componentId)continue;let I=`semantic:${u.componentId}->${w.componentId}`;g.has(I)||(g.add(I),d.push({fromComponentId:u.componentId,toComponentId:w.componentId,type:"semantic",weight:.4,confidence:.9}))}}let l=new Set(i.map(u=>u.componentId));for(let u of n.values()){if(!l.has(u.fromComponentId)||!l.has(u.toComponentId))continue;let f=`structural:${u.fromComponentId}->${u.toComponentId}`;g.has(f)||(g.add(f),d.push({fromComponentId:u.fromComponentId,toComponentId:u.toComponentId,type:"structural",weight:u.weight,confidence:1}))}let m={pageUrl:window.location.href,nodes:i.map(u=>{let f=Ve(u.semanticType);return{componentId:u.componentId,semanticType:f,answers:u.answers,contentHash:Xe(u.componentId,f,u.answers),prominenceScore:u.prominenceScore,depthInPage:u.depth}}),edges:d};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:_({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(m)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:o,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(V),localStorage.removeItem(ae)}catch(i){}}}}var Ze="https://sentient-api.fly.dev/v1/events";function et(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function tt(e){var i;let t=se(e);if(!e.graph||typeof window=="undefined")return t;let n=ie(),a=(i=e.ingestUrl)!=null?i:Ze,o=ce({syncUrl:a.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:et()});try{let r=localStorage.getItem("_snt_graph_nodes");r&&o.restore(JSON.stringify({pageNodes:JSON.parse(r)}))}catch(r){}return n.scan().then(r=>{for(let s of r.nodes)o.addPageNode({id:s.componentId,componentId:s.componentId,semanticType:s.semanticType,answers:s.headingText?[s.headingText]:[],prominenceScore:s.prominenceScore,depth:s.depth});for(let s of r.edges)o.addStructuralEdge(s);o.syncOnce()}),n.observe(r=>{for(let s of r.nodes)o.addPageNode({id:s.componentId,componentId:s.componentId,semanticType:s.semanticType,answers:s.headingText?[s.headingText]:[],prominenceScore:s.prominenceScore,depth:s.depth});for(let s of r.edges)o.addStructuralEdge(s)}),L(_({},t),{getGraph:()=>o.snapshot(),destroy:()=>{n.destroy(),o.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
|
|
1
|
+
"use strict";var B=Object.defineProperty,fe=Object.defineProperties,he=Object.getOwnPropertyDescriptor,ye=Object.getOwnPropertyDescriptors,Se=Object.getOwnPropertyNames,te=Object.getOwnPropertySymbols;var re=Object.prototype.hasOwnProperty,ve=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,A=(e,t)=>{for(var n in t||(t={}))re.call(t,n)&&ne(e,n,t[n]);if(te)for(var n of te(t))ve.call(t,n)&&ne(e,n,t[n]);return e},O=(e,t)=>fe(e,ye(t));var Ie=(e,t)=>{for(var n in t)B(e,n,{get:t[n],enumerable:!0})},we=(e,t,n,a)=>{if(t&&typeof t=="object"||typeof t=="function")for(let s of Se(t))!re.call(e,s)&&s!==n&&B(e,s,{get:()=>t[s],enumerable:!(a=he(t,s))||a.enumerable});return e};var Ee=e=>we(B({},"__esModule",{value:!0}),e);var ut={};Ie(ut,{deriveSessionSegment:()=>W,detectDeviceClass:()=>D,detectTimeOfDay:()=>P,detectTrafficSource:()=>R,init:()=>dt,preloadAssignments:()=>H,readSessionCookie:()=>V,referrerDomainFromReferer:()=>U});module.exports=Ee(ut);var be="_snt_uid";var N="_snt_uid";function Ce(){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 Ae(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(a){}}function Te(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 ke(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 Ne(e){try{sessionStorage.removeItem(e)}catch(t){}}function De(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 Re(e){try{localStorage.removeItem(e)}catch(t){}}function Ue(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Pe={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function se(e){var d,u,g,m,l;if(typeof window=="undefined")return Pe;let t=(d=e==null?void 0:e.cookieName)!=null?d:be,a=((u=e==null?void 0:e.cookieTTLDays)!=null?u:365)*24*60*60,s=(l=(m=(g=Ae(t))!=null?g:Te(N))!=null?m:ke(N))!=null?l:Ce();xe(t,s,a);let o=_e(N,s),r=De(t),i=o?!1:Oe(N,s),c=!o&&!r&&!i;return{getSessionId:()=>s,isEphemeral:()=>c,destroy:()=>{s=null,Ue(t),Re(N),Ne(N)}}}var j="_snt_retry";var Me={push:()=>{},flush:()=>{},destroy:()=>{}};function $e(e){try{let t=localStorage.getItem(j);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(j),n.slice(-e)):[]}catch(t){return[]}}function Q(e,t){try{let a=[...(()=>{try{let s=localStorage.getItem(j);if(!s)return[];let o=JSON.parse(s);return Array.isArray(o)?o:[]}catch(s){return[]}})(),...e].slice(-t);localStorage.setItem(j,JSON.stringify(a))}catch(n){}}function oe(e){var _,k,$;if(typeof window=="undefined")return Me;let t=(_=e.flushIntervalMs)!=null?_:5e3,n=(k=e.maxBatchSize)!=null?k:20,a=($=e.maxRetrySize)!=null?$:100,s=e.ingestUrl,o=e.apiKey,r=[],i=new Set,c=[],d=p=>{for(let S of p)u.delete(S),!i.has(S)&&(i.add(S),c.push(S));for(;c.length>500;){let S=c.shift();S&&i.delete(S)}},u=new Set,g=p=>{i.has(p.id)||u.has(p.id)||(u.add(p.id),r.push(p))},m=$e(a);for(let p of m)g(p);let l=0,f=0,I=p=>{if(p.length===0)return;let S=JSON.stringify(p),b=p.map(C=>C.id),T;try{T=fetch(s,{method:"POST",keepalive:!0,body:S,headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`}})}catch(C){Q(p,a);for(let z of b)u.delete(z);f++,l=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6));return}let L=C=>{if(C.ok||C.status>=400&&C.status<500&&C.status!==429){d(b),f=0,l=0;return}Q(p,a);for(let z of b)u.delete(z);f++,l=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6))};T instanceof Promise?T.then(L).catch(()=>{Q(p,a);for(let C of b)u.delete(C);f++,l=Date.now()+Math.min(6e4,1e3*2**Math.min(f,6))}):L(T)},w=typeof TextEncoder!="undefined"?new TextEncoder:null,x=p=>w?w.encode(p).length:p.length,G=p=>{let S=[],b=2;for(let T of p){let L=x(JSON.stringify(T))+1;if(S.length>0&&b+L>57344||S.length>=n)break;S.push(T),b+=L}return S},E=()=>{try{if(Date.now()<l)return;for(;r.length>0;){let p=r.filter(b=>!i.has(b.id));if(r.length=0,p.length===0)break;let S=G(p);if(S.length===0)break;S.length<p.length&&r.push(...p.slice(S.length)),I(S)}}catch(p){}},h=!0,y=null;y=setInterval(()=>{h&&E()},t);let v=()=>{document.visibilityState==="hidden"&&E()},M=()=>{E()};return document.addEventListener("visibilitychange",v),window.addEventListener("beforeunload",M),{push(p){g(p),r.length>=n&&E()},flush:E,destroy(){h=!1,y!==null&&(clearInterval(y),y=null),document.removeEventListener("visibilitychange",v),window.removeEventListener("beforeunload",M),E()}}}var J="_snt_asgn_";function F(e,t){return`${e}:${t}`}function Le(e,t){return`${J}${e}_${t}`}function q(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(J)&&e.push(n)}return e}catch(e){return[]}}function ie(e=18e5){let t=new Map,n=s=>s.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let s of q())try{let o=localStorage.getItem(s);if(!o)continue;let r=JSON.parse(o);if(n(r)){localStorage.removeItem(s);continue}let i=s.slice(J.length),c=i.lastIndexOf("_");if(c<0)continue;let d=i.slice(0,c),u=i.slice(c+1);t.set(F(d,u),r)}catch(o){}})(),{get(s,o){let r=t.get(F(s,o));return r?n(r)?(t.delete(F(s,o)),null):r:null},set(s,o,r){let i=F(s,o);t.set(i,r);try{localStorage.setItem(Le(s,o),JSON.stringify(r))}catch(c){}},invalidate(s){let o=`${s}:`;for(let r of[...t.keys()])r.startsWith(o)&&t.delete(r);for(let r of q()){let i=r.slice(J.length),c=i.lastIndexOf("_");if(c<0)continue;if(i.slice(0,c)===s)try{localStorage.removeItem(r)}catch(u){}}},clear(){t.clear();for(let s of q())try{localStorage.removeItem(s)}catch(o){}}}}function D(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function 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 a=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(a)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(a)?"social":"referral"}catch(n){return"direct"}}function U(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function P(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function W(e){let t=Y("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function Y(e,t){var o,r,i,c,d,u,g;let n=(r=(o=t==null?void 0:t.userAgent)==null?void 0:o.trim())!=null?r:"",a=(c=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?c:"",s=(d=t==null?void 0:t.now)!=null?d:new Date;return{sessionId:e,ephemeral:!1,utmParams:(u=t==null?void 0:t.utmParams)!=null?u:{},deviceClass:n?D(n):"desktop",trafficSource:a?R(a,t==null?void 0:t.appOrigin):"direct",referrerDomain:U(a),timeOfDay:P(s),dayOfWeek:(g=["sun","mon","tue","wed","thu","fri","sat"][s.getDay()])!=null?g:"sun"}}var Ke=1500;function ae(e,t,n){let a=new AbortController,s=setTimeout(()=>a.abort(),n);return fetch(e,O(A({},t),{signal:a.signal})).finally(()=>clearTimeout(s))}async function H(e,t,n){var c;let a=(c=n.timeoutMs)!=null?c:Ke,s={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(s.Origin=n.origin);let o=Y(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await ae(`${n.baseUrl}/sessions`,{method:"POST",headers:s,body:JSON.stringify(o)},a)).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(d){}let r=await Promise.allSettled(e.map(async({id:d,variantIds:u})=>{let g=await ae(`${n.baseUrl}/assign`,{method:"POST",headers:s,body:JSON.stringify({sessionId:t,componentId:d,variantIds:u})},a);if(!g.ok)return null;let m=await g.json();return{id:d,variantId:m.variantId}})),i={};for(let d of r)d.status==="fulfilled"&&d.value&&(i[d.value.id]=d.value.variantId);return i}function V(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}var ce="https://sentient-api.fly.dev/v1/events",Ge=null,Be=null;function je(){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 K={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Fe(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,a]of t)n.startsWith("utm_")&&(e[n]=a);return e}catch(e){return{}}}function de(e){return e.replace(/\/events\/?$/,"")}function Je(e){var s;let t=de((s=e.ingestUrl)!=null?s:ce),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},a={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,async assign(o,r,i){try{let c=new URLSearchParams({componentId:o});for(let g of r!=null?r:[])c.append("variantIds[]",g);let d=await fetch(`${t}/winner?${c.toString()}`,{headers:n});return d.ok?{variantId:(await d.json()).variantId,assignmentTtlMs:0}:r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}catch(c){return r!=null&&r[0]?{variantId:r[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};return Be=o=>{a=o},{track:o=>a.track(o),goal:(o,r)=>a.goal(o,r),identify:o=>a.identify(o),getAssignment:(o,r)=>a.getAssignment(o,r),assign:(o,r,i)=>a.assign(o,r,i),getGraph:()=>a.getGraph(),destroy:()=>a.destroy()}}function ue(e){var I,w,x,G,E;if(typeof window=="undefined")return K;if(Ge=e,e.consent===!1)return e.preConsentBehavior==="statistical_winner"?!e.apiKey||!e.apiKey.startsWith("pk_")?(console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),K):Je(e):K;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."),K;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),K;let t=(I=e.ingestUrl)!=null?I:ce,n=Date.now(),a=se(),s=ie(),o=oe({ingestUrl:t,apiKey:e.apiKey}),r=de(t),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},c=D((w=navigator.userAgent)!=null?w:""),d=typeof window!="undefined"?window.location.origin:void 0,u=R((x=document.referrer)!=null?x:"",d),g=(G=e.sessionSegment)!=null?G:`${c}:${u}`;if(e.initialAssignments)for(let[h,y]of Object.entries(e.initialAssignments))s.set(h,g,{variantId:y,assignedAt:Date.now(),segment:g,confidence:1});let m=Promise.resolve(),l=a.getSessionId();if(l){let h=U((E=document.referrer)!=null?E:""),y=A({sessionId:l,deviceClass:c,trafficSource:u,referrerDomain:h,utmParams:Fe(),timeOfDay:P(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:a.isEphemeral()},e.userId?{userId:e.userId}:{});try{m=fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(y),headers:i}).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 sentientui.dev/pricing")}).catch(()=>{})}catch(v){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let f={goal(h,y={}){let v=a.getSessionId();v&&m.then(()=>{fetch(`${r}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:v,name:h,metadata:y}),headers:i}).catch(()=>{})})},identify(h){let y=a.getSessionId();y&&m.then(()=>{fetch(`${r}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,userId:h,ephemeral:a.isEphemeral()}),headers:i}).catch(()=>{})})},track(h){let y=a.getSessionId();if(!y)return;let v=O(A({},h),{id:je(),sessionId:y,timestamp:Date.now(),timeInSession:Date.now()-n});o.push(v),e.debug&&console.log("[sentient] track",v)},getAssignment(h,y){return s.get(h,y)},async assign(h,y,v){let M=a.getSessionId();if(!M)return null;let _=s.get(h,g);if(_)return{variantId:_.variantId,assignmentTtlMs:0,content:_.content};await m;try{let k={sessionId:M,componentId:h,variantIds:y};v!==void 0&&(k.agentData=v);let $=await fetch(`${r}/assign`,{method:"POST",body:JSON.stringify(k),headers:i});if(!$.ok)return null;let p=await $.json();return s.set(h,g,{variantId:p.variantId,assignedAt:Date.now(),segment:g,confidence:1,content:p.content}),p}catch(k){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){o.destroy(),a.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let h=window;h.__sentient&&(h.__sentient.client=f)}return f}var ze=new Set(["SECTION","ARTICLE","MAIN","DIV"]),Qe="h1, h2, h3",qe={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 We(e){var t,n,a;try{let s=e;for(let o of Object.keys(s)){if(!o.startsWith("__reactFiber")&&!o.startsWith("__reactInternalInstance"))continue;let r=s[o],i=(a=(t=r==null?void 0:r.type)==null?void 0:t.displayName)!=null?a:(n=r==null?void 0:r.type)==null?void 0:n.name;if(i&&i.length>1)return i}}catch(s){}}function Ye(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function He(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function Ve(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function Xe(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function Z(e,t){var a,s,o;let n=e.querySelector(Qe);return{componentId:Ve(e),semanticType:He(e),ariaLabel:(a=e.getAttribute("aria-label"))!=null?a:void 0,headingText:(o=(s=n==null?void 0:n.textContent)==null?void 0:s.trim())!=null?o:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:Xe(e),reactComponentName:We(e),dataAttributes:Ye(e)}}function le(e){var o;let t=[],n=new Set,a="__root__",s=new Map;for(let[r,i]of e){let c=r.parentElement,d=a;for(;c;){if(e.has(c)){d=e.get(c);let g=e.get(r),m=`${d}->${g}`;!n.has(m)&&d!==g&&(n.add(m),t.push({fromComponentId:d,toComponentId:g,weight:.6}));break}c=c.parentElement}let u=(o=s.get(d))!=null?o:[];u.push(r),s.set(d,u)}for(let r of s.values())if(!(r.length<2))for(let i=0;i<r.length;i++)for(let c=i+1;c<r.length;c++){let d=e.get(r[i]),u=e.get(r[c]);if(d===u)continue;let g=`${d}->${u}::sib`,m=`${u}->${d}::sib`;n.has(g)||(n.add(g),t.push({fromComponentId:d,toComponentId:u,weight:.3})),n.has(m)||(n.add(m),t.push({fromComponentId:u,toComponentId:d,weight:.3}))}return t}function Ze(e){let t=[],n=new Set,a=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(r=>{if(r instanceof Element&&!n.has(r)){n.add(r);let i=Z(r,e);t.push(i),a.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"),c=r.hasAttribute("data-sentient-id");if(!i&&!c)return;n.add(r);let d=Z(r,e);t.push(d),a.set(r,d.componentId)}),{nodes:t,edges:le(a)}}function ge(){if(typeof window=="undefined")return qe;let e=null,t=0,n=null,a=i=>{try{let c=window.getComputedStyle(i),d=parseFloat(c.fontSize)||12,u=parseFloat(c.zIndex)||0,g=i.getBoundingClientRect(),m=Math.max(g.top,0),l=window.innerHeight||1,f=1/(m/l+1),I=X(d,12,48)*.4+X(f,0,1)*.4+X(u,0,100)*.2;return Math.max(0,Math.min(1,I))}catch(c){return .5}};return{scan:()=>new Promise(i=>{let c=()=>{let{nodes:d,edges:u}=Ze(a);i({nodes:d,edges:u,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(c,{timeout:100}):c()}catch(d){c()}}),observe:i=>{n=i;try{e=new MutationObserver(c=>{let d=[],u=new Map;for(let g of c)g.type==="childList"&&g.addedNodes.forEach(m=>{if(!(m instanceof Element)||!ze.has(m.tagName))return;let l=m.hasAttribute("data-sentient-id"),f=m.hasAttribute("aria-label");if(!l&&!f)return;let I=Z(m,a);d.push(I),u.set(m,I.componentId)});d.length>0&&n&&n({nodes:d,edges:le(u),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(c){}},getProminenceScore:a,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(i){}t=0,n=null}}}var ee="_snt_graph_nodes",pe="_snt_graph_edges",et={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function tt(e){var t;return(t=et[e])!=null?t:[]}function nt(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 ot(e){return st.has(e)?e:"generic"}function it(e,t,n){let a=`${e}:${t}:${n.join(",")}`,s=5381;for(let o=0;o<a.length;o++)s=(s<<5)+s+a.charCodeAt(o)&4294967295;return(s>>>0).toString(16).padStart(8,"0")}function me(e){let t=new Map,n=new Map,a=()=>{typeof window!="undefined"&&rt(ee,[...t.values()])},s=o=>{var r;try{let i=JSON.parse(o);t.clear();for(let c of(r=i.pageNodes)!=null?r:[])t.set(c.componentId,c)}catch(i){}};if(typeof window!="undefined"){let o=nt(ee,[]);for(let r of o)t.set(r.componentId,r);try{localStorage.removeItem(pe)}catch(r){}}return{addPageNode(o){t.set(o.componentId,o),a()},addStructuralEdge(o){let r=`${o.fromComponentId}->${o.toComponentId}`;n.set(r,o)},syncOnce(){var r,i;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let o=[...t.values()];if(o.length!==0)try{let c=new Map;for(let l of o){let f=(r=c.get(l.semanticType))!=null?r:[];f.push(l),c.set(l.semanticType,f)}let d=[],u=new Set;for(let l of o)for(let f of tt(l.semanticType)){let I=(i=c.get(f))!=null?i:[];for(let w of I){if(w.componentId===l.componentId)continue;let x=`semantic:${l.componentId}->${w.componentId}`;u.has(x)||(u.add(x),d.push({fromComponentId:l.componentId,toComponentId:w.componentId,type:"semantic",weight:.4,confidence:.9}))}}let g=new Set(o.map(l=>l.componentId));for(let l of n.values()){if(!g.has(l.fromComponentId)||!g.has(l.toComponentId))continue;let f=`structural:${l.fromComponentId}->${l.toComponentId}`;u.has(f)||(u.add(f),d.push({fromComponentId:l.fromComponentId,toComponentId:l.toComponentId,type:"structural",weight:l.weight,confidence:1}))}let m={pageUrl:window.location.href,nodes:o.map(l=>{let f=ot(l.semanticType);return{componentId:l.componentId,semanticType:f,answers:l.answers,contentHash:it(l.componentId,f,l.answers),prominenceScore:l.prominenceScore,depthInPage:l.depth}}),edges:d};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:A({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(m)}).catch(()=>{})}catch(c){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:s,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(ee),localStorage.removeItem(pe)}catch(o){}}}}var at="https://sentient-api.fly.dev/v1/events";function ct(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function dt(e){var o;let t=ue(e);if(!e.graph||typeof window=="undefined")return t;let n=ge(),a=(o=e.ingestUrl)!=null?o:at,s=me({syncUrl:a.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:ct()});try{let r=localStorage.getItem("_snt_graph_nodes");r&&s.restore(JSON.stringify({pageNodes:JSON.parse(r)}))}catch(r){}return n.scan().then(r=>{for(let i of r.nodes)s.addPageNode({id:i.componentId,componentId:i.componentId,semanticType:i.semanticType,answers:i.headingText?[i.headingText]:[],prominenceScore:i.prominenceScore,depth:i.depth});for(let i of r.edges)s.addStructuralEdge(i);s.syncOnce()}),n.observe(r=>{for(let i of r.nodes)s.addPageNode({id:i.componentId,componentId:i.componentId,semanticType:i.semanticType,answers:i.headingText?[i.headingText]:[],prominenceScore:i.prominenceScore,depth:i.depth});for(let i of r.edges)s.addStructuralEdge(i)}),O(A({},t),{getGraph:()=>s.snapshot(),destroy:()=>{n.destroy(),s.destroy(),t.destroy()}})}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,readSessionCookie,referrerDomainFromReferer});
|
package/dist/index-graph.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as h,b,c as x,d as _,e as O,f as M,g as R,h as P,i as D,
|
|
1
|
+
import{a as h,b,c as x,d as _,e as O,f as M,g as R,h as P,i as D,l as v}from"./chunk-CJD3GMCD.mjs";var G=new Set(["SECTION","ARTICLE","MAIN","DIV"]),k="h1, h2, h3",$={scan:async()=>({nodes:[],edges:[],scannedAt:0}),observe:()=>{},getProminenceScore:()=>0,destroy:()=>{}};function S(e,t,n){return n<=t?0:Math.max(0,Math.min(1,(e-t)/(n-t)))}function L(e){var t,n,p;try{let d=e;for(let s of Object.keys(d)){if(!s.startsWith("__reactFiber")&&!s.startsWith("__reactInternalInstance"))continue;let o=d[s],r=(p=(t=o==null?void 0:o.type)==null?void 0:t.displayName)!=null?p:(n=o==null?void 0:o.type)==null?void 0:n.name;if(r&&r.length>1)return r}}catch(d){}}function U(e){let t={};for(let n of Array.from(e.attributes))n.name.startsWith("data-")&&(t[n.name]=n.value);return t}function j(e){let t=e.getAttribute("data-sentient-type");if(t)return t;let n=e.getAttribute("role");return n||"generic"}function F(e){var t,n;return(n=(t=e.getAttribute("data-sentient-id"))!=null?t:e.getAttribute("id"))!=null?n:e.tagName.toLowerCase()}function K(e){let t=0,n=e.parentElement;for(;n;)t++,n=n.parentElement;return t}function I(e,t){var p,d,s;let n=e.querySelector(k);return{componentId:F(e),semanticType:j(e),ariaLabel:(p=e.getAttribute("aria-label"))!=null?p:void 0,headingText:(s=(d=n==null?void 0:n.textContent)==null?void 0:d.trim())!=null?s:void 0,isAboveFold:e.getBoundingClientRect().top<window.innerHeight,prominenceScore:t(e),depth:K(e),reactComponentName:L(e),dataAttributes:U(e)}}function w(e){var s;let t=[],n=new Set,p="__root__",d=new Map;for(let[o,r]of e){let a=o.parentElement,c=p;for(;a;){if(e.has(a)){c=e.get(a);let m=e.get(o),g=`${c}->${m}`;!n.has(g)&&c!==m&&(n.add(g),t.push({fromComponentId:c,toComponentId:m,weight:.6}));break}a=a.parentElement}let u=(s=d.get(c))!=null?s:[];u.push(o),d.set(c,u)}for(let o of d.values())if(!(o.length<2))for(let r=0;r<o.length;r++)for(let a=r+1;a<o.length;a++){let c=e.get(o[r]),u=e.get(o[a]);if(c===u)continue;let m=`${c}->${u}::sib`,g=`${u}->${c}::sib`;n.has(m)||(n.add(m),t.push({fromComponentId:c,toComponentId:u,weight:.3})),n.has(g)||(n.add(g),t.push({fromComponentId:u,toComponentId:c,weight:.3}))}return t}function q(e){let t=[],n=new Set,p=new Map;return document.querySelectorAll("[data-sentient-id]").forEach(o=>{if(o instanceof Element&&!n.has(o)){n.add(o);let r=I(o,e);t.push(r),p.set(o,r.componentId)}}),document.querySelectorAll("section, article, main, aside").forEach(o=>{if(!(o instanceof Element)||n.has(o))return;let r=o.hasAttribute("aria-label"),a=o.hasAttribute("data-sentient-id");if(!r&&!a)return;n.add(o);let c=I(o,e);t.push(c),p.set(o,c.componentId)}),{nodes:t,edges:w(p)}}function N(){if(typeof window=="undefined")return $;let e=null,t=0,n=null,p=r=>{try{let a=window.getComputedStyle(r),c=parseFloat(a.fontSize)||12,u=parseFloat(a.zIndex)||0,m=r.getBoundingClientRect(),g=Math.max(m.top,0),i=window.innerHeight||1,f=1/(g/i+1),l=S(c,12,48)*.4+S(f,0,1)*.4+S(u,0,100)*.2;return Math.max(0,Math.min(1,l))}catch(a){return .5}};return{scan:()=>new Promise(r=>{let a=()=>{let{nodes:c,edges:u}=q(p);r({nodes:c,edges:u,scannedAt:Date.now()})};try{typeof requestIdleCallback=="function"?t=requestIdleCallback(a,{timeout:100}):a()}catch(c){a()}}),observe:r=>{n=r;try{e=new MutationObserver(a=>{let c=[],u=new Map;for(let m of a)m.type==="childList"&&m.addedNodes.forEach(g=>{if(!(g instanceof Element)||!G.has(g.tagName))return;let i=g.hasAttribute("data-sentient-id"),f=g.hasAttribute("aria-label");if(!i&&!f)return;let l=I(g,p);c.push(l),u.set(g,l.componentId)});c.length>0&&n&&n({nodes:c,edges:w(u),addedAt:Date.now()})}),e.observe(document.body,{childList:!0,subtree:!0})}catch(a){}},getProminenceScore:p,destroy:()=>{if(e&&(e.disconnect(),e=null),t&&typeof cancelIdleCallback=="function")try{cancelIdleCallback(t)}catch(r){}t=0,n=null}}}var C="_snt_graph_nodes",A="_snt_graph_edges",z={pricing:["features","faq"],features:["pricing"],faq:["pricing"],social_proof:["cta"],cta:["social_proof","hero","trust"],hero:["cta"],comparison:["pricing"],trust:["cta"]};function H(e){var t;return(t=z[e])!=null?t:[]}function J(e,t){try{let n=localStorage.getItem(e);return n?JSON.parse(n):t}catch(n){return t}}function B(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(n){}}var V=new Set(["pricing","hero","social_proof","cta","features","faq","comparison","trust","navigation","generic"]);function W(e){return V.has(e)?e:"generic"}function Y(e,t,n){let p=`${e}:${t}:${n.join(",")}`,d=5381;for(let s=0;s<p.length;s++)d=(d<<5)+d+p.charCodeAt(s)&4294967295;return(d>>>0).toString(16).padStart(8,"0")}function T(e){let t=new Map,n=new Map,p=()=>{typeof window!="undefined"&&B(C,[...t.values()])},d=s=>{var o;try{let r=JSON.parse(s);t.clear();for(let a of(o=r.pageNodes)!=null?o:[])t.set(a.componentId,a)}catch(r){}};if(typeof window!="undefined"){let s=J(C,[]);for(let o of s)t.set(o.componentId,o);try{localStorage.removeItem(A)}catch(o){}}return{addPageNode(s){t.set(s.componentId,s),p()},addStructuralEdge(s){let o=`${s.fromComponentId}->${s.toComponentId}`;n.set(o,s)},syncOnce(){var o,r;if(!(e!=null&&e.syncUrl)||typeof window=="undefined")return;let s=[...t.values()];if(s.length!==0)try{let a=new Map;for(let i of s){let f=(o=a.get(i.semanticType))!=null?o:[];f.push(i),a.set(i.semanticType,f)}let c=[],u=new Set;for(let i of s)for(let f of H(i.semanticType)){let l=(r=a.get(f))!=null?r:[];for(let y of l){if(y.componentId===i.componentId)continue;let E=`semantic:${i.componentId}->${y.componentId}`;u.has(E)||(u.add(E),c.push({fromComponentId:i.componentId,toComponentId:y.componentId,type:"semantic",weight:.4,confidence:.9}))}}let m=new Set(s.map(i=>i.componentId));for(let i of n.values()){if(!m.has(i.fromComponentId)||!m.has(i.toComponentId))continue;let f=`structural:${i.fromComponentId}->${i.toComponentId}`;u.has(f)||(u.add(f),c.push({fromComponentId:i.fromComponentId,toComponentId:i.toComponentId,type:"structural",weight:i.weight,confidence:1}))}let g={pageUrl:window.location.href,nodes:s.map(i=>{let f=W(i.semanticType);return{componentId:i.componentId,semanticType:f,answers:i.answers,contentHash:Y(i.componentId,f,i.answers),prominenceScore:i.prominenceScore,depthInPage:i.depth}}),edges:c};fetch(e.syncUrl,{method:"POST",keepalive:!0,headers:h({"Content-Type":"application/json"},e.apiKey?{Authorization:`Bearer ${e.apiKey}`}:{}),body:JSON.stringify(g)}).catch(()=>{})}catch(a){}},snapshot(){return{pageNodes:[...t.values()],capturedAt:Date.now()}},serialize(){return JSON.stringify({pageNodes:[...t.values()]})},restore:d,destroy(){if(typeof window!="undefined")try{localStorage.removeItem(C),localStorage.removeItem(A)}catch(s){}}}}var Q="https://sentient-api.fly.dev/v1/events";function X(){try{let e=document.cookie.match(/(?:^|; )_snt_uid=([^;]*)/);return e?decodeURIComponent(e[1]):void 0}catch(e){return}}function se(e){var s;let t=v(e);if(!e.graph||typeof window=="undefined")return t;let n=N(),p=(s=e.ingestUrl)!=null?s:Q,d=T({syncUrl:p.replace(/\/events\/?$/,"/graph/sync"),apiKey:e.apiKey,projectId:e.apiKey,sessionId:X()});try{let o=localStorage.getItem("_snt_graph_nodes");o&&d.restore(JSON.stringify({pageNodes:JSON.parse(o)}))}catch(o){}return n.scan().then(o=>{for(let r of o.nodes)d.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of o.edges)d.addStructuralEdge(r);d.syncOnce()}),n.observe(o=>{for(let r of o.nodes)d.addPageNode({id:r.componentId,componentId:r.componentId,semanticType:r.semanticType,answers:r.headingText?[r.headingText]:[],prominenceScore:r.prominenceScore,depth:r.depth});for(let r of o.edges)d.addStructuralEdge(r)}),b(h({},t),{getGraph:()=>d.snapshot(),destroy:()=>{n.destroy(),d.destroy(),t.destroy()}})}export{R as deriveSessionSegment,x as detectDeviceClass,M as detectTimeOfDay,_ as detectTrafficSource,se as init,P as preloadAssignments,D as readSessionCookie,O as referrerDomainFromReferer};
|
package/dist/index.d.cts
CHANGED
|
@@ -43,6 +43,7 @@ type Assignment = {
|
|
|
43
43
|
assignedAt: number;
|
|
44
44
|
segment: string;
|
|
45
45
|
confidence: number;
|
|
46
|
+
content?: string;
|
|
46
47
|
};
|
|
47
48
|
type AssignmentCache = {
|
|
48
49
|
get(componentId: string, segment: string): Assignment | null;
|
|
@@ -152,6 +153,11 @@ type ServerAssignConfig = {
|
|
|
152
153
|
/** From `Referer` request header. */
|
|
153
154
|
referer?: string;
|
|
154
155
|
utmParams?: Record<string, string>;
|
|
156
|
+
/**
|
|
157
|
+
* Milliseconds to wait for the API before returning default variants.
|
|
158
|
+
* Prevents slow/cold API from blocking SSR. Defaults to 1500.
|
|
159
|
+
*/
|
|
160
|
+
timeoutMs?: number;
|
|
155
161
|
};
|
|
156
162
|
/** componentId → assigned variantId */
|
|
157
163
|
type ServerAssignments = Record<string, string>;
|
|
@@ -230,6 +236,13 @@ type SentientConfig = {
|
|
|
230
236
|
* the user grants or revokes consent mid-session.
|
|
231
237
|
*/
|
|
232
238
|
consent?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Behavior before consent is granted. `'statistical_winner'` fetches the
|
|
241
|
+
* best-performing variant via `GET /v1/winner` — no session or tracking data
|
|
242
|
+
* is stored. `'control'` (default) shows `variantIds[0]` with no API call.
|
|
243
|
+
* Only applies when `consent: false`.
|
|
244
|
+
*/
|
|
245
|
+
preConsentBehavior?: 'statistical_winner' | 'control';
|
|
233
246
|
userId?: string;
|
|
234
247
|
};
|
|
235
248
|
type AssignResult = {
|
|
@@ -243,14 +256,20 @@ type SentientClient = {
|
|
|
243
256
|
identify(userId: string): void;
|
|
244
257
|
getAssignment(componentId: string, segment: string): Assignment | null;
|
|
245
258
|
/** Server-side variant assignment. Caches the result locally per (component, segment). */
|
|
246
|
-
assign(componentId: string, variantIds?: string[]): Promise<AssignResult | null>;
|
|
259
|
+
assign(componentId: string, variantIds?: string[], agentData?: unknown): Promise<AssignResult | null>;
|
|
247
260
|
getGraph(): GraphSnapshot;
|
|
248
261
|
destroy(): void;
|
|
249
262
|
};
|
|
250
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Upgrades a pre-consent client (created with `consent: false, preConsentBehavior: 'statistical_winner'`)
|
|
266
|
+
* to a fully-tracking client. Call this from your consent management platform callback.
|
|
267
|
+
* For React apps, prefer updating the `consent` prop on `<AdaptiveProvider>`.
|
|
268
|
+
*/
|
|
269
|
+
declare function grantConsent(): void;
|
|
251
270
|
/**
|
|
252
271
|
* Initializes the Sentient client. Returns a no-op client during SSR.
|
|
253
272
|
*/
|
|
254
273
|
declare function init(config: SentientConfig): SentientClient;
|
|
255
274
|
|
|
256
|
-
export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type DecideResult, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, preloadDecisions, readSessionCookie, referrerDomainFromReferer };
|
|
275
|
+
export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type DecideResult, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, grantConsent, init, preloadAssignments, preloadDecisions, readSessionCookie, referrerDomainFromReferer };
|
package/dist/index.d.ts
CHANGED
|
@@ -43,6 +43,7 @@ type Assignment = {
|
|
|
43
43
|
assignedAt: number;
|
|
44
44
|
segment: string;
|
|
45
45
|
confidence: number;
|
|
46
|
+
content?: string;
|
|
46
47
|
};
|
|
47
48
|
type AssignmentCache = {
|
|
48
49
|
get(componentId: string, segment: string): Assignment | null;
|
|
@@ -152,6 +153,11 @@ type ServerAssignConfig = {
|
|
|
152
153
|
/** From `Referer` request header. */
|
|
153
154
|
referer?: string;
|
|
154
155
|
utmParams?: Record<string, string>;
|
|
156
|
+
/**
|
|
157
|
+
* Milliseconds to wait for the API before returning default variants.
|
|
158
|
+
* Prevents slow/cold API from blocking SSR. Defaults to 1500.
|
|
159
|
+
*/
|
|
160
|
+
timeoutMs?: number;
|
|
155
161
|
};
|
|
156
162
|
/** componentId → assigned variantId */
|
|
157
163
|
type ServerAssignments = Record<string, string>;
|
|
@@ -230,6 +236,13 @@ type SentientConfig = {
|
|
|
230
236
|
* the user grants or revokes consent mid-session.
|
|
231
237
|
*/
|
|
232
238
|
consent?: boolean;
|
|
239
|
+
/**
|
|
240
|
+
* Behavior before consent is granted. `'statistical_winner'` fetches the
|
|
241
|
+
* best-performing variant via `GET /v1/winner` — no session or tracking data
|
|
242
|
+
* is stored. `'control'` (default) shows `variantIds[0]` with no API call.
|
|
243
|
+
* Only applies when `consent: false`.
|
|
244
|
+
*/
|
|
245
|
+
preConsentBehavior?: 'statistical_winner' | 'control';
|
|
233
246
|
userId?: string;
|
|
234
247
|
};
|
|
235
248
|
type AssignResult = {
|
|
@@ -243,14 +256,20 @@ type SentientClient = {
|
|
|
243
256
|
identify(userId: string): void;
|
|
244
257
|
getAssignment(componentId: string, segment: string): Assignment | null;
|
|
245
258
|
/** Server-side variant assignment. Caches the result locally per (component, segment). */
|
|
246
|
-
assign(componentId: string, variantIds?: string[]): Promise<AssignResult | null>;
|
|
259
|
+
assign(componentId: string, variantIds?: string[], agentData?: unknown): Promise<AssignResult | null>;
|
|
247
260
|
getGraph(): GraphSnapshot;
|
|
248
261
|
destroy(): void;
|
|
249
262
|
};
|
|
250
263
|
|
|
264
|
+
/**
|
|
265
|
+
* Upgrades a pre-consent client (created with `consent: false, preConsentBehavior: 'statistical_winner'`)
|
|
266
|
+
* to a fully-tracking client. Call this from your consent management platform callback.
|
|
267
|
+
* For React apps, prefer updating the `consent` prop on `<AdaptiveProvider>`.
|
|
268
|
+
*/
|
|
269
|
+
declare function grantConsent(): void;
|
|
251
270
|
/**
|
|
252
271
|
* Initializes the Sentient client. Returns a no-op client during SSR.
|
|
253
272
|
*/
|
|
254
273
|
declare function init(config: SentientConfig): SentientClient;
|
|
255
274
|
|
|
256
|
-
export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type DecideResult, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, init, preloadAssignments, preloadDecisions, readSessionCookie, referrerDomainFromReferer };
|
|
275
|
+
export { type AssignResult, type Assignment, type AssignmentCache, type ContentAddedEvent, type DOMScanner, type DecideResult, type EventQueue, type EventType, type GraphClient, type GraphConfig, type GraphSnapshot, type PageNode, type QueueConfig, type ScanResult, type ScannedNode, type SentientClient, type SentientConfig, type SentientEvent, type ServerAssignConfig, type ServerAssignments, type SessionConfig, type SessionManager, deriveSessionSegment, detectDeviceClass, detectTimeOfDay, detectTrafficSource, grantConsent, init, preloadAssignments, preloadDecisions, readSessionCookie, referrerDomainFromReferer };
|
package/dist/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var L=Object.defineProperty,ne=Object.defineProperties,re=Object.getOwnPropertyDescriptor,se=Object.getOwnPropertyDescriptors,ie=Object.getOwnPropertyNames,j=Object.getOwnPropertySymbols;var W=Object.prototype.hasOwnProperty,oe=Object.prototype.propertyIsEnumerable;var z=(e,t,n)=>t in e?L(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,G=(e,t)=>{for(var n in t||(t={}))W.call(t,n)&&z(e,n,t[n]);if(j)for(var n of j(t))oe.call(t,n)&&z(e,n,t[n]);return e},Y=(e,t)=>ne(e,se(t));var ae=(e,t)=>{for(var n in t)L(e,n,{get:t[n],enumerable:!0})},ce=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of ie(t))!W.call(e,r)&&r!==n&&L(e,r,{get:()=>t[r],enumerable:!(i=re(t,r))||i.enumerable});return e};var de=e=>ce(L({},"__esModule",{value:!0}),e);var Oe={};ae(Oe,{deriveSessionSegment:()=>H,detectDeviceClass:()=>C,detectTimeOfDay:()=>R,detectTrafficSource:()=>O,init:()=>Ce,preloadAssignments:()=>Z,preloadDecisions:()=>te,readSessionCookie:()=>ee,referrerDomainFromReferer:()=>U});module.exports=de(Oe);var ue="_snt_uid";var k="_snt_uid";function le(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function ge(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function me(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function fe(e){try{return localStorage.getItem(e)}catch(t){return null}}function pe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ye(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function he(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Se(e){try{sessionStorage.removeItem(e)}catch(t){}}function ve(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 Ie(e){try{localStorage.removeItem(e)}catch(t){}}function we(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Ae={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function q(e){var f,m,p,v,h;if(typeof window=="undefined")return Ae;let t=(f=e==null?void 0:e.cookieName)!=null?f:ue,i=((m=e==null?void 0:e.cookieTTLDays)!=null?m:365)*24*60*60,r=(h=(v=(p=ge(t))!=null?p:fe(k))!=null?v:ye(k))!=null?h:le();me(t,r,i);let a=pe(k,r),s=ve(t),o=a?!1:he(k,r),d=!a&&!s&&!o;return{getSessionId:()=>r,isEphemeral:()=>d,destroy:()=>{r=null,we(t),Ie(k),Se(k)}}}var N="_snt_retry";var Ee={push:()=>{},flush:()=>{},destroy:()=>{}};function be(e){try{let t=localStorage.getItem(N);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(N),n.slice(-e)):[]}catch(t){return[]}}function J(e,t){try{let i=[...(()=>{try{let r=localStorage.getItem(N);if(!r)return[];let a=JSON.parse(r);return Array.isArray(a)?a:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(N,JSON.stringify(i))}catch(n){}}function V(e){var y,T,b;if(typeof window=="undefined")return Ee;let t=(y=e.flushIntervalMs)!=null?y:5e3,n=(T=e.maxBatchSize)!=null?T:20,i=(b=e.maxRetrySize)!=null?b:100,r=e.ingestUrl,a=e.apiKey,s=[],o=new Set,d=[],f=c=>{for(let g of c)o.has(g)||(o.add(g),d.push(g));for(;d.length>500;){let g=d.shift();g&&o.delete(g)}},m=new Set,p=c=>{o.has(c.id)||m.has(c.id)||(m.add(c.id),s.push(c))},v=be(i);for(let c of v)p(c);let h=0,S=0,P=c=>{if(c.length===0)return;let g=JSON.stringify(c),_=c.map(E=>E.id),A;try{A=fetch(r,{method:"POST",keepalive:!0,body:g,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(E){J(c,i),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6));return}let x=E=>{if(E.ok||E.status>=400&&E.status<500&&E.status!==429){f(_),S=0,h=0;return}J(c,i),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6))};A instanceof Promise?A.then(x).catch(()=>{J(c,i),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6))}):x(A)},$=c=>{let g=[],_=2;for(let A of c){let x=JSON.stringify(A).length+1;if(g.length>0&&_+x>57344||g.length>=n)break;g.push(A),_+=x}return g},I=()=>{try{if(Date.now()<h)return;for(;s.length>0;){let c=s.filter(_=>!o.has(_.id));if(s.length=0,c.length===0)break;let g=$(c);if(g.length===0)break;g.length<c.length&&s.push(...c.slice(g.length)),P(g)}}catch(c){}},D=!0,w=null;w=setInterval(()=>{D&&I()},t);let u=()=>{document.visibilityState==="hidden"&&I()},l=()=>{I()};return document.addEventListener("visibilitychange",u),window.addEventListener("beforeunload",l),{push(c){p(c),s.length>=n&&I()},flush:I,destroy(){D=!1,w!==null&&(clearInterval(w),w=null),document.removeEventListener("visibilitychange",u),window.removeEventListener("beforeunload",l),I()}}}var K="_snt_asgn_";function M(e,t){return`${e}:${t}`}function _e(e,t){return`${K}${e}_${t}`}function F(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(K)&&e.push(n)}return e}catch(e){return[]}}function X(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of F())try{let a=localStorage.getItem(r);if(!a)continue;let s=JSON.parse(a);if(n(s)){localStorage.removeItem(r);continue}let o=r.slice(K.length),d=o.lastIndexOf("_");if(d<0)continue;let f=o.slice(0,d),m=o.slice(d+1);t.set(M(f,m),s)}catch(a){}})(),{get(r,a){let s=t.get(M(r,a));return s?n(s)?(t.delete(M(r,a)),null):s:null},set(r,a,s){let o=M(r,a);t.set(o,s);try{localStorage.setItem(_e(r,a),JSON.stringify(s))}catch(d){}},invalidate(r){let a=`${r}:`;for(let s of[...t.keys()])s.startsWith(a)&&t.delete(s);for(let s of F()){let o=s.slice(K.length),d=o.lastIndexOf("_");if(d<0)continue;if(o.slice(0,d)===r)try{localStorage.removeItem(s)}catch(m){}}},clear(){t.clear();for(let r of F())try{localStorage.removeItem(r)}catch(a){}}}}function C(e){let t=e.toLowerCase();return/ipad|tablet|playbook|kindle|silk/.test(t)?"tablet":/mobi|iphone|ipod|android.*mobile|phone/.test(t)?"mobile":"desktop"}function O(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let 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 U(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function R(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function H(e){let t=B("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function B(e,t){var a,s,o,d,f,m,p;let n=(s=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?s:"",i=(d=(o=t==null?void 0:t.referer)==null?void 0:o.trim())!=null?d:"",r=(f=t==null?void 0:t.now)!=null?f:new Date;return{sessionId:e,ephemeral:!1,utmParams:(m=t==null?void 0:t.utmParams)!=null?m:{},deviceClass:n?C(n):"desktop",trafficSource:i?O(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:U(i),timeOfDay:R(r),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?p:"sun"}}async function Z(e,t,n){let i={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(i.Origin=n.origin);let r=B(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:i,body:JSON.stringify(r)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(o){}let a=await Promise.allSettled(e.map(async({id:o,variantIds:d})=>{let f=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:i,body:JSON.stringify({sessionId:t,componentId:o,variantIds:d})});if(!f.ok)return null;let m=await f.json();return{id:o,variantId:m.variantId}})),s={};for(let o of a)o.status==="fulfilled"&&o.value&&(s[o.value.id]=o.value.variantId);return s}function ee(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}async function te(e,t,n){let i={layoutOrder:e.sections,assignments:{},persona:"unknown",confidence:0},r={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(r.Origin=n.origin);let a=B(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:r,body:JSON.stringify(a)})}catch(s){}try{let s=await fetch(`${n.baseUrl}/decide`,{method:"POST",headers:r,body:JSON.stringify({sessionId:t,sections:e.sections.map(o=>({id:o})),components:e.components})});return s.ok?await s.json():i}catch(s){return i}}var ke="https://sentient-api.fly.dev/v1/events";function De(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var Q={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Te(){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 xe(e){return e.replace(/\/events\/?$/,"")}function Ce(e){var P,$,I,D,w;if(typeof window=="undefined"||e.consent===!1)return Q;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."),Q;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),Q;let t=(P=e.ingestUrl)!=null?P:ke,n=Date.now(),i=q(),r=X(),a=V({ingestUrl:t,apiKey:e.apiKey}),s=xe(t),o={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},d=C(($=navigator.userAgent)!=null?$:""),f=typeof window!="undefined"?window.location.origin:void 0,m=O((I=document.referrer)!=null?I:"",f),p=(D=e.sessionSegment)!=null?D:`${d}:${m}`;if(e.initialAssignments)for(let[u,l]of Object.entries(e.initialAssignments))r.set(u,p,{variantId:l,assignedAt:Date.now(),segment:p,confidence:1});let v=Promise.resolve(),h=i.getSessionId();if(h){let u=U((w=document.referrer)!=null?w:""),l=G({sessionId:h,deviceClass:d,trafficSource:m,referrerDomain:u,utmParams:Te(),timeOfDay:R(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:i.isEphemeral()},e.userId?{userId:e.userId}:{});try{v=fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(l),headers:o}).then(y=>{y.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(y){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:a});let S={goal(u,l={}){let y=i.getSessionId();y&&v.then(()=>{fetch(`${s}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,name:u,metadata:l}),headers:o}).catch(()=>{})})},identify(u){let l=i.getSessionId();l&&v.then(()=>{fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:l,userId:u,ephemeral:i.isEphemeral()}),headers:o}).catch(()=>{})})},track(u){let l=i.getSessionId();if(!l)return;let y=Y(G({},u),{id:De(),sessionId:l,timestamp:Date.now(),timeInSession:Date.now()-n});a.push(y),e.debug&&console.log("[sentient] track",y)},getAssignment(u,l){return r.get(u,l)},async assign(u,l){let y=i.getSessionId();if(!y)return null;let T=r.get(u,p);if(T)return{variantId:T.variantId,assignmentTtlMs:0};await v;try{let b=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify({sessionId:y,componentId:u,variantIds:l}),headers:o});if(!b.ok)return null;let c=await b.json();return r.set(u,p,{variantId:c.variantId,assignedAt:Date.now(),segment:p,confidence:1}),c}catch(b){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){a.destroy(),i.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let u=window;u.__sentient&&(u.__sentient.client=S)}return S}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,init,preloadAssignments,preloadDecisions,readSessionCookie,referrerDomainFromReferer});
|
|
1
|
+
"use strict";var G=Object.defineProperty,ge=Object.defineProperties,me=Object.getOwnPropertyDescriptor,fe=Object.getOwnPropertyDescriptors,pe=Object.getOwnPropertyNames,X=Object.getOwnPropertySymbols;var ee=Object.prototype.hasOwnProperty,ye=Object.prototype.propertyIsEnumerable;var Z=(e,t,n)=>t in e?G(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,_=(e,t)=>{for(var n in t||(t={}))ee.call(t,n)&&Z(e,n,t[n]);if(X)for(var n of X(t))ye.call(t,n)&&Z(e,n,t[n]);return e},U=(e,t)=>ge(e,fe(t));var he=(e,t)=>{for(var n in t)G(e,n,{get:t[n],enumerable:!0})},Se=(e,t,n,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let r of pe(t))!ee.call(e,r)&&r!==n&&G(e,r,{get:()=>t[r],enumerable:!(i=me(t,r))||i.enumerable});return e};var ve=e=>Se(G({},"__esModule",{value:!0}),e);var Be={};he(Be,{deriveSessionSegment:()=>se,detectDeviceClass:()=>R,detectTimeOfDay:()=>$,detectTrafficSource:()=>P,grantConsent:()=>Ke,init:()=>le,preloadAssignments:()=>oe,preloadDecisions:()=>ce,readSessionCookie:()=>ae,referrerDomainFromReferer:()=>M});module.exports=ve(Be);var we="_snt_uid";var k="_snt_uid";function xe(){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 Ae(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function be(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(i){}}function Ie(e){try{return localStorage.getItem(e)}catch(t){return null}}function Ee(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 ke(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function Ce(e){try{sessionStorage.removeItem(e)}catch(t){}}function Te(e){try{return document.cookie=`${e}_probe=1; max-age=1; SameSite=strict; path=/`,/(?:^|; )_snt_uid_probe=1/.test(document.cookie)||document.cookie.indexOf(`${e}_probe=1`)!==-1}catch(t){return!1}}function De(e){try{localStorage.removeItem(e)}catch(t){}}function Oe(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var Ue={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function te(e){var d,l,f,h,S;if(typeof window=="undefined")return Ue;let t=(d=e==null?void 0:e.cookieName)!=null?d:we,i=((l=e==null?void 0:e.cookieTTLDays)!=null?l:365)*24*60*60,r=(S=(h=(f=Ae(t))!=null?f:Ie(k))!=null?h:_e(k))!=null?S:xe();be(t,r,i);let o=Ee(k,r),s=Te(t),a=o?!1:ke(k,r),u=!o&&!s&&!a;return{getSessionId:()=>r,isEphemeral:()=>u,destroy:()=>{r=null,Oe(t),De(k),Ce(k)}}}var Q="_snt_retry";var Re={push:()=>{},flush:()=>{},destroy:()=>{}};function Pe(e){try{let t=localStorage.getItem(Q);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(Q),n.slice(-e)):[]}catch(t){return[]}}function Y(e,t){try{let i=[...(()=>{try{let r=localStorage.getItem(Q);if(!r)return[];let o=JSON.parse(r);return Array.isArray(o)?o:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(Q,JSON.stringify(i))}catch(n){}}function ne(e){var I,E,D;if(typeof window=="undefined")return Re;let t=(I=e.flushIntervalMs)!=null?I:5e3,n=(E=e.maxBatchSize)!=null?E:20,i=(D=e.maxRetrySize)!=null?D:100,r=e.ingestUrl,o=e.apiKey,s=[],a=new Set,u=[],d=c=>{for(let p of c)l.delete(p),!a.has(p)&&(a.add(p),u.push(p));for(;u.length>500;){let p=u.shift();p&&a.delete(p)}},l=new Set,f=c=>{a.has(c.id)||l.has(c.id)||(l.add(c.id),s.push(c))},h=Pe(i);for(let c of h)f(c);let S=0,v=0,K=c=>{if(c.length===0)return;let p=JSON.stringify(c),x=c.map(A=>A.id),b;try{b=fetch(r,{method:"POST",keepalive:!0,body:p,headers:{"Content-Type":"application/json",Authorization:`Bearer ${o}`}})}catch(A){Y(c,i);for(let W of x)l.delete(W);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6));return}let O=A=>{if(A.ok||A.status>=400&&A.status<500&&A.status!==429){d(x),v=0,S=0;return}Y(c,i);for(let W of x)l.delete(W);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))};b instanceof Promise?b.then(O).catch(()=>{Y(c,i);for(let A of x)l.delete(A);v++,S=Date.now()+Math.min(6e4,1e3*2**Math.min(v,6))}):O(b)},C=typeof TextEncoder!="undefined"?new TextEncoder:null,N=c=>C?C.encode(c).length:c.length,B=c=>{let p=[],x=2;for(let b of c){let O=N(JSON.stringify(b))+1;if(p.length>0&&x+O>57344||p.length>=n)break;p.push(b),x+=O}return p},w=()=>{try{if(Date.now()<S)return;for(;s.length>0;){let c=s.filter(x=>!a.has(x.id));if(s.length=0,c.length===0)break;let p=B(c);if(p.length===0)break;p.length<c.length&&s.push(...c.slice(p.length)),K(p)}}catch(c){}},g=!0,m=null;m=setInterval(()=>{g&&w()},t);let y=()=>{document.visibilityState==="hidden"&&w()},T=()=>{w()};return document.addEventListener("visibilitychange",y),window.addEventListener("beforeunload",T),{push(c){f(c),s.length>=n&&w()},flush:w,destroy(){g=!1,m!==null&&(clearInterval(m),m=null),document.removeEventListener("visibilitychange",y),window.removeEventListener("beforeunload",T),w()}}}var j="_snt_asgn_";function J(e,t){return`${e}:${t}`}function Me(e,t){return`${j}${e}_${t}`}function q(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(j)&&e.push(n)}return e}catch(e){return[]}}function re(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of q())try{let o=localStorage.getItem(r);if(!o)continue;let s=JSON.parse(o);if(n(s)){localStorage.removeItem(r);continue}let a=r.slice(j.length),u=a.lastIndexOf("_");if(u<0)continue;let d=a.slice(0,u),l=a.slice(u+1);t.set(J(d,l),s)}catch(o){}})(),{get(r,o){let s=t.get(J(r,o));return s?n(s)?(t.delete(J(r,o)),null):s:null},set(r,o,s){let a=J(r,o);t.set(a,s);try{localStorage.setItem(Me(r,o),JSON.stringify(s))}catch(u){}},invalidate(r){let o=`${r}:`;for(let s of[...t.keys()])s.startsWith(o)&&t.delete(s);for(let s of q()){let a=s.slice(j.length),u=a.lastIndexOf("_");if(u<0)continue;if(a.slice(0,u)===r)try{localStorage.removeItem(s)}catch(l){}}},clear(){t.clear();for(let r of q())try{localStorage.removeItem(r)}catch(o){}}}}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 P(e,t){if(!e)return"direct";try{let n=new URL(e);if(t)try{if(new URL(t).host===n.host)return"direct"}catch(r){}let i=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(i)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(i)?"social":"referral"}catch(n){return"direct"}}function M(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function $(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function se(e){let t=F("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function F(e,t){var o,s,a,u,d,l,f;let n=(s=(o=t==null?void 0:t.userAgent)==null?void 0:o.trim())!=null?s:"",i=(u=(a=t==null?void 0:t.referer)==null?void 0:a.trim())!=null?u:"",r=(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?R(n):"desktop",trafficSource:i?P(i,t==null?void 0:t.appOrigin):"direct",referrerDomain:M(i),timeOfDay:$(r),dayOfWeek:(f=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?f:"sun"}}var ie=1500;function z(e,t,n){let i=new AbortController,r=setTimeout(()=>i.abort(),n);return fetch(e,U(_({},t),{signal:i.signal})).finally(()=>clearTimeout(r))}async function oe(e,t,n){var u;let i=(u=n.timeoutMs)!=null?u:ie,r={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(r.Origin=n.origin);let o=F(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await z(`${n.baseUrl}/sessions`,{method:"POST",headers:r,body:JSON.stringify(o)},i)).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(d){}let s=await Promise.allSettled(e.map(async({id:d,variantIds:l})=>{let f=await z(`${n.baseUrl}/assign`,{method:"POST",headers:r,body:JSON.stringify({sessionId:t,componentId:d,variantIds:l})},i);if(!f.ok)return null;let h=await f.json();return{id:d,variantId:h.variantId}})),a={};for(let d of s)d.status==="fulfilled"&&d.value&&(a[d.value.id]=d.value.variantId);return a}function ae(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}async function ce(e,t,n){var a;let i=(a=n.timeoutMs)!=null?a:ie,r={layoutOrder:e.sections,assignments:{},persona:"unknown",confidence:0},o={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(o.Origin=n.origin);let s=F(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await z(`${n.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(s)},i)}catch(u){}try{let u=await z(`${n.baseUrl}/decide`,{method:"POST",headers:o,body:JSON.stringify({sessionId:t,sections:e.sections.map(d=>({id:d})),components:e.components})},i);return u.ok?await u.json():r}catch(u){return r}}var ue="https://sentient-api.fly.dev/v1/events",H=null,V=null;function $e(){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 L={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),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 de(e){return e.replace(/\/events\/?$/,"")}function Ke(){if(typeof window=="undefined")return;if(!H){console.warn("[sentient] grantConsent() called before init()");return}let e=V;V=null;let t=le(U(_({},H),{consent:!0}));e==null||e(t)}function Ne(e){var r;let t=de((r=e.ingestUrl)!=null?r:ue),n={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},i={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,async assign(o,s,a){try{let u=new URLSearchParams({componentId:o});for(let f of s!=null?s:[])u.append("variantIds[]",f);let d=await fetch(`${t}/winner?${u.toString()}`,{headers:n});return d.ok?{variantId:(await d.json()).variantId,assignmentTtlMs:0}:s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}catch(u){return s!=null&&s[0]?{variantId:s[0],assignmentTtlMs:0}:null}},getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};return V=o=>{i=o},{track:o=>i.track(o),goal:(o,s)=>i.goal(o,s),identify:o=>i.identify(o),getAssignment:(o,s)=>i.getAssignment(o,s),assign:(o,s,a)=>i.assign(o,s,a),getGraph:()=>i.getGraph(),destroy:()=>i.destroy()}}function le(e){var K,C,N,B,w;if(typeof window=="undefined")return L;if(H=e,e.consent===!1)return e.preConsentBehavior==="statistical_winner"?!e.apiKey||!e.apiKey.startsWith("pk_")?(console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),L):Ne(e):L;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),L;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),L;let t=(K=e.ingestUrl)!=null?K:ue,n=Date.now(),i=te(),r=re(),o=ne({ingestUrl:t,apiKey:e.apiKey}),s=de(t),a={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},u=R((C=navigator.userAgent)!=null?C:""),d=typeof window!="undefined"?window.location.origin:void 0,l=P((N=document.referrer)!=null?N:"",d),f=(B=e.sessionSegment)!=null?B:`${u}:${l}`;if(e.initialAssignments)for(let[g,m]of Object.entries(e.initialAssignments))r.set(g,f,{variantId:m,assignedAt:Date.now(),segment:f,confidence:1});let h=Promise.resolve(),S=i.getSessionId();if(S){let g=M((w=document.referrer)!=null?w:""),m=_({sessionId:S,deviceClass:u,trafficSource:l,referrerDomain:g,utmParams:Le(),timeOfDay:$(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:i.isEphemeral()},e.userId?{userId:e.userId}:{});try{h=fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(m),headers:a}).then(y=>{y.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(y){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:o});let v={goal(g,m={}){let y=i.getSessionId();y&&h.then(()=>{fetch(`${s}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,name:g,metadata:m}),headers:a}).catch(()=>{})})},identify(g){let m=i.getSessionId();m&&h.then(()=>{fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:m,userId:g,ephemeral:i.isEphemeral()}),headers:a}).catch(()=>{})})},track(g){let m=i.getSessionId();if(!m)return;let y=U(_({},g),{id:$e(),sessionId:m,timestamp:Date.now(),timeInSession:Date.now()-n});o.push(y),e.debug&&console.log("[sentient] track",y)},getAssignment(g,m){return r.get(g,m)},async assign(g,m,y){let T=i.getSessionId();if(!T)return null;let I=r.get(g,f);if(I)return{variantId:I.variantId,assignmentTtlMs:0,content:I.content};await h;try{let E={sessionId:T,componentId:g,variantIds:m};y!==void 0&&(E.agentData=y);let D=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify(E),headers:a});if(!D.ok)return null;let c=await D.json();return r.set(g,f,{variantId:c.variantId,assignedAt:Date.now(),segment:f,confidence:1,content:c.content}),c}catch(E){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){o.destroy(),i.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let g=window;g.__sentient&&(g.__sentient.client=v)}return v}0&&(module.exports={deriveSessionSegment,detectDeviceClass,detectTimeOfDay,detectTrafficSource,grantConsent,init,preloadAssignments,preloadDecisions,readSessionCookie,referrerDomainFromReferer});
|
package/dist/index.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h,k as i}from"./chunk-
|
|
1
|
+
import{c as a,d as b,e as c,f as d,g as e,h as f,i as g,j as h,k as i,l as j}from"./chunk-CJD3GMCD.mjs";export{e as deriveSessionSegment,a as detectDeviceClass,d as detectTimeOfDay,b as detectTrafficSource,i as grantConsent,j as init,f as preloadAssignments,h as preloadDecisions,g as readSessionCookie,c as referrerDomainFromReferer};
|
package/package.json
CHANGED
package/dist/chunk-HWKW5O3R.mjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var V=Object.defineProperty,X=Object.defineProperties;var H=Object.getOwnPropertyDescriptors;var F=Object.getOwnPropertySymbols;var Z=Object.prototype.hasOwnProperty,ee=Object.prototype.propertyIsEnumerable;var j=(e,t,n)=>t in e?V(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n,Q=(e,t)=>{for(var n in t||(t={}))Z.call(t,n)&&j(e,n,t[n]);if(F)for(var n of F(t))ee.call(t,n)&&j(e,n,t[n]);return e},z=(e,t)=>X(e,H(t));var te="_snt_uid";var k="_snt_uid";function ne(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(t){}let e=()=>Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0");return`${e()}-${e()}-${e()}-${e()}`}function re(e){try{let t=document.cookie.match(new RegExp(`(?:^|; )${e}=([^;]*)`));return t?decodeURIComponent(t[1]):null}catch(t){return null}}function se(e,t,n){try{document.cookie=`${e}=${encodeURIComponent(t)}; max-age=${n}; SameSite=strict; path=/`}catch(o){}}function ie(e){try{return localStorage.getItem(e)}catch(t){return null}}function oe(e,t){try{return localStorage.setItem(e,t),!0}catch(n){return!1}}function ae(e){try{return sessionStorage.getItem(e)}catch(t){return null}}function ce(e,t){try{return sessionStorage.setItem(e,t),!0}catch(n){return!1}}function 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 le(e){try{localStorage.removeItem(e)}catch(t){}}function ge(e){try{document.cookie=`${e}=; max-age=0; SameSite=strict; path=/`}catch(t){}}var me={getSessionId:()=>null,isEphemeral:()=>!1,destroy:()=>{}};function W(e){var f,m,p,v,h;if(typeof window=="undefined")return me;let t=(f=e==null?void 0:e.cookieName)!=null?f:te,o=((m=e==null?void 0:e.cookieTTLDays)!=null?m:365)*24*60*60,r=(h=(v=(p=re(t))!=null?p:ie(k))!=null?v:ae(k))!=null?h:ne();se(t,r,o);let a=oe(k,r),s=ue(t),i=a?!1:ce(k,r),d=!a&&!s&&!i;return{getSessionId:()=>r,isEphemeral:()=>d,destroy:()=>{r=null,ge(t),le(k),de(k)}}}var U="_snt_retry";var fe={push:()=>{},flush:()=>{},destroy:()=>{}};function pe(e){try{let t=localStorage.getItem(U);if(!t)return[];let n=JSON.parse(t);return Array.isArray(n)?(localStorage.removeItem(U),n.slice(-e)):[]}catch(t){return[]}}function G(e,t){try{let o=[...(()=>{try{let r=localStorage.getItem(U);if(!r)return[];let a=JSON.parse(r);return Array.isArray(a)?a:[]}catch(r){return[]}})(),...e].slice(-t);localStorage.setItem(U,JSON.stringify(o))}catch(n){}}function Y(e){var y,T,b;if(typeof window=="undefined")return fe;let t=(y=e.flushIntervalMs)!=null?y:5e3,n=(T=e.maxBatchSize)!=null?T:20,o=(b=e.maxRetrySize)!=null?b:100,r=e.ingestUrl,a=e.apiKey,s=[],i=new Set,d=[],f=c=>{for(let g of c)i.has(g)||(i.add(g),d.push(g));for(;d.length>500;){let g=d.shift();g&&i.delete(g)}},m=new Set,p=c=>{i.has(c.id)||m.has(c.id)||(m.add(c.id),s.push(c))},v=pe(o);for(let c of v)p(c);let h=0,S=0,C=c=>{if(c.length===0)return;let g=JSON.stringify(c),_=c.map(E=>E.id),A;try{A=fetch(r,{method:"POST",keepalive:!0,body:g,headers:{"Content-Type":"application/json",Authorization:`Bearer ${a}`}})}catch(E){G(c,o),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6));return}let x=E=>{if(E.ok||E.status>=400&&E.status<500&&E.status!==429){f(_),S=0,h=0;return}G(c,o),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6))};A instanceof Promise?A.then(x).catch(()=>{G(c,o),S++,h=Date.now()+Math.min(6e4,1e3*2**Math.min(S,6))}):x(A)},O=c=>{let g=[],_=2;for(let A of c){let x=JSON.stringify(A).length+1;if(g.length>0&&_+x>57344||g.length>=n)break;g.push(A),_+=x}return g},I=()=>{try{if(Date.now()<h)return;for(;s.length>0;){let c=s.filter(_=>!i.has(_.id));if(s.length=0,c.length===0)break;let g=O(c);if(g.length===0)break;g.length<c.length&&s.push(...c.slice(g.length)),C(g)}}catch(c){}},D=!0,w=null;w=setInterval(()=>{D&&I()},t);let u=()=>{document.visibilityState==="hidden"&&I()},l=()=>{I()};return document.addEventListener("visibilitychange",u),window.addEventListener("beforeunload",l),{push(c){p(c),s.length>=n&&I()},flush:I,destroy(){D=!1,w!==null&&(clearInterval(w),w=null),document.removeEventListener("visibilitychange",u),window.removeEventListener("beforeunload",l),I()}}}var P="_snt_asgn_";function R(e,t){return`${e}:${t}`}function ye(e,t){return`${P}${e}_${t}`}function J(){try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n!=null&&n.startsWith(P)&&e.push(n)}return e}catch(e){return[]}}function q(e=18e5){let t=new Map,n=r=>r.assignedAt+e<Date.now();return typeof window!="undefined"&&(()=>{for(let r of J())try{let a=localStorage.getItem(r);if(!a)continue;let s=JSON.parse(a);if(n(s)){localStorage.removeItem(r);continue}let i=r.slice(P.length),d=i.lastIndexOf("_");if(d<0)continue;let f=i.slice(0,d),m=i.slice(d+1);t.set(R(f,m),s)}catch(a){}})(),{get(r,a){let s=t.get(R(r,a));return s?n(s)?(t.delete(R(r,a)),null):s:null},set(r,a,s){let i=R(r,a);t.set(i,s);try{localStorage.setItem(ye(r,a),JSON.stringify(s))}catch(d){}},invalidate(r){let a=`${r}:`;for(let s of[...t.keys()])s.startsWith(a)&&t.delete(s);for(let s of J()){let i=s.slice(P.length),d=i.lastIndexOf("_");if(d<0)continue;if(i.slice(0,d)===r)try{localStorage.removeItem(s)}catch(m){}}},clear(){t.clear();for(let r of J())try{localStorage.removeItem(r)}catch(a){}}}}function $(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(r){}let o=n.hostname.toLowerCase();return/(^|\.)(google|bing|duckduckgo|yahoo)\./.test(o)?"search":/(^|\.)(twitter|x\.com|facebook|linkedin|reddit|t\.co)/.test(o)?"social":"referral"}catch(n){return"direct"}}function N(e){if(!e)return null;try{return new URL(e).hostname}catch(t){return null}}function M(e){let t=e.getHours();return t<6?"night":t<12?"morning":t<18?"afternoon":"evening"}function he(e){let t=K("__segment__",e);return`${t.deviceClass}:${t.trafficSource}`}function K(e,t){var a,s,i,d,f,m,p;let n=(s=(a=t==null?void 0:t.userAgent)==null?void 0:a.trim())!=null?s:"",o=(d=(i=t==null?void 0:t.referer)==null?void 0:i.trim())!=null?d:"",r=(f=t==null?void 0:t.now)!=null?f:new Date;return{sessionId:e,ephemeral:!1,utmParams:(m=t==null?void 0:t.utmParams)!=null?m:{},deviceClass:n?$(n):"desktop",trafficSource:o?L(o,t==null?void 0:t.appOrigin):"direct",referrerDomain:N(o),timeOfDay:M(r),dayOfWeek:(p=["sun","mon","tue","wed","thu","fri","sat"][r.getDay()])!=null?p:"sun"}}async function Se(e,t,n){let o={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(o.Origin=n.origin);let r=K(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{(await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:o,body:JSON.stringify(r)})).status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}catch(i){}let a=await Promise.allSettled(e.map(async({id:i,variantIds:d})=>{let f=await fetch(`${n.baseUrl}/assign`,{method:"POST",headers:o,body:JSON.stringify({sessionId:t,componentId:i,variantIds:d})});if(!f.ok)return null;let m=await f.json();return{id:i,variantId:m.variantId}})),s={};for(let i of a)i.status==="fulfilled"&&i.value&&(s[i.value.id]=i.value.variantId);return s}function ve(e){var t,n;return(n=(t=e.get("_snt_uid"))==null?void 0:t.value)!=null?n:null}async function Ie(e,t,n){let o={layoutOrder:e.sections,assignments:{},persona:"unknown",confidence:0},r={"Content-Type":"application/json",Authorization:`Bearer ${n.apiKey}`};n.origin&&(r.Origin=n.origin);let a=K(t,{userAgent:n.userAgent,referer:n.referer,utmParams:n.utmParams,appOrigin:n.origin});try{await fetch(`${n.baseUrl}/sessions`,{method:"POST",headers:r,body:JSON.stringify(a)})}catch(s){}try{let s=await fetch(`${n.baseUrl}/decide`,{method:"POST",headers:r,body:JSON.stringify({sessionId:t,sections:e.sections.map(i=>({id:i})),components:e.components})});return s.ok?await s.json():o}catch(s){return o}}var we="https://sentient-api.fly.dev/v1/events";function Ae(){try{if(typeof crypto!="undefined"&&typeof crypto.randomUUID=="function")return crypto.randomUUID()}catch(e){}return`evt-${Date.now()}-${Math.random().toString(16).slice(2)}`}var B={track:()=>{},goal:()=>{},identify:()=>{},getAssignment:()=>null,assign:()=>Promise.resolve(null),getGraph:()=>({pageNodes:[],capturedAt:0}),destroy:()=>{}};function Ee(){try{let e={},t=new URLSearchParams(window.location.search);for(let[n,o]of t)n.startsWith("utm_")&&(e[n]=o);return e}catch(e){return{}}}function be(e){return e.replace(/\/events\/?$/,"")}function Le(e){var C,O,I,D,w;if(typeof window=="undefined"||e.consent===!1)return B;if(!e.apiKey||!e.apiKey.startsWith("pk_"))return console.warn("[sentient] init() called with an invalid apiKey \u2014 expected a pk_ public key. SDK disabled."),B;if(e.ingestUrl==="")return console.warn("[sentient] init() called with an empty ingestUrl. SDK disabled."),B;let t=(C=e.ingestUrl)!=null?C:we,n=Date.now(),o=W(),r=q(),a=Y({ingestUrl:t,apiKey:e.apiKey}),s=be(t),i={"Content-Type":"application/json",Authorization:`Bearer ${e.apiKey}`},d=$((O=navigator.userAgent)!=null?O:""),f=typeof window!="undefined"?window.location.origin:void 0,m=L((I=document.referrer)!=null?I:"",f),p=(D=e.sessionSegment)!=null?D:`${d}:${m}`;if(e.initialAssignments)for(let[u,l]of Object.entries(e.initialAssignments))r.set(u,p,{variantId:l,assignedAt:Date.now(),segment:p,confidence:1});let v=Promise.resolve(),h=o.getSessionId();if(h){let u=N((w=document.referrer)!=null?w:""),l=Q({sessionId:h,deviceClass:d,trafficSource:m,referrerDomain:u,utmParams:Ee(),timeOfDay:M(new Date),dayOfWeek:["sun","mon","tue","wed","thu","fri","sat"][new Date().getDay()],ephemeral:o.isEphemeral()},e.userId?{userId:e.userId}:{});try{v=fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify(l),headers:i}).then(y=>{y.status===402&&console.warn("[SentientUI] Session limit exceeded for this project. The bandit will stop learning until the limit resets. Upgrade at sentientui.dev/pricing")}).catch(()=>{})}catch(y){}}e.debug&&(console.log("[sentient] initialized",{context:e.context}),window.__sentient={client:null,queue:a});let S={goal(u,l={}){let y=o.getSessionId();y&&v.then(()=>{fetch(`${s}/goals`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:y,name:u,metadata:l}),headers:i}).catch(()=>{})})},identify(u){let l=o.getSessionId();l&&v.then(()=>{fetch(`${s}/sessions`,{method:"POST",keepalive:!0,body:JSON.stringify({sessionId:l,userId:u,ephemeral:o.isEphemeral()}),headers:i}).catch(()=>{})})},track(u){let l=o.getSessionId();if(!l)return;let y=z(Q({},u),{id:Ae(),sessionId:l,timestamp:Date.now(),timeInSession:Date.now()-n});a.push(y),e.debug&&console.log("[sentient] track",y)},getAssignment(u,l){return r.get(u,l)},async assign(u,l){let y=o.getSessionId();if(!y)return null;let T=r.get(u,p);if(T)return{variantId:T.variantId,assignmentTtlMs:0};await v;try{let b=await fetch(`${s}/assign`,{method:"POST",body:JSON.stringify({sessionId:y,componentId:u,variantIds:l}),headers:i});if(!b.ok)return null;let c=await b.json();return r.set(u,p,{variantId:c.variantId,assignedAt:Date.now(),segment:p,confidence:1}),c}catch(b){return null}},getGraph(){return{pageNodes:[],capturedAt:0}},destroy(){a.destroy(),o.destroy(),e.debug&&console.log("[sentient] destroyed")}};if(e.debug){let u=window;u.__sentient&&(u.__sentient.client=S)}return S}export{Q as a,z as b,$ as c,L as d,N as e,M as f,he as g,Se as h,ve as i,Ie as j,Le as k};
|