@prodantix/sdk 0.1.0-beta.341 → 0.1.0-beta.348
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chat.d.cts +1 -12
- package/dist/chat.d.ts +1 -12
- package/dist/chat.js +2 -2
- package/dist/chunk-CSIP3PZ7.js +2 -0
- package/dist/chunk-V77KYPOF.js +2 -0
- package/dist/{client-BBUAoQg2.d.cts → client-Ca6xJESF.d.ts} +25 -80
- package/dist/{client-BBUAoQg2.d.ts → client-y1xyVF6C.d.cts} +25 -80
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +17 -5
- package/dist/index.d.ts +17 -5
- package/dist/index.js +1 -1
- package/dist/node.cjs +1 -1
- package/dist/node.d.cts +2 -1
- package/dist/node.d.ts +2 -1
- package/dist/node.js +1 -1
- package/dist/{transport-DhhzvwpV.d.cts → transport-Bj4nXmgt.d.cts} +1 -1
- package/dist/{transport-dWp3NUMj.d.ts → transport-CTPih3Jj.d.ts} +1 -1
- package/dist/types-68Sc11g8.d.cts +105 -0
- package/dist/types-68Sc11g8.d.ts +105 -0
- package/dist/web.cjs +1 -1
- package/dist/web.d.cts +3 -2
- package/dist/web.d.ts +3 -2
- package/dist/web.js +1 -1
- package/package.json +1 -1
- package/dist/chunk-7J6AQICL.js +0 -2
package/dist/chat.d.cts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
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
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 { S as SocketFactory } from './types-68Sc11g8.cjs';
|
|
3
4
|
import './http-BCh716Vs.cjs';
|
|
4
5
|
|
|
5
6
|
interface ChatStrings {
|
|
@@ -44,18 +45,6 @@ declare class ChatPanel {
|
|
|
44
45
|
private renderBadge;
|
|
45
46
|
}
|
|
46
47
|
|
|
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
|
-
|
|
59
48
|
interface MountChatOptions extends ChatClientOptions {
|
|
60
49
|
mountPoint?: HTMLElement;
|
|
61
50
|
strings?: Partial<ChatStrings>;
|
package/dist/chat.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
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
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 { S as SocketFactory } from './types-68Sc11g8.js';
|
|
3
4
|
import './http-BCh716Vs.js';
|
|
4
5
|
|
|
5
6
|
interface ChatStrings {
|
|
@@ -44,18 +45,6 @@ declare class ChatPanel {
|
|
|
44
45
|
private renderBadge;
|
|
45
46
|
}
|
|
46
47
|
|
|
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
|
-
|
|
59
48
|
interface MountChatOptions extends ChatClientOptions {
|
|
60
49
|
mountPoint?: HTMLElement;
|
|
61
50
|
strings?: Partial<ChatStrings>;
|
package/dist/chat.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var
|
|
1
|
+
import {c,a as a$2,b as b$1}from'./chunk-V77KYPOF.js';import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var I="X-Prodantix-Conversation-Token",T="prodantix.chat.handle";function H(){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??H(),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(T,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(T);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(T),null}async request(e,t,n={}){let a=this.fetchImpl;if(!a)return this.options.onError?.(new Error("no fetch available for prodantix chat")),null;let o={authorization:`Bearer ${this.options.apiKey}`,"content-type":"application/json"};n.token&&(o[I]=n.token);try{let l=await a(`${this.host}${t}`,{body:n.body===void 0?void 0:JSON.stringify(n.body),headers:o,method:e}),i=await l.text();return l.ok?i?JSON.parse(i):{}:(this.options.onError?.(new Error(`prodantix chat ${t}: ${l.status}`)),null)}catch(l){return this.options.onError?.(l),null}}};var h={bubbleStyle:"tailed",launcherStyle:"circle_outlined",namePlacement:"avatar_only",skin:"concierge",timestampStyle:"cluster"},N=["concierge","console","quiet"],M=["avatar_circle","circle_filled","circle_outlined","pill_labelled","pill_team","squircle_filled"],$=["hairline","outlined","rounded","tailed"],F=["above","avatar_only","gutter","hidden","inline"],R=["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,F,h.namePlacement),skin:b(r?.skin,N,h.skin),timestampStyle:b(r?.timestampStyle,R,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 O={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)}"},K={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 _(r){let e=y(r),t=r.launcherPosition==="bottom_left"?"left":"right",n=r.accentColor;return `${`
|
|
2
2
|
:host {
|
|
3
3
|
all: initial; --a: ${n};
|
|
4
4
|
--paper: #fff; --ink: #0f172a; --ink-3: var(--ink-3);
|
|
@@ -61,5 +61,5 @@ import {a as a$1,d}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js'
|
|
|
61
61
|
.panel { animation: rise 180ms ease-out; }
|
|
62
62
|
@keyframes rise { from { transform: translateY(8px); opacity: 0; } to { transform: none; opacity: 1; } }
|
|
63
63
|
}
|
|
64
|
-
`}${z[e.skin]}${
|
|
64
|
+
`}${z[e.skin]}${K[e.launcherStyle]}${B[e.bubbleStyle]}${D[e.namePlacement]}${q[e.timestampStyle]}`}var U=["end_user","agent","ai"],x=class{constructor(e,t,n={},a$1={}){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={...O,...n},this.appearance={...v,...a$1},this.settings=y({...v,...a$1}),this.root=e.attachShadow({mode:"closed"});let o=document.createElement("style");o.textContent=_({...v,...a$1}),this.root.append(o),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 a=document.createElement("button");a.className="close",a.type="button",a.setAttribute("aria-label",this.strings.closeLabel),a.textContent="\xD7",a.addEventListener("click",()=>this.close()),t.append(n,a);let o=document.createElement("div");o.className="log",o.setAttribute("role","log"),o.setAttribute("aria-live","polite"),o.setAttribute("aria-label",this.strings.title);let l=document.createElement("form");l.className="composer";let i=document.createElement("input");i.type="text",i.setAttribute("aria-label",this.strings.inputPlaceholder),i.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),l.append(i,p),l.addEventListener("submit",g=>{g.preventDefault(),this.submit(i,o);}),e.append(t,o,l),e.addEventListener("keydown",g=>this.onKeydown(g,e,a)),this.root.append(e),this.panel=e,i.focus();let d=await this.client.load();d&&d.turns.length>0?this.renderThread(o,d):this.renderFirstRun(o,i);}renderFirstRun(e,t){let n=document.createElement("div");n.className="empty";let a=document.createElement("h3");a.textContent=this.appearance.greeting.trim()||this.strings.emptyTitle;let o=document.createElement("p");o.textContent=this.strings.emptyBody,n.append(a,o);for(let l of this.appearance.starterPrompts){let i=document.createElement("button");i.className="prompt",i.type="button",i.textContent=l,i.addEventListener("click",()=>{t.value=l,this.submit(t,e);}),n.append(i);}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 a=await this.client.send(n);a&&this.appendTurn(t,a);}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",a=this.settings,o=document.createElement("div");if(o.className=`turn ${n}`,n!=="end_user"&&(a.namePlacement==="avatar_only"||a.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"),o.append(d);}let i=document.createElement("div");if(i.className="body",n!=="end_user"&&a.namePlacement!=="hidden"&&!(a.namePlacement==="avatar_only"&&n==="agent")||n==="ai"&&a.namePlacement==="hidden"){let d=document.createElement("div");d.className=n==="ai"?"author ai":"author",d.textContent=n==="ai"?this.strings.aiLabel:this.strings.agentLabel,(a.timestampStyle==="with_name"||a.timestampStyle==="latency")&&d.append(this.stamp(t)),i.append(d);}let u=document.createElement("div");u.textContent=t.body,i.append(u),a.timestampStyle==="trailing"&&i.append(this.stamp(t)),o.append(i),e.append(o),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 a=t.querySelectorAll('button, input, [tabindex]:not([tabindex="-1"])');if(a.length===0)return;let o=a[0],l=a[a.length-1],i=this.root.activeElement;e.shiftKey&&i===o?(e.preventDefault(),l.focus()):!e.shiftKey&&i===l?(e.preventDefault(),o.focus()):i===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));}};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=c(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(a$2(this.options.auth));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(b$1());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 oe(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),a=new x(t,n,r.strings,r.appearance),o=new Set,l,i=null,p=r.pollIntervalMs??15e3,u=c=>{o.has(c.id)||c.authorKind==="end_user"||(o.add(c.id),a.onIncomingTurn(c));},d=async()=>{if(!n.hasThread)return;let c=await n.load();if(c){for(let m of c.turns)u(m);o=new Set(c.turns.map(m=>m.id));}},g=()=>{l||p<=0||(l=setInterval(()=>void d(),p));},C=()=>{l&&clearInterval(l),l=void 0;},S=()=>{if(i||!r.socketHost)return;let c=n.socketAuth;c&&(i=new k({auth:c,host:r.socketHost,onClosed:m=>{i=null,g(),m&&S();},onReady:C,onTurn:u,socketFactory:r.socketFactory}),i.open());};return g(),S(),{close:()=>a.close(),destroy:()=>{C(),i?.close(),i=null,a.close(),t.remove();},identify:c=>n.identify(c),open:()=>{a.open().then(S);}}}export{f as ChatClient,x as ChatPanel,v as DEFAULT_APPEARANCE,h as DEFAULT_APPEARANCE_SETTINGS,oe as mountChat,_ as panelStyles,y as resolveAppearance};//# sourceMappingURL=chat.js.map
|
|
65
65
|
//# sourceMappingURL=chat.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {c as c$1,a as a$2,b as b$2}from'./chunk-V77KYPOF.js';import {a as a$1,d,b as b$1,c}from'./chunk-VG77TYVX.js';import {a}from'./chunk-5XGN7UAV.js';var h=class extends Error{constructor(t,r,n){super(r,n);a(this,"code");this.code=t,this.name="ProdantixError";}},v=class extends h{constructor(e){super("config",e),this.name="ConfigError";}},m=class extends h{constructor(t,r){super("validation",r);a(this,"field");this.field=t,this.name="ValidationError";}},l=class extends h{constructor(t,r,n){super("transport",t,n);a(this,"status");this.status=r,this.name="TransportError";}};var y=class{constructor(){a(this,"store",new Map);}getItem(e){return this.store.get(e)??null}removeItem(e){this.store.delete(e);}setItem(e,t){this.store.set(e,t);}};function be(){try{let s=globalThis.localStorage;if(s){let e="__pdx_probe__";return s.setItem(e,"1"),s.removeItem(e),s}}catch{return new y}return new y}var K="prodantix-js",D="0.0.1";var f=Symbol("absent");function ne(s,e){if(s==="distinct_id")return e.distinctId;let t=e.properties??{};if(Object.prototype.hasOwnProperty.call(t,s))return t[s];let r=e.attributes??{};return Object.prototype.hasOwnProperty.call(r,s)?r[s]:f}function p(s){return s===f?"undefined":String(s)}function O(s){return s===f?Number.NaN:Number(s)}function N(s){return s!==f&&s!==null&&s!==""}function L(s,e){if(!Array.isArray(e))return false;let t=p(s);return e.map(r=>String(r)).includes(t)}function V(s,e){let t=ne(s.attribute,e),r=s.value;switch(s.op){case "is_set":return N(t);case "is_not_set":return !N(t);case "eq":return p(t)===p(r===void 0?f:r);case "neq":return p(t)!==p(r===void 0?f:r);case "contains":return p(t).includes(p(r===void 0?f:r));case "in":return L(t,r);case "not_in":return Array.isArray(r)?!L(t,r):false;case "gt":return k(t,r,(n,i)=>n>i);case "gte":return k(t,r,(n,i)=>n>=i);case "lt":return k(t,r,(n,i)=>n<i);case "lte":return k(t,r,(n,i)=>n<=i);case "in_cohort":return typeof r=="string"&&r!==""&&(e.cohorts??[]).includes(r);case "not_in_cohort":return typeof r=="string"&&r!==""&&!(e.cohorts??[]).includes(r);default:return false}}function k(s,e,t){let r=O(s),n=e===void 0?Number.NaN:O(e);return Number.isNaN(r)||Number.isNaN(n)?false:t(r,n)}function j(s,e){let t=`${s}:${e}`,r=2166136261;for(let n=0;n<t.length;n++)r^=t.charCodeAt(n),r=Math.imul(r,16777619);return (r>>>0)%100}function _(s,e){return s.targeting.length===0||s.targeting.every(t=>V(t,e))}function U(s,e){let t=j(s.key,e.distinctId),r=s.variations??[];if(r.length===0)return s.rolloutPercentage>=100||t<s.rolloutPercentage?"true":"false";let n=0;for(let i=r.length-1;i>=0;i--)if(n+=r[i].weight,t<n)return r[i].key;return r[0].key}function P(s,e,t,r){for(let n of s.prerequisites??[]){if(r.includes(n.flagKey))return false;let i=e.find(c=>c.key===n.flagKey);if(!i||!i.enabled)return false;r.push(i.key);let a=P(i,e,t,r)&&_(i,t)&&U(i,t)===n.variationKey;if(r.pop(),!a)return false}return true}function b(s,e,t){return s.enabled?P(s,e,t,[s.key])?_(s,t)?s.rolloutPercentage>=100?{enabled:true,reason:"rollout_full"}:j(s.key,t.distinctId)<s.rolloutPercentage?{enabled:true,reason:"rollout"}:{enabled:false,reason:"rollout_excluded"}:{enabled:false,reason:"targeting"}:{enabled:false,reason:"prerequisite"}:{enabled:false,reason:"disabled"}}function Ee(s,e){return b(s,[],e)}function z(s,e){let t={};for(let r of s)t[r.key]=b(r,s,e).enabled;return t}function x(s,e,t){let r=s.variations??[],n=r[0];if(!n)return null;if(!s.enabled||!P(s,e,t,[s.key])||!_(s,t))return n;let i=U(s,t);return r.find(a=>a.key===i)??n}function Se(s,e){return x(s,[],e)}function Te(s,e,t){let r=s.find(n=>n.key===e);return r?x(r,s,t)?.value??null:null}function H(s){return s.some(e=>e.targeting.some(t=>t.op==="in_cohort"||t.op==="not_in_cohort"))}var F=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){return (await this.fetchDecisions(e)).flags}async fetchDecisions(e){let t=this.fetch;if(!t)throw new l("no fetch implementation available in this runtime");let r=`${this.host}/v1/flags?distinct_id=${encodeURIComponent(e)}`,n=b$1(),i=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{let a=await t(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);let c=JSON.parse(await a.text());return {flags:c.flags??{},variants:c.variants??{}}}finally{i!==void 0&&clearTimeout(i);}}async snapshot(){let e=this.fetch;if(!e)throw new l("no fetch implementation available in this runtime");let t=`${this.host}/v1/flags/snapshot`,r=b$1(),n=r?setTimeout(()=>r.abort(),this.requestTimeoutMs):void 0;try{let i=await e(t,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:r?.signal});if(!i.ok)throw new l(`flag snapshot request failed with status ${i.status}`,i.status);let a=JSON.parse(await i.text()),c={flags:a.flags??[],generatedAt:a.generatedAt};return typeof a.socketUrl=="string"&&a.socketUrl!==""&&(c.socketUrl=a.socketUrl),c}finally{n!==void 0&&clearTimeout(n);}}async memberships(e){let t=this.fetch;if(!t)throw new l("no fetch implementation available in this runtime");let r=`${this.host}/v1/flags/memberships?distinct_id=${encodeURIComponent(e)}`,n=b$1(),i=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{let a=await t(r,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:n?.signal});if(!a.ok)throw new l(`memberships request failed with status ${a.status}`,a.status);return JSON.parse(await a.text()).cohorts??[]}finally{i!==void 0&&clearTimeout(i);}}};var w=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 t=this.requireFetch(),r=`${this.host}/v1/messages?distinct_id=${encodeURIComponent(e)}`,n=await this.request(t,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,t){let r=this.requireFetch(),n=`${this.host}/v1/messages/read`,i=await this.request(r,n,{body:JSON.stringify({distinct_id:t,message_id:e}),headers:{...this.authHeaders(),"content-type":"application/json"},method:"POST"});if(!i.ok)throw new l(`mark-read request failed with status ${i.status}`,i.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,t,r){let n=b$1(),i=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(t,{...r,signal:n?.signal})}finally{i!==void 0&&clearTimeout(i);}}};function J(s){return s>=400&&s<500&&s!==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,this.random=e.random??Math.random;}async send(e){let t=this.fetch;if(!t)throw new l("no fetch implementation available in this runtime");let r=JSON.stringify(e.body),n;for(let i=0;i<=this.maxRetries;i+=1){try{let a=await this.attempt(t,e,r);if(a.ok)return;if(J(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&&J(a.status))throw a;n=a;}i<this.maxRetries&&await this.sleep(this.backoff(i));}throw new l("ingest delivery failed after retries",void 0,{cause:n})}async attempt(e,t,r){let n=b$1(),i=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(t.url,{body:r,headers:{authorization:`Bearer ${t.projectKey}`,"content-type":"application/json"},method:"POST",signal:n?.signal})}finally{i!==void 0&&clearTimeout(i);}}backoff(e){return Math.min(this.maxDelayMs,this.baseDelayMs*2**e)+this.random()*this.baseDelayMs}};var Q={now:()=>new Date};function E(s){return s.toISOString()}function ie(){return globalThis.crypto}function oe(s){s[6]=s[6]&15|64,s[8]=s[8]&63|128;let e=[];for(let t=0;t<16;t+=1)e.push(s[t].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 ae(){let s=ie();if(s?.randomUUID)return s.randomUUID();let e=new Uint8Array(16);if(s?.getRandomValues)s.getRandomValues(e);else for(let t=0;t<16;t+=1)e[t]=Math.floor(Math.random()*256);return oe(e)}var B={uuid:ae};var le=/^pdx_pub_(?:(?:live|test)_)?[a-z0-9]{32}$/;var ce=/^(?:\$|[a-z])[a-z0-9_.]*$/;function G(s){let e=0;for(let t of s)e+=1;return e}function W(s){return le.test(s)}function ue(s){return ce.test(s)}function X(s){let e=G(s);if(e<1||e>200)throw new m("distinct_id","distinct_id must be between 1 and 200 characters")}function Y(s){let e=G(s);if(e<1||e>200)throw new m("event_name","event_name must be between 1 and 200 characters");if(!ue(s))throw new m("event_name","event_name must match /^(\\$|[a-z])[a-z0-9_.]*$/")}var de=s=>{};function Z(s){if(!s.apiKey||!W(s.apiKey))throw new v("apiKey must be a public project key of the form pdx_pub_<32 lowercase alphanumerics>");if(!s.host)throw new v("host is required (the ingest base URL)");let e=d(s.host),t=s.defaultProperties;return {apiKey:s.apiKey,autocapture:s.autocapture??false,clock:s.clock??Q,defaultProperties:typeof t=="function"?t:()=>t??{},flagsHost:s.flagsHost?d(s.flagsHost):e,flushAt:s.flushAt??20,flushIntervalMs:s.flushIntervalMs??1e4,host:e,ids:s.ids??B,locale:s.locale,maxQueueSize:s.maxQueueSize??1e3,maxRetries:s.maxRetries??3,namespace:s.apiKey.slice(0,16),onError:s.onError??de,os:s.os,requestTimeoutMs:s.requestTimeoutMs??1e4,sdkName:s.sdkName??K,sdkVersion:s.sdkVersion??D,socketFactory:s.socketFactory,storage:s.storage??new y,streamFlags:s.streamFlags??false,transport:s.transport}}function ee(s,e,t){Y(s.eventName),X(s.distinctId);let r={distinct_id:s.distinctId,event_id:s.eventId??t.uuid(),event_name:s.eventName,properties:s.properties??{},schema_version:1,timestamp:E(s.timestamp??e.now())};return s.context&&(r.context=s.context),s.sessionId&&(r.session_id=s.sessionId),r}var he="/socket.io/?EIO=4&transport=websocket",pe=250,S=class{constructor(e){this.options=e;a(this,"socket",null);a(this,"heartbeat",null);a(this,"pending",null);a(this,"lastKey","");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??fe,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(/\/+$/,"")}${he}`,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(),this.pending!==null&&this.clearTimer(this.pending),this.pending=null;let e=this.socket;this.socket=null,e?.close();}receive(e){let t=c$1(e);if(t.kind==="open"){this.armHeartbeat(t.pingInterval+t.pingTimeout),this.socket?.send(a$2({projectKey:this.options.projectKey}));return}if(t.kind==="ping"){this.armHeartbeat(),this.socket?.send(b$2());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;return}if(t.name==="flagChange"){let r=t.payload?.key;this.lastKey=typeof r=="string"?r:"",this.pending===null&&(this.pending=this.setTimer(()=>{this.pending=null,this.options.onChange(this.lastKey);},pe));}}}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 fe(s){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(s)}var T=class{constructor(e,t,r){this.storage=e;this.ids=t;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=t.uuid(),e.setItem(this.key("anonymous_id"),this.anonymousId));let i=e.getItem(this.key("distinct_id"));i?(this.distinctId=i,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 C=class{constructor(e,t){this.maxSize=e;this.onOverflow=t;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 t=e===void 0?this.events.length:Math.min(e,this.events.length);return this.events.splice(0,t)}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 ge="queue",me=1e3,te=3e4,se=s=>{let e={};return s.avatar!==void 0&&(e.$avatar=s.avatar),s.email!==void 0&&(e.$email=s.email),s.name!==void 0&&(e.$name=s.name),s.phone!==void 0&&(e.$phone=s.phone),e},R=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");a(this,"membershipCache");a(this,"stream");a(this,"shutDown",false);a(this,"exposures",new Set);this.config=Z(e),this.identity=new T(this.config.storage,this.config.ids,this.config.namespace),this.queue=new C(this.config.maxQueueSize,({dropped:t})=>{this.config.onError(new h("queue_overflow",`event queue overflow: dropped ${t.length} oldest event(s)`));}),this.transport=this.config.transport??new I({maxRetries:this.config.maxRetries,requestTimeoutMs:this.config.requestTimeoutMs}),this.flagsClient=new F({host:this.config.flagsHost,projectKey:this.config.apiKey,requestTimeoutMs:this.config.requestTimeoutMs}),this.messagesClient=new w({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,t={}){try{let r={...this.config.defaultProperties(),...t.properties??{}},n=ee({context:this.context,distinctId:this.identity.getDistinctId(),eventName:e,properties:r,sessionId:t.sessionId,timestamp:t.timestamp},this.config.clock,this.config.ids);this.enqueue(n);}catch(r){this.config.onError(r);}}identify(e,t={}){let r=this.identity.getAnonymousId(),n=!this.identity.isIdentified(),i=this.identity.identify(e),a={};n&&i.changed&&(a.$anon_distinct_id=r);let c={...se(t.traits??{}),...t.set??{}};Object.keys(c).length>0&&(a.$set=c),this.capture("$identify",{properties:a});}alias(e){this.capture("$create_alias",{properties:{alias:e}});}group(e,t,r){let n={$group_key:t,$group_type:e};r&&(n.$set=r),this.capture("$group",{properties:n});}setPersonProperties(e,t){let r={};e&&(r.$set=e),t&&(r.$set_once=t),this.capture("$set",{properties:r});}setPersonTraits(e){let t=se(e);Object.keys(t).length!==0&&this.capture("$set",{properties:{$set:t}});}async getAllFlags(){let e=this.identity.getDistinctId(),t=await this.flagsClient.fetchDecisions(e);return this.cachedFlags={distinctId:e,flags:t.flags,variants:t.variants??{}},t.flags}async isFeatureEnabled(e){let r=(await this.getAllFlags())[e]??false;return this.recordExposure(e,this.cachedFlags?.variants[e]?.key??String(r)),r}async getVariant(e){let t=await this.getAllFlags(),r=this.cachedFlags?.variants[e]??null;return this.recordExposure(e,r?.key??String(t[e]??false)),r}async getVariantLocal(e,t={}){let r=await this.flagSnapshot(),n=r.flags.find(re=>re.key===e),i=await this.localContext(t,r.flags),a=n?x(n,r.flags,i):null,c=n?b(n,r.flags,i).enabled:false;return this.recordExposure(e,a?.key??String(c)),a?{key:a.key,value:a.value}:null}recordExposure(e,t){let r=`${this.identity.getDistinctId()} ${e} ${t}`;this.exposures.has(r)||(this.exposures.add(r),this.capture("$feature_flag_called",{properties:{$feature_flag:e,$feature_flag_response:t}}));}getCachedFlag(e){if(!(!this.cachedFlags||this.cachedFlags.distinctId!==this.distinctId))return this.cachedFlags.flags[e]}async getLocalFlags(e={}){let t=await this.flagSnapshot();return z(t.flags,await this.localContext(e,t.flags))}async isFeatureEnabledLocal(e,t={}){let r=await this.flagSnapshot(),n=r.flags.find(c=>c.key===e),i=await this.localContext(t,r.flags),a=n?b(n,r.flags,i).enabled:false;return this.recordExposure(e,(n?x(n,r.flags,i)?.key:void 0)??String(a)),a}async localContext(e,t){let r=this.identity.getDistinctId(),n=e.cohorts;if(n===void 0&&H(t)){let i=this.config.clock.now().getTime();this.membershipCache&&this.membershipCache.distinctId===r&&i-this.membershipCache.fetchedAt<te?n=this.membershipCache.cohorts:(n=await this.flagsClient.memberships(r),this.membershipCache={cohorts:n,distinctId:r,fetchedAt:i});}return {attributes:e.attributes,cohorts:n,distinctId:r,properties:e.properties}}async flagSnapshot(){let e=this.config.clock.now().getTime();if(this.cachedSnapshot&&e-this.cachedSnapshot.fetchedAt<te)return this.cachedSnapshot.snapshot;let t=await this.flagsClient.snapshot();return this.cachedSnapshot={fetchedAt:e,snapshot:t},this.maybeStream(t),t}maybeStream(e){if(!this.config.streamFlags||this.shutDown||this.stream||!e.socketUrl)return;let t=new S({host:e.socketUrl,onChange:()=>{this.cachedSnapshot=void 0,this.flagSnapshot().catch(r=>this.config.onError(r));},onClosed:r=>{this.stream=void 0,r&&this.maybeStream(e);},projectKey:this.config.apiKey,socketFactory:this.config.socketFactory});this.stream=t,t.open();}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(me);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(t){this.queue.requeue(e),this.persistQueue(),this.config.onError(t);}finally{this.flushing=false;}}reset(){this.identity.reset(),this.cachedFlags=void 0,this.cachedSnapshot=void 0,this.membershipCache=void 0;}async shutdown(){this.shutDown=true,this.stopTimer(),this.stream?.close(),this.stream=void 0,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 t=JSON.parse(e);Array.isArray(t)&&this.queue.restore(t);}catch(e){this.config.onError(e);}}startTimer(){if(this.config.flushIntervalMs<=0)return;let e=setInterval(()=>{this.flush();},this.config.flushIntervalMs),t=e;typeof t.unref=="function"&&t.unref(),this.flushTimer=e;}stopTimer(){this.flushTimer!==void 0&&(clearInterval(this.flushTimer),this.flushTimer=void 0);}persistKey(){return `pdx.${this.config.namespace}.${ge}`}};function xt(s){return new R(s)}export{h as a,v as b,m as c,l as d,y as e,be as f,ae as g,K as h,D as i,V as j,j as k,Ee as l,z as m,Se as n,Te as o,F as p,w as q,I as r,R as s,xt as t};//# sourceMappingURL=chunk-CSIP3PZ7.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-CSIP3PZ7.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
function c(e){return `40${JSON.stringify(e)}`}function N(){return "3"}function u(e){let t=e.charAt(0),o=e.slice(1);if(t==="2")return {kind:"ping"};if(t==="1")return {kind:"disconnect"};if(t==="0"){let n=E(o);return {kind:"open",pingInterval:typeof n?.pingInterval=="number"?n.pingInterval:25e3,pingTimeout:typeof n?.pingTimeout=="number"?n.pingTimeout:2e4}}if(t!=="4")return {kind:"other"};let r=o.charAt(0),s=o.slice(1);if(r==="0")return {kind:"connected"};if(r==="1")return {kind:"disconnect"};if(r==="4"){let n=E(s);return {kind:"connectError",message:typeof n?.message=="string"?n.message:"refused"}}if(r!=="2")return {kind:"other"};let i=E(s);return !Array.isArray(i)||typeof i[0]!="string"?{kind:"other"}:{kind:"event",name:i[0],payload:i[1]}}function E(e){try{return JSON.parse(e)}catch{return null}}export{c as a,N as b,u as c};//# sourceMappingURL=chunk-V77KYPOF.js.map
|
|
2
|
+
//# sourceMappingURL=chunk-V77KYPOF.js.map
|
|
@@ -1,85 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
3
|
-
[key: string]: JsonValue;
|
|
4
|
-
};
|
|
5
|
-
type EventProperties = Record<string, JsonValue>;
|
|
6
|
-
interface EventContext {
|
|
7
|
-
locale?: string;
|
|
8
|
-
os?: string;
|
|
9
|
-
sdk?: string;
|
|
10
|
-
sdk_version?: string;
|
|
11
|
-
}
|
|
12
|
-
interface EventEnvelope {
|
|
13
|
-
context?: EventContext;
|
|
14
|
-
distinct_id: string;
|
|
15
|
-
event_id: string;
|
|
16
|
-
event_name: string;
|
|
17
|
-
properties: EventProperties;
|
|
18
|
-
schema_version: 1;
|
|
19
|
-
session_id?: string;
|
|
20
|
-
timestamp: string;
|
|
21
|
-
}
|
|
22
|
-
interface EventBatch {
|
|
23
|
-
api_key?: string;
|
|
24
|
-
events: EventEnvelope[];
|
|
25
|
-
sent_at: string;
|
|
26
|
-
}
|
|
27
|
-
interface FlagsResponse {
|
|
28
|
-
flags: Record<string, boolean>;
|
|
29
|
-
}
|
|
30
|
-
interface InboxMessage {
|
|
31
|
-
body: string;
|
|
32
|
-
createdAt: string;
|
|
33
|
-
id: string;
|
|
34
|
-
read: boolean;
|
|
35
|
-
title: string;
|
|
36
|
-
}
|
|
37
|
-
interface InboxResponse {
|
|
38
|
-
messages: InboxMessage[];
|
|
39
|
-
}
|
|
40
|
-
interface Clock {
|
|
41
|
-
now(): Date;
|
|
42
|
-
}
|
|
43
|
-
interface IdFactory {
|
|
44
|
-
uuid(): string;
|
|
45
|
-
}
|
|
46
|
-
interface StorageAdapter {
|
|
47
|
-
getItem(key: string): string | null;
|
|
48
|
-
removeItem(key: string): void;
|
|
49
|
-
setItem(key: string, value: string): void;
|
|
50
|
-
}
|
|
51
|
-
interface TransportRequest {
|
|
52
|
-
body: EventBatch;
|
|
53
|
-
projectKey: string;
|
|
54
|
-
url: string;
|
|
55
|
-
}
|
|
56
|
-
interface Transport {
|
|
57
|
-
send(request: TransportRequest): Promise<void>;
|
|
58
|
-
}
|
|
59
|
-
interface ProdantixConfig {
|
|
60
|
-
apiKey: string;
|
|
61
|
-
autocapture?: boolean;
|
|
62
|
-
clock?: Clock;
|
|
63
|
-
defaultProperties?: EventProperties | (() => EventProperties);
|
|
64
|
-
flagsHost?: string;
|
|
65
|
-
flushAt?: number;
|
|
66
|
-
flushIntervalMs?: number;
|
|
67
|
-
host: string;
|
|
68
|
-
ids?: IdFactory;
|
|
69
|
-
locale?: string;
|
|
70
|
-
maxQueueSize?: number;
|
|
71
|
-
maxRetries?: number;
|
|
72
|
-
onError?: (error: unknown) => void;
|
|
73
|
-
os?: string;
|
|
74
|
-
requestTimeoutMs?: number;
|
|
75
|
-
sdkName?: string;
|
|
76
|
-
sdkVersion?: string;
|
|
77
|
-
storage?: StorageAdapter;
|
|
78
|
-
transport?: Transport;
|
|
79
|
-
}
|
|
1
|
+
import { d as EventProperties, P as ProdantixConfig, e as FlagVariant, I as InboxMessage } from './types-68Sc11g8.js';
|
|
80
2
|
|
|
81
3
|
interface LocalFlagContext {
|
|
82
4
|
attributes?: EventProperties;
|
|
5
|
+
/** The cohorts the current distinct id belongs to. When omitted and the
|
|
6
|
+
* snapshot names a cohort, the client fetches them once per distinct id. */
|
|
7
|
+
cohorts?: string[];
|
|
83
8
|
properties?: EventProperties;
|
|
84
9
|
}
|
|
85
10
|
interface CaptureOptions {
|
|
@@ -121,6 +46,13 @@ declare class ProdantixClient {
|
|
|
121
46
|
private flushing;
|
|
122
47
|
private cachedFlags?;
|
|
123
48
|
private cachedSnapshot?;
|
|
49
|
+
private membershipCache?;
|
|
50
|
+
private stream?;
|
|
51
|
+
private shutDown;
|
|
52
|
+
/** One `$feature_flag_called` per (distinct id, flag, response) per client
|
|
53
|
+
* lifetime: the experiment engine attributes on the FIRST exposure, so a
|
|
54
|
+
* second event for the same answer would only cost the project an event. */
|
|
55
|
+
private readonly exposures;
|
|
124
56
|
constructor(config: ProdantixConfig);
|
|
125
57
|
get distinctId(): string;
|
|
126
58
|
get anonymousId(): string;
|
|
@@ -139,10 +71,23 @@ declare class ProdantixClient {
|
|
|
139
71
|
setPersonTraits(traits: PersonTraits): void;
|
|
140
72
|
getAllFlags(): Promise<Record<string, boolean>>;
|
|
141
73
|
isFeatureEnabled(key: string): Promise<boolean>;
|
|
74
|
+
/** The assigned variation for one flag, or null when the flag is unknown or
|
|
75
|
+
* carries no variations. Records the exposure either way. */
|
|
76
|
+
getVariant(key: string): Promise<FlagVariant | null>;
|
|
77
|
+
getVariantLocal(key: string, context?: LocalFlagContext): Promise<FlagVariant | null>;
|
|
78
|
+
private recordExposure;
|
|
142
79
|
getCachedFlag(key: string): boolean | undefined;
|
|
143
80
|
getLocalFlags(context?: LocalFlagContext): Promise<Record<string, boolean>>;
|
|
144
81
|
isFeatureEnabledLocal(key: string, context?: LocalFlagContext): Promise<boolean>;
|
|
82
|
+
/** The evaluation context for a local read. Memberships come from the caller
|
|
83
|
+
* when supplied, else from the server once per distinct id per snapshot
|
|
84
|
+
* TTL, and only when the snapshot names a cohort at all. */
|
|
85
|
+
private localContext;
|
|
145
86
|
private flagSnapshot;
|
|
87
|
+
/** Opens the flag stream once, when streaming was asked for and the snapshot
|
|
88
|
+
* names a gateway. A pushed change drops the cached snapshot and refetches
|
|
89
|
+
* it; a refused handshake stays closed, a dropped one reopens. */
|
|
90
|
+
private maybeStream;
|
|
146
91
|
getInbox(): Promise<InboxMessage[]>;
|
|
147
92
|
markMessageRead(messageId: string): Promise<void>;
|
|
148
93
|
flush(): Promise<void>;
|
|
@@ -157,4 +102,4 @@ declare class ProdantixClient {
|
|
|
157
102
|
}
|
|
158
103
|
declare function createClient(config: ProdantixConfig): ProdantixClient;
|
|
159
104
|
|
|
160
|
-
export { type CaptureOptions as C, type
|
|
105
|
+
export { type CaptureOptions as C, type IdentifyOptions as I, type LocalFlagContext as L, ProdantixClient as P, createClient as c };
|
|
@@ -1,85 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
type JsonValue = JsonPrimitive | JsonValue[] | {
|
|
3
|
-
[key: string]: JsonValue;
|
|
4
|
-
};
|
|
5
|
-
type EventProperties = Record<string, JsonValue>;
|
|
6
|
-
interface EventContext {
|
|
7
|
-
locale?: string;
|
|
8
|
-
os?: string;
|
|
9
|
-
sdk?: string;
|
|
10
|
-
sdk_version?: string;
|
|
11
|
-
}
|
|
12
|
-
interface EventEnvelope {
|
|
13
|
-
context?: EventContext;
|
|
14
|
-
distinct_id: string;
|
|
15
|
-
event_id: string;
|
|
16
|
-
event_name: string;
|
|
17
|
-
properties: EventProperties;
|
|
18
|
-
schema_version: 1;
|
|
19
|
-
session_id?: string;
|
|
20
|
-
timestamp: string;
|
|
21
|
-
}
|
|
22
|
-
interface EventBatch {
|
|
23
|
-
api_key?: string;
|
|
24
|
-
events: EventEnvelope[];
|
|
25
|
-
sent_at: string;
|
|
26
|
-
}
|
|
27
|
-
interface FlagsResponse {
|
|
28
|
-
flags: Record<string, boolean>;
|
|
29
|
-
}
|
|
30
|
-
interface InboxMessage {
|
|
31
|
-
body: string;
|
|
32
|
-
createdAt: string;
|
|
33
|
-
id: string;
|
|
34
|
-
read: boolean;
|
|
35
|
-
title: string;
|
|
36
|
-
}
|
|
37
|
-
interface InboxResponse {
|
|
38
|
-
messages: InboxMessage[];
|
|
39
|
-
}
|
|
40
|
-
interface Clock {
|
|
41
|
-
now(): Date;
|
|
42
|
-
}
|
|
43
|
-
interface IdFactory {
|
|
44
|
-
uuid(): string;
|
|
45
|
-
}
|
|
46
|
-
interface StorageAdapter {
|
|
47
|
-
getItem(key: string): string | null;
|
|
48
|
-
removeItem(key: string): void;
|
|
49
|
-
setItem(key: string, value: string): void;
|
|
50
|
-
}
|
|
51
|
-
interface TransportRequest {
|
|
52
|
-
body: EventBatch;
|
|
53
|
-
projectKey: string;
|
|
54
|
-
url: string;
|
|
55
|
-
}
|
|
56
|
-
interface Transport {
|
|
57
|
-
send(request: TransportRequest): Promise<void>;
|
|
58
|
-
}
|
|
59
|
-
interface ProdantixConfig {
|
|
60
|
-
apiKey: string;
|
|
61
|
-
autocapture?: boolean;
|
|
62
|
-
clock?: Clock;
|
|
63
|
-
defaultProperties?: EventProperties | (() => EventProperties);
|
|
64
|
-
flagsHost?: string;
|
|
65
|
-
flushAt?: number;
|
|
66
|
-
flushIntervalMs?: number;
|
|
67
|
-
host: string;
|
|
68
|
-
ids?: IdFactory;
|
|
69
|
-
locale?: string;
|
|
70
|
-
maxQueueSize?: number;
|
|
71
|
-
maxRetries?: number;
|
|
72
|
-
onError?: (error: unknown) => void;
|
|
73
|
-
os?: string;
|
|
74
|
-
requestTimeoutMs?: number;
|
|
75
|
-
sdkName?: string;
|
|
76
|
-
sdkVersion?: string;
|
|
77
|
-
storage?: StorageAdapter;
|
|
78
|
-
transport?: Transport;
|
|
79
|
-
}
|
|
1
|
+
import { d as EventProperties, P as ProdantixConfig, e as FlagVariant, I as InboxMessage } from './types-68Sc11g8.cjs';
|
|
80
2
|
|
|
81
3
|
interface LocalFlagContext {
|
|
82
4
|
attributes?: EventProperties;
|
|
5
|
+
/** The cohorts the current distinct id belongs to. When omitted and the
|
|
6
|
+
* snapshot names a cohort, the client fetches them once per distinct id. */
|
|
7
|
+
cohorts?: string[];
|
|
83
8
|
properties?: EventProperties;
|
|
84
9
|
}
|
|
85
10
|
interface CaptureOptions {
|
|
@@ -121,6 +46,13 @@ declare class ProdantixClient {
|
|
|
121
46
|
private flushing;
|
|
122
47
|
private cachedFlags?;
|
|
123
48
|
private cachedSnapshot?;
|
|
49
|
+
private membershipCache?;
|
|
50
|
+
private stream?;
|
|
51
|
+
private shutDown;
|
|
52
|
+
/** One `$feature_flag_called` per (distinct id, flag, response) per client
|
|
53
|
+
* lifetime: the experiment engine attributes on the FIRST exposure, so a
|
|
54
|
+
* second event for the same answer would only cost the project an event. */
|
|
55
|
+
private readonly exposures;
|
|
124
56
|
constructor(config: ProdantixConfig);
|
|
125
57
|
get distinctId(): string;
|
|
126
58
|
get anonymousId(): string;
|
|
@@ -139,10 +71,23 @@ declare class ProdantixClient {
|
|
|
139
71
|
setPersonTraits(traits: PersonTraits): void;
|
|
140
72
|
getAllFlags(): Promise<Record<string, boolean>>;
|
|
141
73
|
isFeatureEnabled(key: string): Promise<boolean>;
|
|
74
|
+
/** The assigned variation for one flag, or null when the flag is unknown or
|
|
75
|
+
* carries no variations. Records the exposure either way. */
|
|
76
|
+
getVariant(key: string): Promise<FlagVariant | null>;
|
|
77
|
+
getVariantLocal(key: string, context?: LocalFlagContext): Promise<FlagVariant | null>;
|
|
78
|
+
private recordExposure;
|
|
142
79
|
getCachedFlag(key: string): boolean | undefined;
|
|
143
80
|
getLocalFlags(context?: LocalFlagContext): Promise<Record<string, boolean>>;
|
|
144
81
|
isFeatureEnabledLocal(key: string, context?: LocalFlagContext): Promise<boolean>;
|
|
82
|
+
/** The evaluation context for a local read. Memberships come from the caller
|
|
83
|
+
* when supplied, else from the server once per distinct id per snapshot
|
|
84
|
+
* TTL, and only when the snapshot names a cohort at all. */
|
|
85
|
+
private localContext;
|
|
145
86
|
private flagSnapshot;
|
|
87
|
+
/** Opens the flag stream once, when streaming was asked for and the snapshot
|
|
88
|
+
* names a gateway. A pushed change drops the cached snapshot and refetches
|
|
89
|
+
* it; a refused handshake stays closed, a dropped one reopens. */
|
|
90
|
+
private maybeStream;
|
|
146
91
|
getInbox(): Promise<InboxMessage[]>;
|
|
147
92
|
markMessageRead(messageId: string): Promise<void>;
|
|
148
93
|
flush(): Promise<void>;
|
|
@@ -157,4 +102,4 @@ declare class ProdantixClient {
|
|
|
157
102
|
}
|
|
158
103
|
declare function createClient(config: ProdantixConfig): ProdantixClient;
|
|
159
104
|
|
|
160
|
-
export { type CaptureOptions as C, type
|
|
105
|
+
export { type CaptureOptions as C, type IdentifyOptions as I, type LocalFlagContext as L, ProdantixClient as P, createClient as c };
|
package/dist/index.cjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
'use strict';var H=Object.defineProperty;var G=(t,e,r)=>e in t?H(t,e,{enumerable:true,configurable:true,writable:true,value:r}):t[e]=r;var i=(t,e,r)=>G(t,typeof e!="symbol"?e+"":e,r);var d=class extends Error{constructor(r,s,n){super(s,n);i(this,"code");this.code=r,this.name="ProdantixError";}},m=class extends d{constructor(e){super("config",e),this.name="ConfigError";}},u=class extends d{constructor(r,s){super("validation",s);i(this,"field");this.field=r,this.name="ValidationError";}},l=class extends d{constructor(r,s,n){super("transport",r,n);i(this,"status");this.status=s,this.name="TransportError";}};function g(t){if(t)return t;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function c(){let t=globalThis.AbortController;return t?new t:void 0}var M=t=>new Promise(e=>{setTimeout(e,t);});function p(t){return t.replace(/\/+$/,"")}var y=class{constructor(){i(this,"store",new Map);}getItem(e){return this.store.get(e)??null}removeItem(e){this.store.delete(e);}setItem(e,r){this.store.set(e,r);}};var $={now:()=>new Date};function I(t){return t.toISOString()}function X(){return globalThis.crypto}function Y(t){t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=[];for(let r=0;r<16;r+=1)e.push(t[r].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 Z(){let t=X();if(t?.randomUUID)return t.randomUUID();let e=new Uint8Array(16);if(t?.getRandomValues)t.getRandomValues(e);else for(let r=0;r<16;r+=1)e[r]=Math.floor(Math.random()*256);return Y(e)}var A={uuid:Z};var W=/^pdx_pub_(?:(?:live|test)_)?[a-z0-9]{32}$/;var ee=/^(?:\$|[a-z])[a-z0-9_.]*$/;function q(t){let e=0;for(let r of t)e+=1;return e}function O(t){return W.test(t)}function te(t){return ee.test(t)}function N(t){let e=q(t);if(e<1||e>200)throw new u("distinct_id","distinct_id must be between 1 and 200 characters")}function D(t){let e=q(t);if(e<1||e>200)throw new u("event_name","event_name must be between 1 and 200 characters");if(!te(t))throw new u("event_name","event_name must match /^(\\$|[a-z])[a-z0-9_.]*$/")}var C="prodantix-js",P="0.0.1";var re=t=>{};function K(t){if(!t.apiKey||!O(t.apiKey))throw new m("apiKey must be a public project key of the form pdx_pub_<32 lowercase alphanumerics>");if(!t.host)throw new m("host is required (the ingest base URL)");let e=p(t.host),r=t.defaultProperties;return {apiKey:t.apiKey,autocapture:t.autocapture??false,clock:t.clock??$,defaultProperties:typeof r=="function"?r:()=>r??{},flagsHost:t.flagsHost?p(t.flagsHost):e,flushAt:t.flushAt??20,flushIntervalMs:t.flushIntervalMs??1e4,host:e,ids:t.ids??A,locale:t.locale,maxQueueSize:t.maxQueueSize??1e3,maxRetries:t.maxRetries??3,namespace:t.apiKey.slice(0,16),onError:t.onError??re,os:t.os,requestTimeoutMs:t.requestTimeoutMs??1e4,sdkName:t.sdkName??C,sdkVersion:t.sdkVersion??P,storage:t.storage??new y,transport:t.transport}}function L(t,e,r){D(t.eventName),N(t.distinctId);let s={distinct_id:t.distinctId,event_id:t.eventId??r.uuid(),event_name:t.eventName,properties:t.properties??{},schema_version:1,timestamp:I(t.timestamp??e.now())};return t.context&&(s.context=t.context),t.sessionId&&(s.session_id=t.sessionId),s}var f=Symbol("absent");function se(t,e){if(t==="distinct_id")return e.distinctId;let r=e.properties??{};if(Object.prototype.hasOwnProperty.call(r,t))return r[t];let s=e.attributes??{};return Object.prototype.hasOwnProperty.call(s,t)?s[t]:f}function h(t){return t===f?"undefined":String(t)}function V(t){return t===f?Number.NaN:Number(t)}function j(t){return t!==f&&t!==null&&t!==""}function z(t,e){if(!Array.isArray(e))return false;let r=h(t);return e.map(s=>String(s)).includes(r)}function F(t,e){let r=se(t.attribute,e),s=t.value;switch(t.op){case "is_set":return j(r);case "is_not_set":return !j(r);case "eq":return h(r)===h(s===void 0?f:s);case "neq":return h(r)!==h(s===void 0?f:s);case "contains":return h(r).includes(h(s===void 0?f:s));case "in":return z(r,s);case "not_in":return Array.isArray(s)?!z(r,s):false;case "gt":return E(r,s,(n,o)=>n>o);case "gte":return E(r,s,(n,o)=>n>=o);case "lt":return E(r,s,(n,o)=>n<o);case "lte":return E(r,s,(n,o)=>n<=o);default:return false}}function E(t,e,r){let s=V(t),n=e===void 0?Number.NaN:V(e);return Number.isNaN(s)||Number.isNaN(n)?false:r(s,n)}function _(t,e){let r=`${t}:${e}`,s=2166136261;for(let n=0;n<r.length;n++)s^=r.charCodeAt(n),s=Math.imul(s,16777619);return (s>>>0)%100}function J(t,e){return t.enabled?t.targeting.length>0&&!t.targeting.every(r=>F(r,e))?{enabled:false,reason:"targeting"}:t.rolloutPercentage>=100?{enabled:true,reason:"rollout_full"}:_(t.key,e.distinctId)<t.rolloutPercentage?{enabled:true,reason:"rollout"}:{enabled:false,reason:"rollout_excluded"}:{enabled:false,reason:"disabled"}}function R(t,e){let r={};for(let s of t)r[s.key]=J(s,e).enabled;return r}function Q(t,e){let r=t.variations??[],s=r[0];if(!s)return null;if(!t.enabled||t.targeting.length>0&&!t.targeting.every(a=>F(a,e)))return s;let n=_(t.key,e.distinctId),o=0;for(let a=r.length-1;a>=0;a--)if(o+=r[a].weight,n<o)return r[a];return s}function ne(t,e,r){let s=t.find(n=>n.key===e);return s?Q(s,r)?.value??null:null}var v=class{constructor(e){i(this,"fetch");i(this,"host");i(this,"projectKey");i(this,"requestTimeoutMs");this.fetch=g(e.fetch),this.host=p(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async fetchAll(e){let r=this.fetch;if(!r)throw new l("no fetch implementation available in this runtime");let s=`${this.host}/v1/flags?distinct_id=${encodeURIComponent(e)}`,n=c(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{let a=await r(s,{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 r=`${this.host}/v1/flags/snapshot`,s=c(),n=s?setTimeout(()=>s.abort(),this.requestTimeoutMs):void 0;try{let o=await e(r,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:s?.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 k=class{constructor(e,r,s){this.storage=e;this.ids=r;this.namespace=s;i(this,"anonymousId");i(this,"distinctId");i(this,"identified");let n=e.getItem(this.key("anonymous_id"));n?this.anonymousId=n:(this.anonymousId=r.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 x=class{constructor(e){i(this,"fetch");i(this,"host");i(this,"projectKey");i(this,"requestTimeoutMs");this.fetch=g(e.fetch),this.host=p(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async inbox(e){let r=this.requireFetch(),s=`${this.host}/v1/messages?distinct_id=${encodeURIComponent(e)}`,n=await this.request(r,s,{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,r){let s=this.requireFetch(),n=`${this.host}/v1/messages/read`,o=await this.request(s,n,{body:JSON.stringify({distinct_id:r,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,r,s){let n=c(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(r,{...s,signal:n?.signal})}finally{o!==void 0&&clearTimeout(o);}}};var w=class{constructor(e,r){this.maxSize=e;this.onOverflow=r;i(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 r=e===void 0?this.events.length:Math.min(e,this.events.length);return this.events.splice(0,r)}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});}};function U(t){return t>=400&&t<500&&t!==429}var b=class{constructor(e={}){i(this,"fetch");i(this,"maxRetries");i(this,"requestTimeoutMs");i(this,"baseDelayMs");i(this,"maxDelayMs");i(this,"sleep");i(this,"random");this.fetch=g(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??M,this.random=e.random??Math.random;}async send(e){let r=this.fetch;if(!r)throw new l("no fetch implementation available in this runtime");let s=JSON.stringify(e.body),n;for(let o=0;o<=this.maxRetries;o+=1){try{let a=await this.attempt(r,e,s);if(a.ok)return;if(U(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&&U(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,r,s){let n=c(),o=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{return await e(r.url,{body:s,headers:{authorization:`Bearer ${r.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 ie="queue",oe=1e3,ae=3e4,B=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},T=class{constructor(e){i(this,"config");i(this,"identity");i(this,"queue");i(this,"transport");i(this,"flagsClient");i(this,"messagesClient");i(this,"context");i(this,"flushTimer");i(this,"flushing",false);i(this,"cachedFlags");i(this,"cachedSnapshot");this.config=K(e),this.identity=new k(this.config.storage,this.config.ids,this.config.namespace),this.queue=new w(this.config.maxQueueSize,({dropped:r})=>{this.config.onError(new d("queue_overflow",`event queue overflow: dropped ${r.length} oldest event(s)`));}),this.transport=this.config.transport??new b({maxRetries:this.config.maxRetries,requestTimeoutMs:this.config.requestTimeoutMs}),this.flagsClient=new v({host:this.config.flagsHost,projectKey:this.config.apiKey,requestTimeoutMs:this.config.requestTimeoutMs}),this.messagesClient=new x({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,r={}){try{let s={...this.config.defaultProperties(),...r.properties??{}},n=L({context:this.context,distinctId:this.identity.getDistinctId(),eventName:e,properties:s,sessionId:r.sessionId,timestamp:r.timestamp},this.config.clock,this.config.ids);this.enqueue(n);}catch(s){this.config.onError(s);}}identify(e,r={}){let s=this.identity.getAnonymousId(),n=!this.identity.isIdentified(),o=this.identity.identify(e),a={};n&&o.changed&&(a.$anon_distinct_id=s);let S={...B(r.traits??{}),...r.set??{}};Object.keys(S).length>0&&(a.$set=S),this.capture("$identify",{properties:a});}alias(e){this.capture("$create_alias",{properties:{alias:e}});}group(e,r,s){let n={$group_key:r,$group_type:e};s&&(n.$set=s),this.capture("$group",{properties:n});}setPersonProperties(e,r){let s={};e&&(s.$set=e),r&&(s.$set_once=r),this.capture("$set",{properties:s});}setPersonTraits(e){let r=B(e);Object.keys(r).length!==0&&this.capture("$set",{properties:{$set:r}});}async getAllFlags(){let e=this.identity.getDistinctId(),r=await this.flagsClient.fetchAll(e);return this.cachedFlags={distinctId:e,flags:r},r}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 r=await this.flagSnapshot();return R(r.flags,{attributes:e.attributes,distinctId:this.identity.getDistinctId(),properties:e.properties})}async isFeatureEnabledLocal(e,r){return (await this.getLocalFlags(r))[e]??false}async flagSnapshot(){let e=this.config.clock.now().getTime();if(this.cachedSnapshot&&e-this.cachedSnapshot.fetchedAt<ae)return this.cachedSnapshot.snapshot;let r=await this.flagsClient.snapshot();return this.cachedSnapshot={fetchedAt:e,snapshot:r},r}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(oe);try{await this.transport.send({body:{events:e,sent_at:I(this.config.clock.now())},projectKey:this.config.apiKey,url:`${this.config.host}/v1/events`}),this.persistQueue();}catch(r){this.queue.requeue(e),this.persistQueue(),this.config.onError(r);}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 r=JSON.parse(e);Array.isArray(r)&&this.queue.restore(r);}catch(e){this.config.onError(e);}}startTimer(){if(this.config.flushIntervalMs<=0)return;let e=setInterval(()=>{this.flush();},this.config.flushIntervalMs),r=e;typeof r.unref=="function"&&r.unref(),this.flushTimer=e;}stopTimer(){this.flushTimer!==void 0&&(clearInterval(this.flushTimer),this.flushTimer=void 0);}persistKey(){return `pdx.${this.config.namespace}.${ie}`}};function le(t){return new T(t)}exports.ConfigError=m;exports.FetchTransport=b;exports.FlagsClient=v;exports.MemoryStorage=y;exports.MessagesClient=x;exports.ProdantixClient=T;exports.ProdantixError=d;exports.SDK_NAME=C;exports.SDK_VERSION=P;exports.TransportError=l;exports.ValidationError=u;exports.assignVariant=Q;exports.bucket=_;exports.createClient=le;exports.evaluateAll=R;exports.evaluateFlag=J;exports.getVariant=ne;exports.matches=F;//# sourceMappingURL=index.cjs.map
|
|
1
|
+
'use strict';var ie=Object.defineProperty;var oe=(t,e,r)=>e in t?ie(t,e,{enumerable:true,configurable:true,writable:true,value:r}):t[e]=r;var o=(t,e,r)=>oe(t,typeof e!="symbol"?e+"":e,r);var u=class extends Error{constructor(r,n,s){super(n,s);o(this,"code");this.code=r,this.name="ProdantixError";}},m=class extends u{constructor(e){super("config",e),this.name="ConfigError";}},p=class extends u{constructor(r,n){super("validation",n);o(this,"field");this.field=r,this.name="ValidationError";}},l=class extends u{constructor(r,n,s){super("transport",r,s);o(this,"status");this.status=n,this.name="TransportError";}};function y(t){if(t)return t;let e=globalThis.fetch;if(typeof e=="function")return e.bind(globalThis)}function d(){let t=globalThis.AbortController;return t?new t:void 0}var K=t=>new Promise(e=>{setTimeout(e,t);});function h(t){return t.replace(/\/+$/,"")}var v=class{constructor(){o(this,"store",new Map);}getItem(e){return this.store.get(e)??null}removeItem(e){this.store.delete(e);}setItem(e,r){this.store.set(e,r);}};var D={now:()=>new Date};function I(t){return t.toISOString()}function ae(){return globalThis.crypto}function le(t){t[6]=t[6]&15|64,t[8]=t[8]&63|128;let e=[];for(let r=0;r<16;r+=1)e.push(t[r].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 ce(){let t=ae();if(t?.randomUUID)return t.randomUUID();let e=new Uint8Array(16);if(t?.getRandomValues)t.getRandomValues(e);else for(let r=0;r<16;r+=1)e[r]=Math.floor(Math.random()*256);return le(e)}var L={uuid:ce};var ue=/^pdx_pub_(?:(?:live|test)_)?[a-z0-9]{32}$/;var de=/^(?:\$|[a-z])[a-z0-9_.]*$/;function V(t){let e=0;for(let r of t)e+=1;return e}function j(t){return ue.test(t)}function pe(t){return de.test(t)}function G(t){let e=V(t);if(e<1||e>200)throw new p("distinct_id","distinct_id must be between 1 and 200 characters")}function U(t){let e=V(t);if(e<1||e>200)throw new p("event_name","event_name must be between 1 and 200 characters");if(!pe(t))throw new p("event_name","event_name must match /^(\\$|[a-z])[a-z0-9_.]*$/")}var P="prodantix-js",R="0.0.1";var he=t=>{};function z(t){if(!t.apiKey||!j(t.apiKey))throw new m("apiKey must be a public project key of the form pdx_pub_<32 lowercase alphanumerics>");if(!t.host)throw new m("host is required (the ingest base URL)");let e=h(t.host),r=t.defaultProperties;return {apiKey:t.apiKey,autocapture:t.autocapture??false,clock:t.clock??D,defaultProperties:typeof r=="function"?r:()=>r??{},flagsHost:t.flagsHost?h(t.flagsHost):e,flushAt:t.flushAt??20,flushIntervalMs:t.flushIntervalMs??1e4,host:e,ids:t.ids??L,locale:t.locale,maxQueueSize:t.maxQueueSize??1e3,maxRetries:t.maxRetries??3,namespace:t.apiKey.slice(0,16),onError:t.onError??he,os:t.os,requestTimeoutMs:t.requestTimeoutMs??1e4,sdkName:t.sdkName??P,sdkVersion:t.sdkVersion??R,socketFactory:t.socketFactory,storage:t.storage??new v,streamFlags:t.streamFlags??false,transport:t.transport}}function H(t,e,r){U(t.eventName),G(t.distinctId);let n={distinct_id:t.distinctId,event_id:t.eventId??r.uuid(),event_name:t.eventName,properties:t.properties??{},schema_version:1,timestamp:I(t.timestamp??e.now())};return t.context&&(n.context=t.context),t.sessionId&&(n.session_id=t.sessionId),n}var g=Symbol("absent");function fe(t,e){if(t==="distinct_id")return e.distinctId;let r=e.properties??{};if(Object.prototype.hasOwnProperty.call(r,t))return r[t];let n=e.attributes??{};return Object.prototype.hasOwnProperty.call(n,t)?n[t]:g}function f(t){return t===g?"undefined":String(t)}function J(t){return t===g?Number.NaN:Number(t)}function B(t){return t!==g&&t!==null&&t!==""}function Q(t,e){if(!Array.isArray(e))return false;let r=f(t);return e.map(n=>String(n)).includes(r)}function N(t,e){let r=fe(t.attribute,e),n=t.value;switch(t.op){case "is_set":return B(r);case "is_not_set":return !B(r);case "eq":return f(r)===f(n===void 0?g:n);case "neq":return f(r)!==f(n===void 0?g:n);case "contains":return f(r).includes(f(n===void 0?g:n));case "in":return Q(r,n);case "not_in":return Array.isArray(n)?!Q(r,n):false;case "gt":return S(r,n,(s,i)=>s>i);case "gte":return S(r,n,(s,i)=>s>=i);case "lt":return S(r,n,(s,i)=>s<i);case "lte":return S(r,n,(s,i)=>s<=i);case "in_cohort":return typeof n=="string"&&n!==""&&(e.cohorts??[]).includes(n);case "not_in_cohort":return typeof n=="string"&&n!==""&&!(e.cohorts??[]).includes(n);default:return false}}function S(t,e,r){let n=J(t),s=e===void 0?Number.NaN:J(e);return Number.isNaN(n)||Number.isNaN(s)?false:r(n,s)}function $(t,e){let r=`${t}:${e}`,n=2166136261;for(let s=0;s<r.length;s++)n^=r.charCodeAt(s),n=Math.imul(n,16777619);return (n>>>0)%100}function A(t,e){return t.targeting.length===0||t.targeting.every(r=>N(r,e))}function W(t,e){let r=$(t.key,e.distinctId),n=t.variations??[];if(n.length===0)return t.rolloutPercentage>=100||r<t.rolloutPercentage?"true":"false";let s=0;for(let i=n.length-1;i>=0;i--)if(s+=n[i].weight,r<s)return n[i].key;return n[0].key}function O(t,e,r,n){for(let s of t.prerequisites??[]){if(n.includes(s.flagKey))return false;let i=e.find(c=>c.key===s.flagKey);if(!i||!i.enabled)return false;n.push(i.key);let a=O(i,e,r,n)&&A(i,r)&&W(i,r)===s.variationKey;if(n.pop(),!a)return false}return true}function b(t,e,r){return t.enabled?O(t,e,r,[t.key])?A(t,r)?t.rolloutPercentage>=100?{enabled:true,reason:"rollout_full"}:$(t.key,r.distinctId)<t.rolloutPercentage?{enabled:true,reason:"rollout"}:{enabled:false,reason:"rollout_excluded"}:{enabled:false,reason:"targeting"}:{enabled:false,reason:"prerequisite"}:{enabled:false,reason:"disabled"}}function ge(t,e){return b(t,[],e)}function M(t,e){let r={};for(let n of t)r[n.key]=b(n,t,e).enabled;return r}function k(t,e,r){let n=t.variations??[],s=n[0];if(!s)return null;if(!t.enabled||!O(t,e,r,[t.key])||!A(t,r))return s;let i=W(t,r);return n.find(a=>a.key===i)??s}function me(t,e){return k(t,[],e)}function ye(t,e,r){let n=t.find(s=>s.key===e);return n?k(n,t,r)?.value??null:null}function X(t){return t.some(e=>e.targeting.some(r=>r.op==="in_cohort"||r.op==="not_in_cohort"))}function Y(t){return `40${JSON.stringify(t)}`}function Z(){return "3"}function ee(t){let e=t.charAt(0),r=t.slice(1);if(e==="2")return {kind:"ping"};if(e==="1")return {kind:"disconnect"};if(e==="0"){let a=q(r);return {kind:"open",pingInterval:typeof a?.pingInterval=="number"?a.pingInterval:25e3,pingTimeout:typeof a?.pingTimeout=="number"?a.pingTimeout:2e4}}if(e!=="4")return {kind:"other"};let n=r.charAt(0),s=r.slice(1);if(n==="0")return {kind:"connected"};if(n==="1")return {kind:"disconnect"};if(n==="4"){let a=q(s);return {kind:"connectError",message:typeof a?.message=="string"?a.message:"refused"}}if(n!=="2")return {kind:"other"};let i=q(s);return !Array.isArray(i)||typeof i[0]!="string"?{kind:"other"}:{kind:"event",name:i[0],payload:i[1]}}function q(t){try{return JSON.parse(t)}catch{return null}}var ve="/socket.io/?EIO=4&transport=websocket",be=250,C=class{constructor(e){this.options=e;o(this,"socket",null);o(this,"heartbeat",null);o(this,"pending",null);o(this,"lastKey","");o(this,"ready",false);o(this,"closed",false);o(this,"heartbeatWindow",45e3);o(this,"factory");o(this,"setTimer");o(this,"clearTimer");this.factory=e.socketFactory??ke,this.setTimer=e.setTimer??((r,n)=>setTimeout(r,n)),this.clearTimer=e.clearTimer??(r=>clearTimeout(r));}open(){if(this.socket||this.closed)return;let e=`${this.options.host.replace(/^http/,"ws").replace(/\/+$/,"")}${ve}`,r;try{r=this.factory(e);}catch{this.options.onClosed(false);return}this.socket=r,r.onmessage=n=>this.receive(String(n.data)),r.onerror=()=>r.close(),r.onclose=()=>this.fell();}close(){this.closed=true,this.stopHeartbeat(),this.pending!==null&&this.clearTimer(this.pending),this.pending=null;let e=this.socket;this.socket=null,e?.close();}receive(e){let r=ee(e);if(r.kind==="open"){this.armHeartbeat(r.pingInterval+r.pingTimeout),this.socket?.send(Y({projectKey:this.options.projectKey}));return}if(r.kind==="ping"){this.armHeartbeat(),this.socket?.send(Z());return}if(r.kind==="connectError"||r.kind==="disconnect"){this.stopHeartbeat(),this.socket?.close();return}if(r.kind==="event"){if(r.name==="ready"){this.ready=true;return}if(r.name==="flagChange"){let n=r.payload?.key;this.lastKey=typeof n=="string"?n:"",this.pending===null&&(this.pending=this.setTimer(()=>{this.pending=null,this.options.onChange(this.lastKey);},be));}}}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 ke(t){let e=globalThis.WebSocket;if(!e)throw new Error("no WebSocket");return new e(t)}var x=class{constructor(e){o(this,"fetch");o(this,"host");o(this,"projectKey");o(this,"requestTimeoutMs");this.fetch=y(e.fetch),this.host=h(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async fetchAll(e){return (await this.fetchDecisions(e)).flags}async fetchDecisions(e){let r=this.fetch;if(!r)throw new l("no fetch implementation available in this runtime");let n=`${this.host}/v1/flags?distinct_id=${encodeURIComponent(e)}`,s=d(),i=s?setTimeout(()=>s.abort(),this.requestTimeoutMs):void 0;try{let a=await r(n,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:s?.signal});if(!a.ok)throw new l(`flags request failed with status ${a.status}`,a.status);let c=JSON.parse(await a.text());return {flags:c.flags??{},variants:c.variants??{}}}finally{i!==void 0&&clearTimeout(i);}}async snapshot(){let e=this.fetch;if(!e)throw new l("no fetch implementation available in this runtime");let r=`${this.host}/v1/flags/snapshot`,n=d(),s=n?setTimeout(()=>n.abort(),this.requestTimeoutMs):void 0;try{let i=await e(r,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:n?.signal});if(!i.ok)throw new l(`flag snapshot request failed with status ${i.status}`,i.status);let a=JSON.parse(await i.text()),c={flags:a.flags??[],generatedAt:a.generatedAt};return typeof a.socketUrl=="string"&&a.socketUrl!==""&&(c.socketUrl=a.socketUrl),c}finally{s!==void 0&&clearTimeout(s);}}async memberships(e){let r=this.fetch;if(!r)throw new l("no fetch implementation available in this runtime");let n=`${this.host}/v1/flags/memberships?distinct_id=${encodeURIComponent(e)}`,s=d(),i=s?setTimeout(()=>s.abort(),this.requestTimeoutMs):void 0;try{let a=await r(n,{headers:{authorization:`Bearer ${this.projectKey}`},method:"GET",signal:s?.signal});if(!a.ok)throw new l(`memberships request failed with status ${a.status}`,a.status);return JSON.parse(await a.text()).cohorts??[]}finally{i!==void 0&&clearTimeout(i);}}};var T=class{constructor(e,r,n){this.storage=e;this.ids=r;this.namespace=n;o(this,"anonymousId");o(this,"distinctId");o(this,"identified");let s=e.getItem(this.key("anonymous_id"));s?this.anonymousId=s:(this.anonymousId=r.uuid(),e.setItem(this.key("anonymous_id"),this.anonymousId));let i=e.getItem(this.key("distinct_id"));i?(this.distinctId=i,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 E=class{constructor(e){o(this,"fetch");o(this,"host");o(this,"projectKey");o(this,"requestTimeoutMs");this.fetch=y(e.fetch),this.host=h(e.host),this.projectKey=e.projectKey,this.requestTimeoutMs=e.requestTimeoutMs??1e4;}async inbox(e){let r=this.requireFetch(),n=`${this.host}/v1/messages?distinct_id=${encodeURIComponent(e)}`,s=await this.request(r,n,{headers:this.authHeaders(),method:"GET"});if(!s.ok)throw new l(`inbox request failed with status ${s.status}`,s.status);return JSON.parse(await s.text()).messages??[]}async markRead(e,r){let n=this.requireFetch(),s=`${this.host}/v1/messages/read`,i=await this.request(n,s,{body:JSON.stringify({distinct_id:r,message_id:e}),headers:{...this.authHeaders(),"content-type":"application/json"},method:"POST"});if(!i.ok)throw new l(`mark-read request failed with status ${i.status}`,i.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,r,n){let s=d(),i=s?setTimeout(()=>s.abort(),this.requestTimeoutMs):void 0;try{return await e(r,{...n,signal:s?.signal})}finally{i!==void 0&&clearTimeout(i);}}};var w=class{constructor(e,r){this.maxSize=e;this.onOverflow=r;o(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 r=e===void 0?this.events.length:Math.min(e,this.events.length);return this.events.splice(0,r)}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});}};function te(t){return t>=400&&t<500&&t!==429}var F=class{constructor(e={}){o(this,"fetch");o(this,"maxRetries");o(this,"requestTimeoutMs");o(this,"baseDelayMs");o(this,"maxDelayMs");o(this,"sleep");o(this,"random");this.fetch=y(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??K,this.random=e.random??Math.random;}async send(e){let r=this.fetch;if(!r)throw new l("no fetch implementation available in this runtime");let n=JSON.stringify(e.body),s;for(let i=0;i<=this.maxRetries;i+=1){try{let a=await this.attempt(r,e,n);if(a.ok)return;if(te(a.status))throw new l(`ingest rejected batch with status ${a.status}`,a.status);s=new l(`ingest transient status ${a.status}`,a.status);}catch(a){if(a instanceof l&&a.status!==void 0&&te(a.status))throw a;s=a;}i<this.maxRetries&&await this.sleep(this.backoff(i));}throw new l("ingest delivery failed after retries",void 0,{cause:s})}async attempt(e,r,n){let s=d(),i=s?setTimeout(()=>s.abort(),this.requestTimeoutMs):void 0;try{return await e(r.url,{body:n,headers:{authorization:`Bearer ${r.projectKey}`,"content-type":"application/json"},method:"POST",signal:s?.signal})}finally{i!==void 0&&clearTimeout(i);}}backoff(e){return Math.min(this.maxDelayMs,this.baseDelayMs*2**e)+this.random()*this.baseDelayMs}};var xe="queue",Ee=1e3,re=3e4,ne=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},_=class{constructor(e){o(this,"config");o(this,"identity");o(this,"queue");o(this,"transport");o(this,"flagsClient");o(this,"messagesClient");o(this,"context");o(this,"flushTimer");o(this,"flushing",false);o(this,"cachedFlags");o(this,"cachedSnapshot");o(this,"membershipCache");o(this,"stream");o(this,"shutDown",false);o(this,"exposures",new Set);this.config=z(e),this.identity=new T(this.config.storage,this.config.ids,this.config.namespace),this.queue=new w(this.config.maxQueueSize,({dropped:r})=>{this.config.onError(new u("queue_overflow",`event queue overflow: dropped ${r.length} oldest event(s)`));}),this.transport=this.config.transport??new F({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 E({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,r={}){try{let n={...this.config.defaultProperties(),...r.properties??{}},s=H({context:this.context,distinctId:this.identity.getDistinctId(),eventName:e,properties:n,sessionId:r.sessionId,timestamp:r.timestamp},this.config.clock,this.config.ids);this.enqueue(s);}catch(n){this.config.onError(n);}}identify(e,r={}){let n=this.identity.getAnonymousId(),s=!this.identity.isIdentified(),i=this.identity.identify(e),a={};s&&i.changed&&(a.$anon_distinct_id=n);let c={...ne(r.traits??{}),...r.set??{}};Object.keys(c).length>0&&(a.$set=c),this.capture("$identify",{properties:a});}alias(e){this.capture("$create_alias",{properties:{alias:e}});}group(e,r,n){let s={$group_key:r,$group_type:e};n&&(s.$set=n),this.capture("$group",{properties:s});}setPersonProperties(e,r){let n={};e&&(n.$set=e),r&&(n.$set_once=r),this.capture("$set",{properties:n});}setPersonTraits(e){let r=ne(e);Object.keys(r).length!==0&&this.capture("$set",{properties:{$set:r}});}async getAllFlags(){let e=this.identity.getDistinctId(),r=await this.flagsClient.fetchDecisions(e);return this.cachedFlags={distinctId:e,flags:r.flags,variants:r.variants??{}},r.flags}async isFeatureEnabled(e){let n=(await this.getAllFlags())[e]??false;return this.recordExposure(e,this.cachedFlags?.variants[e]?.key??String(n)),n}async getVariant(e){let r=await this.getAllFlags(),n=this.cachedFlags?.variants[e]??null;return this.recordExposure(e,n?.key??String(r[e]??false)),n}async getVariantLocal(e,r={}){let n=await this.flagSnapshot(),s=n.flags.find(se=>se.key===e),i=await this.localContext(r,n.flags),a=s?k(s,n.flags,i):null,c=s?b(s,n.flags,i).enabled:false;return this.recordExposure(e,a?.key??String(c)),a?{key:a.key,value:a.value}:null}recordExposure(e,r){let n=`${this.identity.getDistinctId()} ${e} ${r}`;this.exposures.has(n)||(this.exposures.add(n),this.capture("$feature_flag_called",{properties:{$feature_flag:e,$feature_flag_response:r}}));}getCachedFlag(e){if(!(!this.cachedFlags||this.cachedFlags.distinctId!==this.distinctId))return this.cachedFlags.flags[e]}async getLocalFlags(e={}){let r=await this.flagSnapshot();return M(r.flags,await this.localContext(e,r.flags))}async isFeatureEnabledLocal(e,r={}){let n=await this.flagSnapshot(),s=n.flags.find(c=>c.key===e),i=await this.localContext(r,n.flags),a=s?b(s,n.flags,i).enabled:false;return this.recordExposure(e,(s?k(s,n.flags,i)?.key:void 0)??String(a)),a}async localContext(e,r){let n=this.identity.getDistinctId(),s=e.cohorts;if(s===void 0&&X(r)){let i=this.config.clock.now().getTime();this.membershipCache&&this.membershipCache.distinctId===n&&i-this.membershipCache.fetchedAt<re?s=this.membershipCache.cohorts:(s=await this.flagsClient.memberships(n),this.membershipCache={cohorts:s,distinctId:n,fetchedAt:i});}return {attributes:e.attributes,cohorts:s,distinctId:n,properties:e.properties}}async flagSnapshot(){let e=this.config.clock.now().getTime();if(this.cachedSnapshot&&e-this.cachedSnapshot.fetchedAt<re)return this.cachedSnapshot.snapshot;let r=await this.flagsClient.snapshot();return this.cachedSnapshot={fetchedAt:e,snapshot:r},this.maybeStream(r),r}maybeStream(e){if(!this.config.streamFlags||this.shutDown||this.stream||!e.socketUrl)return;let r=new C({host:e.socketUrl,onChange:()=>{this.cachedSnapshot=void 0,this.flagSnapshot().catch(n=>this.config.onError(n));},onClosed:n=>{this.stream=void 0,n&&this.maybeStream(e);},projectKey:this.config.apiKey,socketFactory:this.config.socketFactory});this.stream=r,r.open();}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(Ee);try{await this.transport.send({body:{events:e,sent_at:I(this.config.clock.now())},projectKey:this.config.apiKey,url:`${this.config.host}/v1/events`}),this.persistQueue();}catch(r){this.queue.requeue(e),this.persistQueue(),this.config.onError(r);}finally{this.flushing=false;}}reset(){this.identity.reset(),this.cachedFlags=void 0,this.cachedSnapshot=void 0,this.membershipCache=void 0;}async shutdown(){this.shutDown=true,this.stopTimer(),this.stream?.close(),this.stream=void 0,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 r=JSON.parse(e);Array.isArray(r)&&this.queue.restore(r);}catch(e){this.config.onError(e);}}startTimer(){if(this.config.flushIntervalMs<=0)return;let e=setInterval(()=>{this.flush();},this.config.flushIntervalMs),r=e;typeof r.unref=="function"&&r.unref(),this.flushTimer=e;}stopTimer(){this.flushTimer!==void 0&&(clearInterval(this.flushTimer),this.flushTimer=void 0);}persistKey(){return `pdx.${this.config.namespace}.${xe}`}};function Fe(t){return new _(t)}exports.ConfigError=m;exports.FetchTransport=F;exports.FlagsClient=x;exports.MemoryStorage=v;exports.MessagesClient=E;exports.ProdantixClient=_;exports.ProdantixError=u;exports.SDK_NAME=P;exports.SDK_VERSION=R;exports.TransportError=l;exports.ValidationError=p;exports.assignVariant=me;exports.bucket=$;exports.createClient=Fe;exports.evaluateAll=M;exports.evaluateFlag=ge;exports.getVariant=ye;exports.matches=N;//# sourceMappingURL=index.cjs.map
|
|
2
2
|
//# sourceMappingURL=index.cjs.map
|