@prodantix/sdk 0.0.1-beta.333 → 0.0.1-beta.340
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 +2 -2
- package/dist/chat.cjs +37 -13
- package/dist/chat.d.cts +31 -43
- package/dist/chat.d.ts +31 -43
- package/dist/chat.js +37 -13
- package/dist/chunk-5XGN7UAV.js +2 -0
- package/dist/chunk-7J6AQICL.js +2 -0
- package/dist/chunk-VG77TYVX.js +2 -0
- package/dist/{client-B1bcIuD8.d.cts → client-BBUAoQg2.d.cts} +28 -1
- package/dist/{client-B1bcIuD8.d.ts → client-BBUAoQg2.d.ts} +28 -1
- package/dist/config-B-cTz9n1.d.ts +94 -0
- package/dist/config-OP9Csae6.d.cts +94 -0
- package/dist/csp.cjs +3 -0
- package/dist/csp.d.cts +37 -0
- package/dist/csp.d.ts +37 -0
- package/dist/csp.js +3 -0
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +3 -3
- package/dist/index.d.ts +3 -3
- package/dist/index.js +1 -1
- package/dist/messenger.cjs +2 -0
- package/dist/messenger.d.cts +2 -0
- package/dist/messenger.d.ts +2 -0
- package/dist/messenger.iife.js +65 -0
- package/dist/messenger.js +2 -0
- package/dist/node.cjs +1 -1
- package/dist/node.d.cts +1 -1
- package/dist/node.d.ts +1 -1
- package/dist/node.js +1 -1
- package/dist/{transport-BOmEPpCa.d.cts → transport-DhhzvwpV.d.cts} +1 -1
- package/dist/{transport-B7A4sAOI.d.ts → transport-dWp3NUMj.d.ts} +1 -1
- package/dist/web.cjs +1 -1
- package/dist/web.d.cts +2 -2
- package/dist/web.d.ts +2 -2
- package/dist/web.js +1 -1
- package/package.json +14 -4
- package/dist/chunk-D2MYK23I.js +0 -2
- package/dist/chunk-STIKBPFF.js +0 -2
package/README.md
CHANGED
|
@@ -81,8 +81,8 @@ anywhere.
|
|
|
81
81
|
|
|
82
82
|
| Option | Default | Notes |
|
|
83
83
|
| --- | --- | --- |
|
|
84
|
-
| `apiKey` |
|
|
85
|
-
| `host` |
|
|
84
|
+
| `apiKey` | required | Public project key (`pdx_pub_…`). Required. |
|
|
85
|
+
| `host` | required | Ingest base URL. Required. |
|
|
86
86
|
| `flagsHost` | `host` | Flag-eval base URL (`GET /v1/flags`). |
|
|
87
87
|
| `flushAt` | `20` | Flush when this many events are queued. |
|
|
88
88
|
| `flushIntervalMs` | `10000` | Periodic flush interval; `0` disables the timer. |
|
package/dist/chat.cjs
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
'use strict';var
|
|
2
|
-
:host {
|
|
1
|
+
'use strict';var I=Object.defineProperty;var O=(n,e,t)=>e in n?I(n,e,{enumerable:true,configurable:true,writable:true,value:t}):n[e]=t;var l=(n,e,t)=>O(n,typeof e!="symbol"?e+"":e,t);function w(n){if(n)return n;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function A(n){return n.replace(/\/+$/,"")}var H="X-Prodantix-Conversation-Token",E="prodantix.chat.handle";function M(){let n=globalThis.localStorage;if(n)return {get:e=>n.getItem(e),remove:e=>n.removeItem(e),set:(e,t)=>n.setItem(e,t)}}var f=class{constructor(e){this.options=e;l(this,"fetchImpl");l(this,"host");l(this,"storage");l(this,"handle");l(this,"identity",null);this.fetchImpl=w(e.fetchImpl),this.host=A(e.host),this.storage=e.storage??M(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(E,JSON.stringify(this.handle)),true)}async send(e){if(!await this.ensureThread())return null;let t=this.handle;return t?(await this.request("POST",`/v1/conversations/${encodeURIComponent(t.conversationId)}/turns`,{body:{body:e},token:t.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(E);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(E),null}async request(e,t,r={}){let i=this.fetchImpl;if(!i)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let a={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};r.token&&(a[H]=r.token);try{let s=await i(`${this.host}${t}`,{body:r.body===void 0?void 0:JSON.stringify(r.body),headers:a,method:e}),o=await s.text();return s.ok?o?JSON.parse(o):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${s.status}`)),null)}catch(s){return this.options.onError?.(s),null}}};var h={bubbleStyle:"tailed",launcherStyle:"circle_outlined",namePlacement:"avatar_only",skin:"concierge",timestampStyle:"cluster"},F=["concierge","console","quiet"],R=["avatar_circle","circle_filled","circle_outlined","pill_labelled","pill_team","squircle_filled"],$=["hairline","outlined","rounded","tailed"],K=["above","avatar_only","gutter","hidden","inline"],z=["cluster","latency","none","trailing","with_name"],b=(n,e,t)=>typeof n=="string"&&e.includes(n)?n:t;function y(n){let e={bubbleStyle:b(n?.bubbleStyle,$,h.bubbleStyle),launcherStyle:b(n?.launcherStyle,R,h.launcherStyle),namePlacement:b(n?.namePlacement,K,h.namePlacement),skin:b(n?.skin,F,h.skin),timestampStyle:b(n?.timestampStyle,z,h.timestampStyle)};return (e.namePlacement==="avatar_only"||e.namePlacement==="hidden")&&(e.timestampStyle==="with_name"||e.timestampStyle==="latency")&&(e.timestampStyle="trailing"),e.namePlacement==="inline"&&e.bubbleStyle==="hairline"&&(e.namePlacement="above"),e}var G={agentLabel:"Agent",aiLabel:"AI",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Open support chat",sendLabel:"Send",timeLabel:n=>{let e=new Date(n);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:n=>`${n} unread`},v={accentColor:"#5b5bff",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],...h},B={concierge:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}.composer{padding:12px 12px 14px;gap:8px}.composer input{border:0;background:var(--fill);height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",console:".panel{border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,.16)}.header{background:var(--paper);color:var(--ink);border-bottom:1px solid var(--hairline)}.close{color:var(--ink-2)}",quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{height:42px;padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.close{color:var(--ink-2)}"},D={avatar_circle:".launcher{width:60px;height:60px;border-radius:30px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2)}",circle_filled:".launcher{width:56px;height:56px;border-radius:28px;background:var(--a);color:#fff}",circle_outlined:".launcher{width:46px;height:46px;border-radius:23px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);font-size:21px}.badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;border-radius:10px;font-size:11.5px}",pill_labelled:".launcher{width:auto;height:52px;border-radius:26px;padding:0 22px;gap:10px;background:var(--a);color:#fff;font-size:14.5px;font-weight:600}",pill_team:".launcher{width:auto;height:54px;border-radius:27px;padding:0 20px 0 8px;gap:10px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink);font-size:14px;font-weight:600}.badge{position:static;background:var(--a)}",squircle_filled:".launcher{width:56px;height:56px;border-radius:16px;background:var(--a);color:#fff}"},q={hairline:".turn{max-width:100%;padding:13px 0;border-top:1px solid var(--hairline);background:none;border-radius:0}.log>.turn:first-child{border-top:0}.turn.end_user{align-self:stretch;display:flex;flex-direction:column;align-items:flex-end}.turn.end_user .body{background:var(--fill);color:var(--ink);border-radius:8px;padding:9px 12px;max-width:85%}",outlined:".turn{background:none;border:1px solid var(--hairline);border-radius:12px}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}",rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},U={above:"",avatar_only:".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}",gutter:".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".author{display:inline;margin-right:6px;font-weight:650}"},j={cluster:'.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',latency:".stamp{font-size:11px;opacity:.7;margin-left:6px}.lat{font-size:11px;opacity:.7;margin-left:6px}",none:"",trailing:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}",with_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}"};function N(n){let e=y(n),t=n.launcherPosition==="bottom_left"?"left":"right",r=n.accentColor;return `${`
|
|
2
|
+
:host {
|
|
3
|
+
all: initial; --a: ${r};
|
|
4
|
+
--paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
|
|
5
|
+
--fill: #f1f5f9; --hairline: #e2e8f0; --field: #cbd5e1; --ink-2: rgba(0,0,0,.72);
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
}
|
|
8
|
+
@media (prefers-color-scheme: dark) {
|
|
9
|
+
:host {
|
|
10
|
+
--paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
|
|
11
|
+
--fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --field: rgba(255,255,255,.22); --ink-2: rgba(255,255,255,.70);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
3
14
|
* { box-sizing: border-box; font-family: system-ui, sans-serif; }
|
|
4
15
|
.launcher {
|
|
5
|
-
position: fixed;
|
|
16
|
+
position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY}px; width: 56px; height: 56px;
|
|
6
17
|
border-radius: 28px; border: none; cursor: pointer;
|
|
7
|
-
|
|
18
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
19
|
+
background: ${r}; color: #fff; font-size: 24px;
|
|
8
20
|
box-shadow: 0 4px 12px rgba(0,0,0,.2);
|
|
9
21
|
}
|
|
10
22
|
.launcher:focus-visible { outline: 3px solid #0b0e14; outline-offset: 2px; }
|
|
@@ -14,8 +26,8 @@
|
|
|
14
26
|
display: flex; align-items: center; justify-content: center; padding: 0 4px;
|
|
15
27
|
}
|
|
16
28
|
.panel {
|
|
17
|
-
position: fixed;
|
|
18
|
-
height: 520px; max-height: calc(100vh - 120px); background:
|
|
29
|
+
position: fixed; ${t}: ${n.launcherOffsetX}px; bottom: ${n.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
|
|
30
|
+
height: 520px; max-height: calc(100vh - 120px); background: var(--paper); color: var(--ink);
|
|
19
31
|
border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.24);
|
|
20
32
|
display: flex; flex-direction: column; overflow: hidden;
|
|
21
33
|
}
|
|
@@ -25,17 +37,29 @@
|
|
|
25
37
|
.close:focus-visible { outline: 2px solid #fff; }
|
|
26
38
|
.log { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
|
|
27
39
|
.turn { max-width: 80%; padding: 8px 12px; border-radius: 12px; font-size: 14px; }
|
|
28
|
-
.turn.end_user { align-self: flex-end; background:
|
|
29
|
-
.turn.agent, .turn.ai { align-self: flex-start; background:
|
|
40
|
+
.turn.end_user { align-self: flex-end; background: ${r}; color: #fff; }
|
|
41
|
+
.turn.agent, .turn.ai { align-self: flex-start; background: var(--fill); color: var(--ink); }
|
|
30
42
|
.author { font-size: 11px; opacity: .7; margin-bottom: 2px; }
|
|
31
|
-
.
|
|
32
|
-
.
|
|
33
|
-
.
|
|
34
|
-
.
|
|
43
|
+
.empty { display: flex; flex-direction: column; gap: 8px; padding: 20px 16px; }
|
|
44
|
+
.empty h3 { margin: 0; font-size: 18px; font-weight: 640; letter-spacing: -.015em; }
|
|
45
|
+
.empty p { margin: 0 0 8px; font-size: 13.5px; color: var(--ink-2); }
|
|
46
|
+
.prompt {
|
|
47
|
+
display: flex; align-items: center; min-height: 44px; padding: 0 14px; text-align: left;
|
|
48
|
+
font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--ink);
|
|
49
|
+
background: none; border: 1px solid var(--hairline); border-radius: 8px; cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
.prompt:focus-visible { outline: 2px solid ${r}; outline-offset: 2px; }
|
|
52
|
+
.av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 650; color: #fff; background: #7c3f3f; }
|
|
53
|
+
.av.bot { border-radius: 9px; background: var(--fill); color: var(--ink); }
|
|
54
|
+
.composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--hairline); }
|
|
55
|
+
.composer input { flex: 1; padding: 8px 10px; border: 1px solid var(--field); border-radius: 8px; font-size: 14px; background: transparent; color: var(--ink); }
|
|
56
|
+
.composer input:focus-visible { outline: 2px solid ${r}; }
|
|
57
|
+
.composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${r}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
|
|
58
|
+
.composer button .sendglyph { display: none; width: 19px; height: 19px; }
|
|
35
59
|
.composer button:focus-visible { outline: 2px solid #0b0e14; }
|
|
36
60
|
@media (prefers-reduced-motion: no-preference) {
|
|
37
61
|
.panel { animation: rise 180ms ease-out; }
|
|
38
62
|
@keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
39
63
|
}
|
|
40
|
-
|
|
64
|
+
`}${B[e.skin]}${D[e.launcherStyle]}${q[e.bubbleStyle]}${U[e.namePlacement]}${j[e.timestampStyle]}`}var W=["end_user","agent","ai"],x=class{constructor(e,t,r={},i={}){this.host=e;this.client=t;l(this,"root");l(this,"strings");l(this,"settings");l(this,"appearance");l(this,"launcher");l(this,"badge");l(this,"panel",null);l(this,"lastFocused",null);l(this,"unread",0);this.strings={...G,...r},this.appearance={...v,...i},this.settings=y({...v,...i}),this.root=e.attachShadow({mode:"closed"});let a=document.createElement("style");a.textContent=N({...v,...i}),this.root.append(a),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.textContent="\u{1F4AC}",this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.launcher.append(this.badge),this.root.append(this.launcher);}toggle(){this.panel?this.close():this.open();}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className="panel",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let r=document.createElement("h2");r.textContent=this.strings.title;let i=document.createElement("button");i.className="close",i.type="button",i.setAttribute("aria-label",this.strings.closeLabel),i.textContent="\xD7",i.addEventListener("click",()=>this.close()),t.append(r,i);let a=document.createElement("div");a.className="log",a.setAttribute("role","log"),a.setAttribute("aria-live","polite"),a.setAttribute("aria-label",this.strings.title);let s=document.createElement("form");s.className="composer";let o=document.createElement("input");o.type="text",o.setAttribute("aria-label",this.strings.inputPlaceholder),o.placeholder=this.strings.inputPlaceholder;let p=document.createElement("button");p.type="submit",p.setAttribute("aria-label",this.strings.sendLabel),p.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let u=document.createElement("span");u.className="sendtext",u.textContent=this.strings.sendLabel,p.append(u),s.append(o,p),s.addEventListener("submit",g=>{g.preventDefault(),this.submit(o,a);}),e.append(t,a,s),e.addEventListener("keydown",g=>this.onKeydown(g,e,i)),this.root.append(e),this.panel=e,o.focus();let d=await this.client.load();d&&d.turns.length>0?this.renderThread(a,d):this.renderFirstRun(a,o);}renderFirstRun(e,t){let r=document.createElement("div");r.className="empty";let i=document.createElement("h3");i.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let a=document.createElement("p");a.textContent=this.strings.emptyBody,r.append(i,a);for(let s of this.appearance.starterPrompts){let o=document.createElement("button");o.className="prompt",o.type="button",o.textContent=s,o.addEventListener("click",()=>{t.value=s,this.submit(t,e);}),r.append(o);}e.replaceChildren(r);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let r=e.value.trim();if(!r)return;e.value="",t.querySelector(".empty")?.remove();let i=await this.client.send(r);i&&this.appendTurn(t,i);}renderThread(e,t){e.replaceChildren();for(let r of t.turns)this.appendTurn(e,r);}appendTurn(e,t){e.querySelector(".empty")?.remove();let r=W.includes(t.authorKind)?t.authorKind:"agent",i=this.settings,a=document.createElement("div");if(a.className=`turn ${r}`,r!=="end_user"&&(i.namePlacement==="avatar_only"||i.namePlacement==="gutter")){let d=document.createElement("span");d.className=r==="ai"?"av bot":"av",d.textContent=r==="ai"?this.strings.aiLabel:this.strings.agentLabel.slice(0,2).toUpperCase(),d.setAttribute("aria-hidden","true"),a.append(d);}let o=document.createElement("div");if(o.className="body",r!=="end_user"&&i.namePlacement!=="hidden"&&!(i.namePlacement==="avatar_only"&&r==="agent")||r==="ai"&&i.namePlacement==="hidden"){let d=document.createElement("div");d.className=r==="ai"?"author ai":"author",d.textContent=r==="ai"?this.strings.aiLabel:this.strings.agentLabel,(i.timestampStyle==="with_name"||i.timestampStyle==="latency")&&d.append(this.stamp(t)),o.append(d);}let u=document.createElement("div");u.textContent=t.body,o.append(u),i.timestampStyle==="trailing"&&o.append(this.stamp(t)),a.append(o),e.append(a),e.scrollTop=e.scrollHeight;}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,r){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let i=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(i.length===0)return;let a=i[0],s=i[i.length-1],o=this.root.activeElement;e.shiftKey&&o===a?(e.preventDefault(),s.focus()):!e.shiftKey&&o===s?(e.preventDefault(),a.focus()):o===null&&(e.preventDefault(),r.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function _(n){return `40${JSON.stringify(n)}`}function P(){return "3"}function L(n){let e=n.charAt(0),t=n.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let s=T(t);return {kind:"open",pingInterval:typeof s?.pingInterval=="number"?s.pingInterval:25e3,pingTimeout:typeof s?.pingTimeout=="number"?s.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let r=t.charAt(0),i=t.slice(1);if(r==="0")return {kind:"connected"};if(r==="1")return {kind:"disconnect"};if(r==="4"){let s=T(i);return {kind:"connectError",message:typeof s?.message=="string"?s.message:"refused"}}if(r!=="2")return {kind:"other"};let a=T(i);return !Array.isArray(a)||typeof a[0]!="string"?{kind:"other"}:{kind:"event",name:a[0],payload:a[1]}}function T(n){try{return JSON.parse(n)}catch{return null}}var Y="/socket.io/?EIO=4&transport=websocket",k=class{constructor(e){this.options=e;l(this,"socket",null);l(this,"heartbeat",null);l(this,"ready",false);l(this,"closed",false);l(this,"heartbeatWindow",45e3);l(this,"factory");l(this,"setTimer");l(this,"clearTimer");this.factory=e.socketFactory??J,this.setTimer=e.setTimer??((t,r)=>setTimeout(t,r)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${Y}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=r=>this.receive(String(r.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=L(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(_(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(P());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let r=t.payload?.turn;r&&this.options.onTurn(r);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function J(n){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(n)}function ue(n){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=n.mountPoint??e.createElement("div");n.mountPoint||e.body.append(t);let r=new f(n),i=new x(t,r,n.strings,n.appearance),a=new Set,s,o=null,p=n.pollIntervalMs??15e3,u=c=>{a.has(c.id)||c.authorKind==="end_user"||(a.add(c.id),i.onIncomingTurn(c));},d=async()=>{if(!r.hasThread)return;let c=await r.load();if(c){for(let m of c.turns)u(m);a=new Set(c.turns.map(m=>m.id));}},g=()=>{s||p<=0||(s=setInterval(()=>void d(),p));},C=()=>{s&&clearInterval(s),s=void 0;},S=()=>{if(o||!n.socketHost)return;let c=r.socketAuth;c&&(o=new k({auth:c,host:n.socketHost,onClosed:m=>{o=null,g(),m&&S();},onReady:C,onTurn:u,socketFactory:n.socketFactory}),o.open());};return g(),S(),{close:()=>i.close(),destroy:()=>{C(),o?.close(),o=null,i.close(),t.remove();},identify:c=>r.identify(c),open:()=>{i.open().then(S);}}}exports.ChatClient=f;exports.ChatPanel=x;exports.DEFAULT_APPEARANCE=v;exports.DEFAULT_APPEARANCE_SETTINGS=h;exports.mountChat=ue;exports.panelStyles=N;exports.resolveAppearance=y;//# sourceMappingURL=chat.cjs.map
|
|
41
65
|
//# sourceMappingURL=chat.cjs.map
|
package/dist/chat.d.cts
CHANGED
|
@@ -1,44 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
id: string;
|
|
5
|
-
authorKind: 'end_user' | 'agent' | 'ai';
|
|
6
|
-
authorId: string | null;
|
|
7
|
-
body: string;
|
|
8
|
-
createdAt: string;
|
|
9
|
-
}
|
|
10
|
-
interface ChatThread {
|
|
11
|
-
id: string;
|
|
12
|
-
status: string;
|
|
13
|
-
turns: ChatTurn[];
|
|
14
|
-
}
|
|
15
|
-
interface ChatClientOptions {
|
|
16
|
-
apiKey: string;
|
|
17
|
-
host: string;
|
|
18
|
-
distinctId: string;
|
|
19
|
-
storage?: ChatStorage;
|
|
20
|
-
fetchImpl?: FetchLike;
|
|
21
|
-
onError?: (error: unknown) => void;
|
|
22
|
-
}
|
|
23
|
-
interface ChatStorage {
|
|
24
|
-
get(key: string): string | null;
|
|
25
|
-
set(key: string, value: string): void;
|
|
26
|
-
remove(key: string): void;
|
|
27
|
-
}
|
|
28
|
-
declare class ChatClient {
|
|
29
|
-
private readonly options;
|
|
30
|
-
private readonly fetchImpl?;
|
|
31
|
-
private readonly host;
|
|
32
|
-
private readonly storage?;
|
|
33
|
-
private handle;
|
|
34
|
-
constructor(options: ChatClientOptions);
|
|
35
|
-
get hasThread(): boolean;
|
|
36
|
-
ensureThread(subject?: string): Promise<boolean>;
|
|
37
|
-
send(body: string): Promise<ChatTurn | null>;
|
|
38
|
-
load(): Promise<ChatThread | null>;
|
|
39
|
-
private readHandle;
|
|
40
|
-
private request;
|
|
41
|
-
}
|
|
1
|
+
import { C as ChatClient, M as MessengerConfig, A as AppearanceSettings, a as ChatTurn, b as ChatIdentity, c as ChatClientOptions } from './config-OP9Csae6.cjs';
|
|
2
|
+
export { B as BubbleStyle, d as ChatStorage, e as ChatThread, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherStyle, f as MessengerSkin, N as NamePlacement, T as TimestampStyle, r as resolveAppearance } from './config-OP9Csae6.cjs';
|
|
3
|
+
import './http-BCh716Vs.cjs';
|
|
42
4
|
|
|
43
5
|
interface ChatStrings {
|
|
44
6
|
launcherLabel: string;
|
|
@@ -49,39 +11,65 @@ interface ChatStrings {
|
|
|
49
11
|
agentLabel: string;
|
|
50
12
|
aiLabel: string;
|
|
51
13
|
unreadLabel: (count: number) => string;
|
|
14
|
+
timeLabel: (createdAt: string) => string;
|
|
15
|
+
emptyTitle: string;
|
|
16
|
+
emptyBody: string;
|
|
52
17
|
}
|
|
18
|
+
type MessengerAppearance = Pick<MessengerConfig, 'accentColor' | 'greeting' | 'launcherOffsetX' | 'launcherOffsetY' | 'launcherPosition' | 'starterPrompts'> & AppearanceSettings;
|
|
19
|
+
declare const DEFAULT_APPEARANCE: MessengerAppearance;
|
|
20
|
+
declare function panelStyles(appearance: MessengerAppearance): string;
|
|
53
21
|
declare class ChatPanel {
|
|
54
22
|
private readonly host;
|
|
55
23
|
private readonly client;
|
|
56
24
|
private readonly root;
|
|
57
25
|
private readonly strings;
|
|
26
|
+
private readonly settings;
|
|
27
|
+
private readonly appearance;
|
|
58
28
|
private readonly launcher;
|
|
59
29
|
private readonly badge;
|
|
60
30
|
private panel;
|
|
61
31
|
private lastFocused;
|
|
62
32
|
private unread;
|
|
63
|
-
constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>);
|
|
33
|
+
constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>);
|
|
64
34
|
private toggle;
|
|
65
35
|
open(): Promise<void>;
|
|
36
|
+
private renderFirstRun;
|
|
66
37
|
close(): void;
|
|
67
38
|
onIncomingTurn(turn: ChatTurn): void;
|
|
68
39
|
private submit;
|
|
69
40
|
private renderThread;
|
|
70
41
|
private appendTurn;
|
|
42
|
+
private stamp;
|
|
71
43
|
private onKeydown;
|
|
72
44
|
private renderBadge;
|
|
73
45
|
}
|
|
74
46
|
|
|
47
|
+
interface SocketLike {
|
|
48
|
+
send(data: string): void;
|
|
49
|
+
close(): void;
|
|
50
|
+
onopen: (() => void) | null;
|
|
51
|
+
onclose: (() => void) | null;
|
|
52
|
+
onerror: (() => void) | null;
|
|
53
|
+
onmessage: ((event: {
|
|
54
|
+
data: string;
|
|
55
|
+
}) => void) | null;
|
|
56
|
+
}
|
|
57
|
+
type SocketFactory = (url: string) => SocketLike;
|
|
58
|
+
|
|
75
59
|
interface MountChatOptions extends ChatClientOptions {
|
|
76
60
|
mountPoint?: HTMLElement;
|
|
77
61
|
strings?: Partial<ChatStrings>;
|
|
62
|
+
appearance?: Partial<MessengerAppearance>;
|
|
78
63
|
pollIntervalMs?: number;
|
|
64
|
+
socketHost?: string;
|
|
65
|
+
socketFactory?: SocketFactory;
|
|
79
66
|
}
|
|
80
67
|
interface ChatHandle {
|
|
81
68
|
open(): void;
|
|
82
69
|
close(): void;
|
|
83
70
|
destroy(): void;
|
|
71
|
+
identify(identity: ChatIdentity): void;
|
|
84
72
|
}
|
|
85
73
|
declare function mountChat(options: MountChatOptions): ChatHandle;
|
|
86
74
|
|
|
87
|
-
export { ChatClient,
|
|
75
|
+
export { AppearanceSettings, ChatClient, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,44 +1,6 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
id: string;
|
|
5
|
-
authorKind: 'end_user' | 'agent' | 'ai';
|
|
6
|
-
authorId: string | null;
|
|
7
|
-
body: string;
|
|
8
|
-
createdAt: string;
|
|
9
|
-
}
|
|
10
|
-
interface ChatThread {
|
|
11
|
-
id: string;
|
|
12
|
-
status: string;
|
|
13
|
-
turns: ChatTurn[];
|
|
14
|
-
}
|
|
15
|
-
interface ChatClientOptions {
|
|
16
|
-
apiKey: string;
|
|
17
|
-
host: string;
|
|
18
|
-
distinctId: string;
|
|
19
|
-
storage?: ChatStorage;
|
|
20
|
-
fetchImpl?: FetchLike;
|
|
21
|
-
onError?: (error: unknown) => void;
|
|
22
|
-
}
|
|
23
|
-
interface ChatStorage {
|
|
24
|
-
get(key: string): string | null;
|
|
25
|
-
set(key: string, value: string): void;
|
|
26
|
-
remove(key: string): void;
|
|
27
|
-
}
|
|
28
|
-
declare class ChatClient {
|
|
29
|
-
private readonly options;
|
|
30
|
-
private readonly fetchImpl?;
|
|
31
|
-
private readonly host;
|
|
32
|
-
private readonly storage?;
|
|
33
|
-
private handle;
|
|
34
|
-
constructor(options: ChatClientOptions);
|
|
35
|
-
get hasThread(): boolean;
|
|
36
|
-
ensureThread(subject?: string): Promise<boolean>;
|
|
37
|
-
send(body: string): Promise<ChatTurn | null>;
|
|
38
|
-
load(): Promise<ChatThread | null>;
|
|
39
|
-
private readHandle;
|
|
40
|
-
private request;
|
|
41
|
-
}
|
|
1
|
+
import { C as ChatClient, M as MessengerConfig, A as AppearanceSettings, a as ChatTurn, b as ChatIdentity, c as ChatClientOptions } from './config-B-cTz9n1.js';
|
|
2
|
+
export { B as BubbleStyle, d as ChatStorage, e as ChatThread, D as DEFAULT_APPEARANCE_SETTINGS, L as LauncherStyle, f as MessengerSkin, N as NamePlacement, T as TimestampStyle, r as resolveAppearance } from './config-B-cTz9n1.js';
|
|
3
|
+
import './http-BCh716Vs.js';
|
|
42
4
|
|
|
43
5
|
interface ChatStrings {
|
|
44
6
|
launcherLabel: string;
|
|
@@ -49,39 +11,65 @@ interface ChatStrings {
|
|
|
49
11
|
agentLabel: string;
|
|
50
12
|
aiLabel: string;
|
|
51
13
|
unreadLabel: (count: number) => string;
|
|
14
|
+
timeLabel: (createdAt: string) => string;
|
|
15
|
+
emptyTitle: string;
|
|
16
|
+
emptyBody: string;
|
|
52
17
|
}
|
|
18
|
+
type MessengerAppearance = Pick<MessengerConfig, 'accentColor' | 'greeting' | 'launcherOffsetX' | 'launcherOffsetY' | 'launcherPosition' | 'starterPrompts'> & AppearanceSettings;
|
|
19
|
+
declare const DEFAULT_APPEARANCE: MessengerAppearance;
|
|
20
|
+
declare function panelStyles(appearance: MessengerAppearance): string;
|
|
53
21
|
declare class ChatPanel {
|
|
54
22
|
private readonly host;
|
|
55
23
|
private readonly client;
|
|
56
24
|
private readonly root;
|
|
57
25
|
private readonly strings;
|
|
26
|
+
private readonly settings;
|
|
27
|
+
private readonly appearance;
|
|
58
28
|
private readonly launcher;
|
|
59
29
|
private readonly badge;
|
|
60
30
|
private panel;
|
|
61
31
|
private lastFocused;
|
|
62
32
|
private unread;
|
|
63
|
-
constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>);
|
|
33
|
+
constructor(host: HTMLElement, client: ChatClient, strings?: Partial<ChatStrings>, appearance?: Partial<MessengerAppearance>);
|
|
64
34
|
private toggle;
|
|
65
35
|
open(): Promise<void>;
|
|
36
|
+
private renderFirstRun;
|
|
66
37
|
close(): void;
|
|
67
38
|
onIncomingTurn(turn: ChatTurn): void;
|
|
68
39
|
private submit;
|
|
69
40
|
private renderThread;
|
|
70
41
|
private appendTurn;
|
|
42
|
+
private stamp;
|
|
71
43
|
private onKeydown;
|
|
72
44
|
private renderBadge;
|
|
73
45
|
}
|
|
74
46
|
|
|
47
|
+
interface SocketLike {
|
|
48
|
+
send(data: string): void;
|
|
49
|
+
close(): void;
|
|
50
|
+
onopen: (() => void) | null;
|
|
51
|
+
onclose: (() => void) | null;
|
|
52
|
+
onerror: (() => void) | null;
|
|
53
|
+
onmessage: ((event: {
|
|
54
|
+
data: string;
|
|
55
|
+
}) => void) | null;
|
|
56
|
+
}
|
|
57
|
+
type SocketFactory = (url: string) => SocketLike;
|
|
58
|
+
|
|
75
59
|
interface MountChatOptions extends ChatClientOptions {
|
|
76
60
|
mountPoint?: HTMLElement;
|
|
77
61
|
strings?: Partial<ChatStrings>;
|
|
62
|
+
appearance?: Partial<MessengerAppearance>;
|
|
78
63
|
pollIntervalMs?: number;
|
|
64
|
+
socketHost?: string;
|
|
65
|
+
socketFactory?: SocketFactory;
|
|
79
66
|
}
|
|
80
67
|
interface ChatHandle {
|
|
81
68
|
open(): void;
|
|
82
69
|
close(): void;
|
|
83
70
|
destroy(): void;
|
|
71
|
+
identify(identity: ChatIdentity): void;
|
|
84
72
|
}
|
|
85
73
|
declare function mountChat(options: MountChatOptions): ChatHandle;
|
|
86
74
|
|
|
87
|
-
export { ChatClient,
|
|
75
|
+
export { AppearanceSettings, ChatClient, ChatClientOptions, type ChatHandle, ChatIdentity, ChatPanel, type ChatStrings, ChatTurn, DEFAULT_APPEARANCE, type MessengerAppearance, type MountChatOptions, mountChat, panelStyles };
|
package/dist/chat.js
CHANGED
|
@@ -1,10 +1,22 @@
|
|
|
1
|
-
import {a
|
|
2
|
-
:host {
|
|
1
|
+
import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var L="X-Prodantix-Conversation-Token",E="prodantix.chat.handle";function O(){let r=globalThis.localStorage;if(r)return {get:e=>r.getItem(e),remove:e=>r.removeItem(e),set:(e,t)=>r.setItem(e,t)}}var f=class{constructor(e){this.options=e;a(this,"fetchImpl");a(this,"host");a(this,"storage");a(this,"handle");a(this,"identity",null);this.fetchImpl=a$1(e.fetchImpl),this.host=d(e.host),this.storage=e.storage??O(),this.handle=this.readHandle();}get hasThread(){return this.handle!==null}get socketAuth(){return this.handle?{conversationId:this.handle.conversationId,conversationToken:this.handle.token,projectKey:this.options.apiKey}:null}identify(e){this.identity=e;}async ensureThread(e){if(this.handle)return true;let t=await this.request("POST","/v1/conversations",{body:{distinctId:this.options.distinctId,subject:e,userHash:this.identity?.userHash,userId:this.identity?.userId}});return !t?.conversationId||!t.token?false:(this.handle={conversationId:t.conversationId,token:t.token},this.storage?.set(E,JSON.stringify(this.handle)),true)}async send(e){if(!await this.ensureThread())return null;let t=this.handle;return t?(await this.request("POST",`/v1/conversations/${encodeURIComponent(t.conversationId)}/turns`,{body:{body:e},token:t.token}))?.turn??null:null}async load(){let e=this.handle;return e?this.request("GET",`/v1/conversations/${encodeURIComponent(e.conversationId)}`,{token:e.token}):null}readHandle(){let e=this.storage?.get(E);if(!e)return null;try{let t=JSON.parse(e);if(typeof t.conversationId=="string"&&typeof t.token=="string")return {conversationId:t.conversationId,token:t.token}}catch{}return this.storage?.remove(E),null}async request(e,t,n={}){let i=this.fetchImpl;if(!i)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let a={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};n.token&&(a[L]=n.token);try{let s=await i(`${this.host}${t}`,{body:n.body===void 0?void 0:JSON.stringify(n.body),headers:a,method:e}),o=await s.text();return s.ok?o?JSON.parse(o):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${s.status}`)),null)}catch(s){return this.options.onError?.(s),null}}};var h={bubbleStyle:"tailed",launcherStyle:"circle_outlined",namePlacement:"avatar_only",skin:"concierge",timestampStyle:"cluster"},H=["concierge","console","quiet"],M=["avatar_circle","circle_filled","circle_outlined","pill_labelled","pill_team","squircle_filled"],$=["hairline","outlined","rounded","tailed"],R=["above","avatar_only","gutter","hidden","inline"],K=["cluster","latency","none","trailing","with_name"],b=(r,e,t)=>typeof r=="string"&&e.includes(r)?r:t;function y(r){let e={bubbleStyle:b(r?.bubbleStyle,$,h.bubbleStyle),launcherStyle:b(r?.launcherStyle,M,h.launcherStyle),namePlacement:b(r?.namePlacement,R,h.namePlacement),skin:b(r?.skin,H,h.skin),timestampStyle:b(r?.timestampStyle,K,h.timestampStyle)};return (e.namePlacement==="avatar_only"||e.namePlacement==="hidden")&&(e.timestampStyle==="with_name"||e.timestampStyle==="latency")&&(e.timestampStyle="trailing"),e.namePlacement==="inline"&&e.bubbleStyle==="hairline"&&(e.namePlacement="above"),e}var F={agentLabel:"Agent",aiLabel:"AI",closeLabel:"Close chat",emptyBody:"We usually reply within a few minutes.",emptyTitle:"Ask us anything.",inputPlaceholder:"Type a message",launcherLabel:"Open support chat",sendLabel:"Send",timeLabel:r=>{let e=new Date(r);return Number.isNaN(e.getTime())?"":`${String(e.getHours()).padStart(2,"0")}:${String(e.getMinutes()).padStart(2,"0")}`},title:"Support",unreadLabel:r=>`${r} unread`},v={accentColor:"#5b5bff",greeting:"",launcherOffsetX:20,launcherOffsetY:20,launcherPosition:"bottom_right",starterPrompts:[],...h},z={concierge:".panel{border-radius:16px;box-shadow:0 16px 40px rgba(0,0,0,.2)}.header{background:var(--a);color:#fff;flex-direction:column;align-items:flex-start;gap:14px;padding:18px 14px 20px 20px}.header h2{font-size:19px;font-weight:640}.composer{padding:12px 12px 14px;gap:8px}.composer input{border:0;background:var(--fill);height:46px;border-radius:23px;padding:0 16px}.composer button{width:46px;min-width:46px;height:46px;padding:0;border-radius:23px}.composer button .sendglyph{display:block}.composer button .sendtext{display:none}",console:".panel{border-radius:12px;box-shadow:0 8px 24px rgba(0,0,0,.16)}.header{background:var(--paper);color:var(--ink);border-bottom:1px solid var(--hairline)}.close{color:var(--ink-2)}",quiet:".composer{position:relative;padding:10px 12px 12px}.composer input{height:42px;padding-right:42px}.composer button{position:absolute;top:50%;right:16px;width:34px;min-width:34px;height:34px;padding:0;background:transparent;color:var(--ink);border-radius:7px;transform:translateY(-50%)}.composer button .sendglyph{display:block;width:18px;height:18px}.composer button .sendtext{display:none}.panel{border-radius:8px;box-shadow:0 2px 8px rgba(0,0,0,.12)}.header{background:var(--paper);color:var(--ink);height:44px;padding:0 8px 0 16px;border-bottom:1px solid var(--hairline)}.header h2{font-size:11px;letter-spacing:.11em;text-transform:uppercase;color:var(--ink-3)}.close{color:var(--ink-2)}"},G={avatar_circle:".launcher{width:60px;height:60px;border-radius:30px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2)}",circle_filled:".launcher{width:56px;height:56px;border-radius:28px;background:var(--a);color:#fff}",circle_outlined:".launcher{width:46px;height:46px;border-radius:23px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink-2);box-shadow:0 1px 2px rgba(0,0,0,.08);font-size:21px}.badge{background:var(--a);top:-7px;right:-7px;min-width:19px;height:19px;border-radius:10px;font-size:11.5px}",pill_labelled:".launcher{width:auto;height:52px;border-radius:26px;padding:0 22px;gap:10px;background:var(--a);color:#fff;font-size:14.5px;font-weight:600}",pill_team:".launcher{width:auto;height:54px;border-radius:27px;padding:0 20px 0 8px;gap:10px;background:var(--paper);border:1px solid var(--hairline);color:var(--ink);font-size:14px;font-weight:600}.badge{position:static;background:var(--a)}",squircle_filled:".launcher{width:56px;height:56px;border-radius:16px;background:var(--a);color:#fff}"},B={hairline:".turn{max-width:100%;padding:13px 0;border-top:1px solid var(--hairline);background:none;border-radius:0}.log>.turn:first-child{border-top:0}.turn.end_user{align-self:stretch;display:flex;flex-direction:column;align-items:flex-end}.turn.end_user .body{background:var(--fill);color:var(--ink);border-radius:8px;padding:9px 12px;max-width:85%}",outlined:".turn{background:none;border:1px solid var(--hairline);border-radius:12px}.turn.end_user{background:none;border-color:var(--a);color:var(--ink)}",rounded:".turn{border-radius:18px;padding:10px 15px}",tailed:".turn.agent,.turn.ai{border-radius:12px 12px 12px 4px}.turn.end_user{border-radius:12px 12px 4px 12px}"},D={above:"",avatar_only:".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}",gutter:".turn.agent,.turn.ai{display:flex;gap:10px;max-width:100%;background:none;padding:0}.turn .body{background:var(--fill);padding:9px 13px;border-radius:inherit}.author{text-transform:none;letter-spacing:0;font-size:12.5px;font-weight:600;opacity:1}",hidden:".turn.agent .author,.turn.ai .author:not(.ai){display:none}",inline:".author{display:inline;margin-right:6px;font-weight:650}"},q={cluster:'.divider{display:flex;align-items:center;gap:10px;margin:0;font-size:11px;opacity:.6}.divider:before,.divider:after{content:"";flex:1;height:1px;background:var(--hairline)}',latency:".stamp{font-size:11px;opacity:.7;margin-left:6px}.lat{font-size:11px;opacity:.7;margin-left:6px}",none:"",trailing:".stamp{display:block;font-size:11px;opacity:.7;margin-top:4px}.turn.end_user .stamp{text-align:right}",with_name:".stamp{font-size:11px;opacity:.7;margin-left:6px}"};function N(r){let e=y(r),t=r.launcherPosition==="bottom_left"?"left":"right",n=r.accentColor;return `${`
|
|
2
|
+
:host {
|
|
3
|
+
all: initial; --a: ${n};
|
|
4
|
+
--paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
|
|
5
|
+
--fill: #f1f5f9; --hairline: #e2e8f0; --field: #cbd5e1; --ink-2: rgba(0,0,0,.72);
|
|
6
|
+
color-scheme: light dark;
|
|
7
|
+
}
|
|
8
|
+
@media (prefers-color-scheme: dark) {
|
|
9
|
+
:host {
|
|
10
|
+
--paper: oklch(24.6% 0.015 257); --ink: #fff; --ink-3: rgba(255,255,255,.55);
|
|
11
|
+
--fill: rgba(255,255,255,.06); --hairline: rgba(255,255,255,.13); --field: rgba(255,255,255,.22); --ink-2: rgba(255,255,255,.70);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
3
14
|
* { box-sizing: border-box; font-family: system-ui, sans-serif; }
|
|
4
15
|
.launcher {
|
|
5
|
-
position: fixed;
|
|
16
|
+
position: fixed; ${t}: ${r.launcherOffsetX}px; bottom: ${r.launcherOffsetY}px; width: 56px; height: 56px;
|
|
6
17
|
border-radius: 28px; border: none; cursor: pointer;
|
|
7
|
-
|
|
18
|
+
display: inline-flex; align-items: center; justify-content: center;
|
|
19
|
+
background: ${n}; color: #fff; font-size: 24px;
|
|
8
20
|
box-shadow: 0 4px 12px rgba(0,0,0,.2);
|
|
9
21
|
}
|
|
10
22
|
.launcher:focus-visible { outline: 3px solid #0b0e14; outline-offset: 2px; }
|
|
@@ -14,8 +26,8 @@ import {a,b as b$1,e}from'./chunk-STIKBPFF.js';var b="X-Prodantix-Conversation-T
|
|
|
14
26
|
display: flex; align-items: center; justify-content: center; padding: 0 4px;
|
|
15
27
|
}
|
|
16
28
|
.panel {
|
|
17
|
-
position: fixed;
|
|
18
|
-
height: 520px; max-height: calc(100vh - 120px); background:
|
|
29
|
+
position: fixed; ${t}: ${r.launcherOffsetX}px; bottom: ${r.launcherOffsetY+68}px; width: 360px; max-width: calc(100vw - 40px);
|
|
30
|
+
height: 520px; max-height: calc(100vh - 120px); background: var(--paper); color: var(--ink);
|
|
19
31
|
border-radius: 12px; box-shadow: 0 8px 32px rgba(0,0,0,.24);
|
|
20
32
|
display: flex; flex-direction: column; overflow: hidden;
|
|
21
33
|
}
|
|
@@ -25,17 +37,29 @@ import {a,b as b$1,e}from'./chunk-STIKBPFF.js';var b="X-Prodantix-Conversation-T
|
|
|
25
37
|
.close:focus-visible { outline: 2px solid #fff; }
|
|
26
38
|
.log { flex: 1; overflow-y: auto; padding: 12px; display: flex; flex-direction: column; gap: 8px; }
|
|
27
39
|
.turn { max-width: 80%; padding: 8px 12px; border-radius: 12px; font-size: 14px; }
|
|
28
|
-
.turn.end_user { align-self: flex-end; background:
|
|
29
|
-
.turn.agent, .turn.ai { align-self: flex-start; background:
|
|
40
|
+
.turn.end_user { align-self: flex-end; background: ${n}; color: #fff; }
|
|
41
|
+
.turn.agent, .turn.ai { align-self: flex-start; background: var(--fill); color: var(--ink); }
|
|
30
42
|
.author { font-size: 11px; opacity: .7; margin-bottom: 2px; }
|
|
31
|
-
.
|
|
32
|
-
.
|
|
33
|
-
.
|
|
34
|
-
.
|
|
43
|
+
.empty { display: flex; flex-direction: column; gap: 8px; padding: 20px 16px; }
|
|
44
|
+
.empty h3 { margin: 0; font-size: 18px; font-weight: 640; letter-spacing: -.015em; }
|
|
45
|
+
.empty p { margin: 0 0 8px; font-size: 13.5px; color: var(--ink-2); }
|
|
46
|
+
.prompt {
|
|
47
|
+
display: flex; align-items: center; min-height: 44px; padding: 0 14px; text-align: left;
|
|
48
|
+
font-family: inherit; font-size: 13.5px; font-weight: 500; color: var(--ink);
|
|
49
|
+
background: none; border: 1px solid var(--hairline); border-radius: 8px; cursor: pointer;
|
|
50
|
+
}
|
|
51
|
+
.prompt:focus-visible { outline: 2px solid ${n}; outline-offset: 2px; }
|
|
52
|
+
.av { width: 30px; height: 30px; border-radius: 50%; flex: none; display: inline-flex; align-items: center; justify-content: center; font-size: 11.5px; font-weight: 650; color: #fff; background: #7c3f3f; }
|
|
53
|
+
.av.bot { border-radius: 9px; background: var(--fill); color: var(--ink); }
|
|
54
|
+
.composer { display: flex; gap: 8px; padding: 12px; border-top: 1px solid var(--hairline); }
|
|
55
|
+
.composer input { flex: 1; padding: 8px 10px; border: 1px solid var(--field); border-radius: 8px; font-size: 14px; background: transparent; color: var(--ink); }
|
|
56
|
+
.composer input:focus-visible { outline: 2px solid ${n}; }
|
|
57
|
+
.composer button { display: inline-flex; align-items: center; justify-content: center; gap: 0; min-width: 64px; height: 44px; padding: 0 16px; background: ${n}; color: #fff; border: none; border-radius: 8px; cursor: pointer; font-family: inherit; font-size: 14.5px; font-weight: 550; }
|
|
58
|
+
.composer button .sendglyph { display: none; width: 19px; height: 19px; }
|
|
35
59
|
.composer button:focus-visible { outline: 2px solid #0b0e14; }
|
|
36
60
|
@media (prefers-reduced-motion: no-preference) {
|
|
37
61
|
.panel { animation: rise 180ms ease-out; }
|
|
38
62
|
@keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
39
63
|
}
|
|
40
|
-
|
|
64
|
+
`}${z[e.skin]}${G[e.launcherStyle]}${B[e.bubbleStyle]}${D[e.namePlacement]}${q[e.timestampStyle]}`}var U=["end_user","agent","ai"],x=class{constructor(e,t,n={},i={}){this.host=e;this.client=t;a(this,"root");a(this,"strings");a(this,"settings");a(this,"appearance");a(this,"launcher");a(this,"badge");a(this,"panel",null);a(this,"lastFocused",null);a(this,"unread",0);this.strings={...F,...n},this.appearance={...v,...i},this.settings=y({...v,...i}),this.root=e.attachShadow({mode:"closed"});let a$1=document.createElement("style");a$1.textContent=N({...v,...i}),this.root.append(a$1),this.launcher=document.createElement("button"),this.launcher.className="launcher",this.launcher.type="button",this.launcher.setAttribute("aria-haspopup","dialog"),this.launcher.setAttribute("aria-label",this.strings.launcherLabel),this.launcher.textContent="\u{1F4AC}",this.launcher.addEventListener("click",()=>this.toggle()),this.badge=document.createElement("span"),this.badge.className="badge",this.badge.hidden=true,this.launcher.append(this.badge),this.root.append(this.launcher);}toggle(){this.panel?this.close():this.open();}async open(){if(this.panel)return;this.lastFocused=this.host.ownerDocument.activeElement,this.unread=0,this.renderBadge();let e=document.createElement("section");e.className="panel",e.setAttribute("role","dialog"),e.setAttribute("aria-modal","true"),e.setAttribute("aria-label",this.strings.title);let t=document.createElement("div");t.className="header";let n=document.createElement("h2");n.textContent=this.strings.title;let i=document.createElement("button");i.className="close",i.type="button",i.setAttribute("aria-label",this.strings.closeLabel),i.textContent="\xD7",i.addEventListener("click",()=>this.close()),t.append(n,i);let a=document.createElement("div");a.className="log",a.setAttribute("role","log"),a.setAttribute("aria-live","polite"),a.setAttribute("aria-label",this.strings.title);let s=document.createElement("form");s.className="composer";let o=document.createElement("input");o.type="text",o.setAttribute("aria-label",this.strings.inputPlaceholder),o.placeholder=this.strings.inputPlaceholder;let p=document.createElement("button");p.type="submit",p.setAttribute("aria-label",this.strings.sendLabel),p.innerHTML='<svg class="sendglyph" aria-hidden="true" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M4.5 12 20 4.5 15 20l-3.6-5.4L4.5 12Z"/></svg>';let u=document.createElement("span");u.className="sendtext",u.textContent=this.strings.sendLabel,p.append(u),s.append(o,p),s.addEventListener("submit",g=>{g.preventDefault(),this.submit(o,a);}),e.append(t,a,s),e.addEventListener("keydown",g=>this.onKeydown(g,e,i)),this.root.append(e),this.panel=e,o.focus();let d=await this.client.load();d&&d.turns.length>0?this.renderThread(a,d):this.renderFirstRun(a,o);}renderFirstRun(e,t){let n=document.createElement("div");n.className="empty";let i=document.createElement("h3");i.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let a=document.createElement("p");a.textContent=this.strings.emptyBody,n.append(i,a);for(let s of this.appearance.starterPrompts){let o=document.createElement("button");o.className="prompt",o.type="button",o.textContent=s,o.addEventListener("click",()=>{t.value=s,this.submit(t,e);}),n.append(o);}e.replaceChildren(n);}close(){this.panel&&(this.panel.remove(),this.panel=null,this.lastFocused instanceof HTMLElement?this.lastFocused.focus():this.launcher.focus());}onIncomingTurn(e){if(this.panel){let t=this.panel.querySelector(".log");t instanceof HTMLElement&&this.appendTurn(t,e);return}e.authorKind!=="end_user"&&(this.unread+=1,this.renderBadge());}async submit(e,t){let n=e.value.trim();if(!n)return;e.value="",t.querySelector(".empty")?.remove();let i=await this.client.send(n);i&&this.appendTurn(t,i);}renderThread(e,t){e.replaceChildren();for(let n of t.turns)this.appendTurn(e,n);}appendTurn(e,t){e.querySelector(".empty")?.remove();let n=U.includes(t.authorKind)?t.authorKind:"agent",i=this.settings,a=document.createElement("div");if(a.className=`turn ${n}`,n!=="end_user"&&(i.namePlacement==="avatar_only"||i.namePlacement==="gutter")){let d=document.createElement("span");d.className=n==="ai"?"av bot":"av",d.textContent=n==="ai"?this.strings.aiLabel:this.strings.agentLabel.slice(0,2).toUpperCase(),d.setAttribute("aria-hidden","true"),a.append(d);}let o=document.createElement("div");if(o.className="body",n!=="end_user"&&i.namePlacement!=="hidden"&&!(i.namePlacement==="avatar_only"&&n==="agent")||n==="ai"&&i.namePlacement==="hidden"){let d=document.createElement("div");d.className=n==="ai"?"author ai":"author",d.textContent=n==="ai"?this.strings.aiLabel:this.strings.agentLabel,(i.timestampStyle==="with_name"||i.timestampStyle==="latency")&&d.append(this.stamp(t)),o.append(d);}let u=document.createElement("div");u.textContent=t.body,o.append(u),i.timestampStyle==="trailing"&&o.append(this.stamp(t)),a.append(o),e.append(a),e.scrollTop=e.scrollHeight;}stamp(e){let t=document.createElement("span");return t.className="stamp",t.textContent=this.strings.timeLabel(e.createdAt),t}onKeydown(e,t,n){if(e.key==="Escape"){e.preventDefault(),this.close();return}if(e.key!=="Tab")return;let i=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(i.length===0)return;let a=i[0],s=i[i.length-1],o=this.root.activeElement;e.shiftKey&&o===a?(e.preventDefault(),s.focus()):!e.shiftKey&&o===s?(e.preventDefault(),a.focus()):o===null&&(e.preventDefault(),n.focus());}renderBadge(){this.unread>0?(this.badge.hidden=false,this.badge.textContent=String(this.unread),this.launcher.setAttribute("aria-label",`${this.strings.launcherLabel}, ${this.strings.unreadLabel(this.unread)}`)):(this.badge.hidden=true,this.badge.textContent="",this.launcher.setAttribute("aria-label",this.strings.launcherLabel));}};function _(r){return `40${JSON.stringify(r)}`}function I(){return "3"}function P(r){let e=r.charAt(0),t=r.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let s=T(t);return {kind:"open",pingInterval:typeof s?.pingInterval=="number"?s.pingInterval:25e3,pingTimeout:typeof s?.pingTimeout=="number"?s.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let n=t.charAt(0),i=t.slice(1);if(n==="0")return {kind:"connected"};if(n==="1")return {kind:"disconnect"};if(n==="4"){let s=T(i);return {kind:"connectError",message:typeof s?.message=="string"?s.message:"refused"}}if(n!=="2")return {kind:"other"};let a=T(i);return !Array.isArray(a)||typeof a[0]!="string"?{kind:"other"}:{kind:"event",name:a[0],payload:a[1]}}function T(r){try{return JSON.parse(r)}catch{return null}}var j="/socket.io/?EIO=4&transport=websocket",k=class{constructor(e){this.options=e;a(this,"socket",null);a(this,"heartbeat",null);a(this,"ready",false);a(this,"closed",false);a(this,"heartbeatWindow",45e3);a(this,"factory");a(this,"setTimer");a(this,"clearTimer");this.factory=e.socketFactory??W,this.setTimer=e.setTimer??((t,n)=>setTimeout(t,n)),this.clearTimer=e.clearTimer??(t=>clearTimeout(t));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${j}`,t;try{t=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=t,t.onmessage=n=>this.receive(String(n.data)),t.onerror=()=>t.close(),t.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat();let e=this.socket;this.socket=null,e?.close();}receive(e){let t=P(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(_(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(I());return}if(t.kind==="connectError"||t.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(t.kind==="event"){if(t.name==="ready"){this.ready=true,this.options.onReady();return}if(t.name==="conversation.turn"){let n=t.payload?.turn;n&&this.options.onTurn(n);}}}fell(){this.stopHeartbeat();let e=this.ready;this.socket=null,this.ready=false,this.closed||this.options.onClosed(e);}armHeartbeat(e){e!==void 0&&(this.heartbeatWindow=e),this.stopHeartbeat(),this.heartbeat=this.setTimer(()=>this.socket?.close(),this.heartbeatWindow);}stopHeartbeat(){this.heartbeat!==null&&this.clearTimer(this.heartbeat),this.heartbeat=null;}};function W(r){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(r)}function le(r){let e=globalThis.document;if(!e)throw new Error("prodantix chat requires a document; mount it in the browser");let t=r.mountPoint??e.createElement("div");r.mountPoint||e.body.append(t);let n=new f(r),i=new x(t,n,r.strings,r.appearance),a=new Set,s,o=null,p=r.pollIntervalMs??15e3,u=c=>{a.has(c.id)||c.authorKind==="end_user"||(a.add(c.id),i.onIncomingTurn(c));},d=async()=>{if(!n.hasThread)return;let c=await n.load();if(c){for(let m of c.turns)u(m);a=new Set(c.turns.map(m=>m.id));}},g=()=>{s||p<=0||(s=setInterval(()=>void d(),p));},C=()=>{s&&clearInterval(s),s=void 0;},S=()=>{if(o||!r.socketHost)return;let c=n.socketAuth;c&&(o=new k({auth:c,host:r.socketHost,onClosed:m=>{o=null,g(),m&&S();},onReady:C,onTurn:u,socketFactory:r.socketFactory}),o.open());};return g(),S(),{close:()=>i.close(),destroy:()=>{C(),o?.close(),o=null,i.close(),t.remove();},identify:c=>n.identify(c),open:()=>{i.open().then(S);}}}export{f as ChatClient,x as ChatPanel,v as DEFAULT_APPEARANCE,h as DEFAULT_APPEARANCE_SETTINGS,le as mountChat,N as panelStyles,y as resolveAppearance};//# sourceMappingURL=chat.js.map
|
|
41
65
|
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {a as a$1,d,b as b$1,c as c$1}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var c=class extends Error{constructor(s,r,n){super(r,n);a(this,"code");this.code=s,this.name="ProdantixError";}},y=class extends c{constructor(e){super("config",e),this.name="ConfigError";}},m=class extends c{constructor(s,r){super("validation",r);a(this,"field");this.field=s,this.name="ValidationError";}},l=class extends c{constructor(s,r,n){super("transport",s,n);a(this,"status");this.status=r,this.name="TransportError";}};var g=class{constructor(){a(this,"store",new Map);}getItem(e){return this.store.get(e)??null}removeItem(e){this.store.delete(e);}setItem(e,s){this.store.set(e,s);}};function ae(){try{let t=globalThis.localStorage;if(t){let e="__pdx_probe__";return t.setItem(e,"1"),t.removeItem(e),t}}catch{return new g}return new g}var _="prodantix-js",C="0.0.1";var h=Symbol("absent");function U(t,e){if(t==="distinct_id")return e.distinctId;let s=e.properties??{};if(Object.prototype.hasOwnProperty.call(s,t))return s[t];let r=e.attributes??{};return Object.prototype.hasOwnProperty.call(r,t)?r[t]:h}function p(t){return t===h?"undefined":String(t)}function R(t){return t===h?Number.NaN:Number(t)}function $(t){return t!==h&&t!==null&&t!==""}function M(t,e){if(!Array.isArray(e))return false;let s=p(t);return e.map(r=>String(r)).includes(s)}function k(t,e){let s=U(t.attribute,e),r=t.value;switch(t.op){case "is_set":return $(s);case "is_not_set":return !$(s);case "eq":return p(s)===p(r===void 0?h:r);case "neq":return p(s)!==p(r===void 0?h:r);case "contains":return p(s).includes(p(r===void 0?h:r));case "in":return M(s,r);case "not_in":return Array.isArray(r)?!M(s,r):false;case "gt":return v(s,r,(n,o)=>n>o);case "gte":return v(s,r,(n,o)=>n>=o);case "lt":return v(s,r,(n,o)=>n<o);case "lte":return v(s,r,(n,o)=>n<=o);default:return false}}function v(t,e,s){let r=R(t),n=e===void 0?Number.NaN:R(e);return Number.isNaN(r)||Number.isNaN(n)?false:s(r,n)}function q(t,e){let s=`${t}:${e}`,r=2166136261;for(let n=0;n<s.length;n++)r^=s.charCodeAt(n),r=Math.imul(r,16777619);return (r>>>0)%100}function B(t,e){return t.enabled?t.targeting.length>0&&!t.targeting.every(s=>k(s,e))?{enabled:false,reason:"targeting"}:t.rolloutPercentage>=100?{enabled:true,reason:"rollout_full"}:q(t.key,e.distinctId)<t.rolloutPercentage?{enabled:true,reason:"rollout"}:{enabled:false,reason:"rollout_excluded"}:{enabled:false,reason:"disabled"}}function A(t,e){let s={};for(let r of t)s[r.key]=B(r,e).enabled;return s}function H(t,e){let s=t.variations??[],r=s[0];if(!r)return null;if(!t.enabled||t.targeting.length>0&&!t.targeting.every(a=>k(a,e)))return r;let n=q(t.key,e.distinctId),o=0;for(let a=s.length-1;a>=0;a--)if(o+=s[a].weight,n<o)return s[a];return r}function he(t,e,s){let r=t.find(n=>n.key===e);return r?H(r,s)?.value??null:null}var x=class{constructor(e){a(this,"fetch");a(this,"host");a(this,"projectKey");a(this,"requestTimeoutMs");this.fetch=a$1(e.fetch),this.host=d(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async fetchAll(e){let s=this.fetch;if(!s)throw new l("no fetch implementation available in this runtime");let r=`${this.host}/v1/flags?distinct_id=${encodeURIComponent(e)}`,n=b$1(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{let a=await s(r,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:n?.signal});if(!a.ok)throw new l(`flags request failed with status ${a.status}`,a.status);return JSON.parse(await a.text()).flags??{}}finally{o!==void 0&&clearTimeout(o);}}async snapshot(){let e=this.fetch;if(!e)throw new l("no fetch implementation available in this runtime");let s=`${this.host}/v1/flags/snapshot`,r=b$1(),n=r?setTimeout(()=>r.abort(),this.requestTimeoutMs):void 0;try{let o=await e(s,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:r?.signal});if(!o.ok)throw new l(`flag snapshot request failed with status ${o.status}`,o.status);let a=JSON.parse(await o.text());return {flags:a.flags??[],generatedAt:a.generatedAt}}finally{n!==void 0&&clearTimeout(n);}}};var b=class{constructor(e){a(this,"fetch");a(this,"host");a(this,"projectKey");a(this,"requestTimeoutMs");this.fetch=a$1(e.fetch),this.host=d(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async inbox(e){let s=this.requireFetch(),r=`${this.host}/v1/messages?distinct_id=${encodeURIComponent(e)}`,n=await this.request(s,r,{headers:this.authHeaders(),method:"GET"});if(!n.ok)throw new l(`inbox request failed with status ${n.status}`,n.status);return JSON.parse(await n.text()).messages??[]}async markRead(e,s){let r=this.requireFetch(),n=`${this.host}/v1/messages/read`,o=await this.request(r,n,{body:JSON.stringify({distinct_id:s,message_id:e}),headers:{...this.authHeaders(),"content-type":"application/json"},method:"POST"});if(!o.ok)throw new l(`mark-read request failed with status ${o.status}`,o.status)}requireFetch(){if(!this.fetch)throw new l("no fetch implementation available in this runtime");return this.fetch}authHeaders(){return {authorization:`Bearer ${this.projectKey}`}}async request(e,s,r){let n=b$1(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(s,{...r,signal:n?.signal})}finally{o!==void 0&&clearTimeout(o);}}};function N(t){return t>=400&&t<500&&t!==429}var I=class{constructor(e={}){a(this,"fetch");a(this,"maxRetries");a(this,"requestTimeoutMs");a(this,"baseDelayMs");a(this,"maxDelayMs");a(this,"sleep");a(this,"random");this.fetch=a$1(e.fetch),this.maxRetries=e.maxRetries??3,this.requestTimeoutMs=e.requestTimeoutMs??1e4,this.baseDelayMs=e.baseDelayMs??500,this.maxDelayMs=e.maxDelayMs??3e4,this.sleep=e.sleep??c$1,this.random=e.random??Math.random;}async send(e){let s=this.fetch;if(!s)throw new l("no fetch implementation available in this runtime");let r=JSON.stringify(e.body),n;for(let o=0;o<=this.maxRetries;o+=1){try{let a=await this.attempt(s,e,r);if(a.ok)return;if(N(a.status))throw new l(`ingest rejected batch with status ${a.status}`,a.status);n=new l(`ingest transient status ${a.status}`,a.status);}catch(a){if(a instanceof l&&a.status!==void 0&&N(a.status))throw a;n=a;}o<this.maxRetries&&await this.sleep(this.backoff(o));}throw new l("ingest delivery failed after retries",void 0,{cause:n})}async attempt(e,s,r){let n=b$1(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(s.url,{body:r,headers:{authorization:`Bearer ${s.projectKey}`,"content-type":"application/json"},method:"POST",signal:n?.signal})}finally{o!==void 0&&clearTimeout(o);}}backoff(e){return Math.min(this.maxDelayMs,this.baseDelayMs*2**e)+this.random()*this.baseDelayMs}};var O={now:()=>new Date};function E(t){return t.toISOString()}function G(){return globalThis.crypto}function X(t){t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=[];for(let s=0;s<16;s+=1)e.push(t[s].toString(16).padStart(2,"0"));return `${e[0]}${e[1]}${e[2]}${e[3]}-${e[4]}${e[5]}-${e[6]}${e[7]}-${e[8]}${e[9]}-${e[10]}${e[11]}${e[12]}${e[13]}${e[14]}${e[15]}`}function Y(){let t=G();if(t?.randomUUID)return t.randomUUID();let e=new Uint8Array(16);if(t?.getRandomValues)t.getRandomValues(e);else for(let s=0;s<16;s+=1)e[s]=Math.floor(Math.random()*256);return X(e)}var D={uuid:Y};var Z=/^pdx_pub_(?:(?:live|test)_)?[a-z0-9]{32}$/;var W=/^(?:\$|[a-z])[a-z0-9_.]*$/;function K(t){let e=0;for(let s of t)e+=1;return e}function L(t){return Z.test(t)}function ee(t){return W.test(t)}function j(t){let e=K(t);if(e<1||e>200)throw new m("distinct_id","distinct_id must be between 1 and 200 characters")}function V(t){let e=K(t);if(e<1||e>200)throw new m("event_name","event_name must be between 1 and 200 characters");if(!ee(t))throw new m("event_name","event_name must match /^(\\$|[a-z])[a-z0-9_.]*$/")}var te=t=>{};function z(t){if(!t.apiKey||!L(t.apiKey))throw new y("apiKey must be a public project key of the form pdx_pub_<32 lowercase alphanumerics>");if(!t.host)throw new y("host is required (the ingest base URL)");let e=d(t.host),s=t.defaultProperties;return {apiKey:t.apiKey,autocapture:t.autocapture??false,clock:t.clock??O,defaultProperties:typeof s=="function"?s:()=>s??{},flagsHost:t.flagsHost?d(t.flagsHost):e,flushAt:t.flushAt??20,flushIntervalMs:t.flushIntervalMs??1e4,host:e,ids:t.ids??D,locale:t.locale,maxQueueSize:t.maxQueueSize??1e3,maxRetries:t.maxRetries??3,namespace:t.apiKey.slice(0,16),onError:t.onError??te,os:t.os,requestTimeoutMs:t.requestTimeoutMs??1e4,sdkName:t.sdkName??_,sdkVersion:t.sdkVersion??C,storage:t.storage??new g,transport:t.transport}}function J(t,e,s){V(t.eventName),j(t.distinctId);let r={distinct_id:t.distinctId,event_id:t.eventId??s.uuid(),event_name:t.eventName,properties:t.properties??{},schema_version:1,timestamp:E(t.timestamp??e.now())};return t.context&&(r.context=t.context),t.sessionId&&(r.session_id=t.sessionId),r}var w=class{constructor(e,s,r){this.storage=e;this.ids=s;this.namespace=r;a(this,"anonymousId");a(this,"distinctId");a(this,"identified");let n=e.getItem(this.key("anonymous_id"));n?this.anonymousId=n:(this.anonymousId=s.uuid(),e.setItem(this.key("anonymous_id"),this.anonymousId));let o=e.getItem(this.key("distinct_id"));o?(this.distinctId=o,this.identified=true):(this.distinctId=this.anonymousId,this.identified=false);}getAnonymousId(){return this.anonymousId}getDistinctId(){return this.distinctId}isIdentified(){return this.identified}snapshot(){return {anonymousId:this.anonymousId,distinctId:this.distinctId,identified:this.identified}}identify(e){return this.identified&&this.distinctId===e?{changed:false}:(this.distinctId=e,this.identified=true,this.storage.setItem(this.key("distinct_id"),e),{changed:true})}reset(){this.anonymousId=this.ids.uuid(),this.distinctId=this.anonymousId,this.identified=false,this.storage.setItem(this.key("anonymous_id"),this.anonymousId),this.storage.removeItem(this.key("distinct_id"));}key(e){return `pdx.${this.namespace}.${e}`}};var F=class{constructor(e,s){this.maxSize=e;this.onOverflow=s;a(this,"events",[]);}get size(){return this.events.length}enqueue(e){this.events.push(e),this.enforceCap();}restore(e){this.events.push(...e),this.enforceCap();}requeue(e){this.events.unshift(...e),this.enforceCap();}drain(e){let s=e===void 0?this.events.length:Math.min(e,this.events.length);return this.events.splice(0,s)}snapshot(){return [...this.events]}enforceCap(){if(this.events.length<=this.maxSize)return;let e=this.events.splice(0,this.events.length-this.maxSize);this.onOverflow?.({dropped:e});}};var se="queue",re=1e3,ne=3e4,Q=t=>{let e={};return t.avatar!==void 0&&(e.$avatar=t.avatar),t.email!==void 0&&(e.$email=t.email),t.name!==void 0&&(e.$name=t.name),t.phone!==void 0&&(e.$phone=t.phone),e},S=class{constructor(e){a(this,"config");a(this,"identity");a(this,"queue");a(this,"transport");a(this,"flagsClient");a(this,"messagesClient");a(this,"context");a(this,"flushTimer");a(this,"flushing",false);a(this,"cachedFlags");a(this,"cachedSnapshot");this.config=z(e),this.identity=new w(this.config.storage,this.config.ids,this.config.namespace),this.queue=new F(this.config.maxQueueSize,({dropped:s})=>{this.config.onError(new c("queue_overflow",`event queue overflow: dropped ${s.length} oldest event(s)`));}),this.transport=this.config.transport??new I({maxRetries:this.config.maxRetries,requestTimeoutMs:this.config.requestTimeoutMs}),this.flagsClient=new x({host:this.config.flagsHost,projectKey:this.config.apiKey,requestTimeoutMs:this.config.requestTimeoutMs}),this.messagesClient=new b({host:this.config.flagsHost,projectKey:this.config.apiKey,requestTimeoutMs:this.config.requestTimeoutMs}),this.context={sdk:this.config.sdkName,sdk_version:this.config.sdkVersion},this.config.os&&(this.context.os=this.config.os),this.config.locale&&(this.context.locale=this.config.locale),this.restoreQueue(),this.startTimer();}get distinctId(){return this.identity.getDistinctId()}get anonymousId(){return this.identity.getAnonymousId()}capture(e,s={}){try{let r={...this.config.defaultProperties(),...s.properties??{}},n=J({context:this.context,distinctId:this.identity.getDistinctId(),eventName:e,properties:r,sessionId:s.sessionId,timestamp:s.timestamp},this.config.clock,this.config.ids);this.enqueue(n);}catch(r){this.config.onError(r);}}identify(e,s={}){let r=this.identity.getAnonymousId(),n=!this.identity.isIdentified(),o=this.identity.identify(e),a={};n&&o.changed&&(a.$anon_distinct_id=r);let T={...Q(s.traits??{}),...s.set??{}};Object.keys(T).length>0&&(a.$set=T),this.capture("$identify",{properties:a});}alias(e){this.capture("$create_alias",{properties:{alias:e}});}group(e,s,r){let n={$group_key:s,$group_type:e};r&&(n.$set=r),this.capture("$group",{properties:n});}setPersonProperties(e,s){let r={};e&&(r.$set=e),s&&(r.$set_once=s),this.capture("$set",{properties:r});}setPersonTraits(e){let s=Q(e);Object.keys(s).length!==0&&this.capture("$set",{properties:{$set:s}});}async getAllFlags(){let e=this.identity.getDistinctId(),s=await this.flagsClient.fetchAll(e);return this.cachedFlags={distinctId:e,flags:s},s}async isFeatureEnabled(e){return (await this.getAllFlags())[e]??false}getCachedFlag(e){if(!(!this.cachedFlags||this.cachedFlags.distinctId!==this.distinctId))return this.cachedFlags.flags[e]}async getLocalFlags(e={}){let s=await this.flagSnapshot();return A(s.flags,{attributes:e.attributes,distinctId:this.identity.getDistinctId(),properties:e.properties})}async isFeatureEnabledLocal(e,s){return (await this.getLocalFlags(s))[e]??false}async flagSnapshot(){let e=this.config.clock.now().getTime();if(this.cachedSnapshot&&e-this.cachedSnapshot.fetchedAt<ne)return this.cachedSnapshot.snapshot;let s=await this.flagsClient.snapshot();return this.cachedSnapshot={fetchedAt:e,snapshot:s},s}async getInbox(){return this.messagesClient.inbox(this.identity.getDistinctId())}async markMessageRead(e){await this.messagesClient.markRead(e,this.identity.getDistinctId());}async flush(){if(this.flushing||this.queue.size===0)return;this.flushing=true;let e=this.queue.drain(re);try{await this.transport.send({body:{events:e,sent_at:E(this.config.clock.now())},projectKey:this.config.apiKey,url:`${this.config.host}/v1/events`}),this.persistQueue();}catch(s){this.queue.requeue(e),this.persistQueue(),this.config.onError(s);}finally{this.flushing=false;}}reset(){this.identity.reset(),this.cachedFlags=void 0,this.cachedSnapshot=void 0;}async shutdown(){this.stopTimer(),await this.flush();}enqueue(e){this.queue.enqueue(e),this.persistQueue(),this.queue.size>=this.config.flushAt&&this.flush();}persistQueue(){try{this.config.storage.setItem(this.persistKey(),JSON.stringify(this.queue.snapshot()));}catch(e){this.config.onError(e);}}restoreQueue(){try{let e=this.config.storage.getItem(this.persistKey());if(!e)return;let s=JSON.parse(e);Array.isArray(s)&&this.queue.restore(s);}catch(e){this.config.onError(e);}}startTimer(){if(this.config.flushIntervalMs<=0)return;let e=setInterval(()=>{this.flush();},this.config.flushIntervalMs),s=e;typeof s.unref=="function"&&s.unref(),this.flushTimer=e;}stopTimer(){this.flushTimer!==void 0&&(clearInterval(this.flushTimer),this.flushTimer=void 0);}persistKey(){return `pdx.${this.config.namespace}.${se}`}};function st(t){return new S(t)}export{c as a,y as b,m as c,l as d,g as e,ae as f,Y as g,_ as h,C as i,k as j,q as k,B as l,A as m,H as n,he as o,x as p,b as q,I as r,S as s,st as t};//# sourceMappingURL=chunk-7J6AQICL.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-7J6AQICL.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function r(e){if(e)return e;let t=globalThis.fetch;if(typeof t=="function")return t.bind(globalThis)}function n(){let e=globalThis.AbortController;return e?new e:void 0}var o=e=>new Promise(t=>{setTimeout(t,e);});function i(e){return e.replace(/\/+$/,"")}export{r as a,n as b,o as c,i as d};//# sourceMappingURL=chunk-VG77TYVX.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-VG77TYVX.js.map
|