useyuva 0.0.23 → 0.0.25

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.
@@ -46,6 +46,7 @@ export interface StoredState {
46
46
  sub: string | null;
47
47
  };
48
48
  launcher?: LauncherStyle;
49
+ dismissed_status?: Record<string, string>;
49
50
  }
50
51
  export declare function storageKey(channel: string): string;
51
52
  export declare function readStored(channel: string): StoredState;
@@ -1,4 +1,4 @@
1
- class c extends Error{status;code;constructor(e,t){super(`${e} ${t}`);this.status=e;this.code=t}}async function m(e,t,n,{method:s="GET",json:i,body:r,headers:a={},token:l,blob:o}={}){if(a={...a},l)a.Authorization=`Bearer ${l}`;let h=r;if(i!==void 0)a["Content-Type"]="application/json",h=JSON.stringify(i);let u;try{u=await e(t+n,{method:s,headers:a,body:h,credentials:"omit"})}catch{throw new c(0,"network")}if(!u.ok){let p="error";try{p=(await u.json()).code??p}catch{}throw new c(u.status,p)}if(u.status===204)return;return o?await u.blob():await u.json()}function P(e,t,n){return m(e,t,`/client/v1/channels/${encodeURIComponent(n)}/lists`)}function b(e,t,n,s){return m(e,t,`/client/v1/channels/${encodeURIComponent(n)}/subscriptions`,{method:"POST",json:s})}class C{server;socketClass;handlers;#s=null;#o=0;#p=0;#t=null;#a=!0;constructor(e,t,n){this.server=e;this.socketClass=t;this.handlers=n}get connected(){return this.#s?.readyState===1}start(){if(this.#a=!1,!this.#s&&!this.#t)this.#r()}stop(){if(this.#a=!0,this.#t)clearTimeout(this.#t);this.#t=null;let e=this.#s;this.#s=null,e?.close(1000)}reset(){this.#o=0}nudge(){if(this.#a||this.#s)return;if(this.#t)clearTimeout(this.#t);this.#t=null,this.#r()}#r(){let e=this.handlers.token();if(!e||this.#a)return;let t=new URL(`${this.server}/client/v1/realtime`,globalThis.location?.href);if(t.protocol=t.protocol==="https:"?"wss:":"ws:",this.#o>0)t.searchParams.set("last_event_id",String(this.#o));let n;try{n=new this.socketClass(t,["yuva",`yuva.token.${e}`])}catch{this.#n();return}this.#s=n,n.onmessage=(s)=>{let i;try{i=JSON.parse(String(s.data))}catch{return}if(i.type==="ready")this.#p=0,this.#o=Math.max(this.#o,i.last_event_id);else if("id"in i&&typeof i.id==="number")this.#o=Math.max(this.#o,i.id);this.handlers.event(i)},n.onclose=(s)=>{if(this.#s!==n)return;if(this.#s=null,this.#a)return;if(s.code===1008){this.#o=0,this.handlers.sessionEnded();return}this.#n()}}#n(){if(this.#a||this.#t)return;let e=this.#p++;this.handlers.reconnecting(e);let t=Math.min(30000,1000*2**e)*(0.75+Math.random()*0.5);this.#t=setTimeout(()=>{this.#t=null,this.#r()},t)}}function I(e,t,n){let s=new URL("/account/connect",e);return s.searchParams.set("channel",t),s.searchParams.set("origin",n),s.href}function T(e){let t=e;return!!t&&typeof t.token==="string"&&t.token.startsWith("yuva_rd_")&&typeof t.expires_at==="string"&&!Number.isNaN(Date.parse(t.expires_at))&&typeof t.channel_key==="string"&&typeof t.origin==="string"&&!!t.reader&&typeof t.reader.initials==="string"}function R(e,t,{width:n=460,height:s=640}={}){let i=new URL(e).origin,r=location.origin,a=Math.max(0,(window.screenX??0)+((window.outerWidth??n)-n)/2),l=Math.max(0,(window.screenY??0)+((window.outerHeight??s)-s)/2),o=window.open(I(e,t,r),"yuva-reader",`popup=yes,width=${n},height=${s},left=${Math.round(a)},top=${Math.round(l)}`);if(!o)return Promise.reject(new c(0,"popup_blocked"));return new Promise((h,u)=>{let p=!1,f=()=>{p=!0,window.removeEventListener("message",S),clearInterval(v)},S=(d)=>{if(p||d.origin!==i||d.source&&d.source!==o)return;let g=d.data;if(!T(g)||g.channel_key!==t||g.origin!==r)return;f();try{o.close()}catch{}h({token:g.token,expires_at:g.expires_at,reader:g.reader})},v=setInterval(()=>{let d=!1;try{d=o.closed}catch{}if(!d)return;clearInterval(v),setTimeout(()=>{if(p)return;f(),u(new c(0,"sign_in_cancelled"))},300)},500);window.addEventListener("message",S)})}function x(e){return`yuva:${e}`}function w(e,t){return`yuva:reader:${e} ${t}`}function k(){if(typeof crypto.randomUUID==="function")return crypto.randomUUID();return Array.from(crypto.getRandomValues(new Uint8Array(16)),(e)=>e.toString(16).padStart(2,"0")).join("")}function _(e){try{let t=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),n=JSON.parse(atob(t));return typeof n.sub==="string"?n.sub:null}catch{return null}}function M(){let e=globalThis.location;if(!e||!/^https?:$/.test(e.protocol))return{};let t=e.origin+e.pathname;if(t.length>2000)return{};let n=Array.from(globalThis.document?.title.trim()??"").slice(0,300).join("").trim();return n?{page_url:t,page_title:n}:{page_url:t}}function U(){try{let t=globalThis.localStorage;if(t)return t}catch{}let e=new Map;return{getItem:(t)=>e.get(t)??null,setItem:(t,n)=>void e.set(t,n)}}function y(e){let t=new URLSearchParams;for(let[s,i]of Object.entries(e))if(i!==void 0)t.set(s,String(i));let n=t.toString();return n?`?${n}`:""}function E(e){return e.replace(/"/g,"%22").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function O(e,t,n){let s=[];for(let[i,r]of e)s.push(`--${n}\r
1
+ class c extends Error{status;code;constructor(e,t){super(`${e} ${t}`);this.status=e;this.code=t}}async function m(e,t,n,{method:s="GET",json:i,body:r,headers:a={},token:l,blob:o}={}){if(a={...a},l)a.Authorization=`Bearer ${l}`;let h=r;if(i!==void 0)a["Content-Type"]="application/json",h=JSON.stringify(i);let u;try{u=await e(t+n,{method:s,headers:a,body:h,credentials:"omit"})}catch{throw new c(0,"network")}if(!u.ok){let p="error";try{p=(await u.json()).code??p}catch{}throw new c(u.status,p)}if(u.status===204)return;return o?await u.blob():await u.json()}function P(e,t,n){return m(e,t,`/client/v1/channels/${encodeURIComponent(n)}/lists`)}function b(e,t,n,s){return m(e,t,`/client/v1/channels/${encodeURIComponent(n)}/subscriptions`,{method:"POST",json:s})}class C{server;socketClass;handlers;#s=null;#o=0;#p=0;#t=null;#a=!0;constructor(e,t,n){this.server=e;this.socketClass=t;this.handlers=n}get connected(){return this.#s?.readyState===1}start(){if(this.#a=!1,!this.#s&&!this.#t)this.#r()}stop(){if(this.#a=!0,this.#t)clearTimeout(this.#t);this.#t=null;let e=this.#s;this.#s=null,e?.close(1000)}reset(){this.#o=0}nudge(){if(this.#a||this.#s)return;if(this.#t)clearTimeout(this.#t);this.#t=null,this.#r()}#r(){let e=this.handlers.token();if(!e||this.#a)return;let t=new URL(`${this.server}/client/v1/realtime`,globalThis.location?.href);if(t.protocol=t.protocol==="https:"?"wss:":"ws:",this.#o>0)t.searchParams.set("last_event_id",String(this.#o));let n;try{n=new this.socketClass(t,["yuva",`yuva.token.${e}`])}catch{this.#n();return}this.#s=n,n.onmessage=(s)=>{let i;try{i=JSON.parse(String(s.data))}catch{return}if(i.type==="ready")this.#p=0,this.#o=Math.max(this.#o,i.last_event_id);else if("id"in i&&typeof i.id==="number")this.#o=Math.max(this.#o,i.id);this.handlers.event(i)},n.onclose=(s)=>{if(this.#s!==n)return;if(this.#s=null,this.#a)return;if(s.code===1008){this.#o=0,this.handlers.sessionEnded();return}this.#n()}}#n(){if(this.#a||this.#t)return;let e=this.#p++;this.handlers.reconnecting(e);let t=Math.min(30000,1000*2**e)*(0.75+Math.random()*0.5);this.#t=setTimeout(()=>{this.#t=null,this.#r()},t)}}function I(e,t,n){let s=new URL("/account/connect",e);return s.searchParams.set("channel",t),s.searchParams.set("origin",n),s.href}function T(e){let t=e;return!!t&&typeof t.token==="string"&&t.token.startsWith("yuva_rd_")&&typeof t.expires_at==="string"&&!Number.isNaN(Date.parse(t.expires_at))&&typeof t.channel_key==="string"&&typeof t.origin==="string"&&!!t.reader&&typeof t.reader.initials==="string"}function R(e,t,{width:n=460,height:s=640}={}){let i=new URL(e).origin,r=location.origin,a=Math.max(0,(window.screenX??0)+((window.outerWidth??n)-n)/2),l=Math.max(0,(window.screenY??0)+((window.outerHeight??s)-s)/2),o=window.open(I(e,t,r),"yuva-reader",`popup=yes,width=${n},height=${s},left=${Math.round(a)},top=${Math.round(l)}`);if(!o)return Promise.reject(new c(0,"popup_blocked"));return new Promise((h,u)=>{let p=!1,S=()=>{p=!0,window.removeEventListener("message",f),clearInterval(v)},f=(d)=>{if(p||d.origin!==i||d.source&&d.source!==o)return;let g=d.data;if(!T(g)||g.channel_key!==t||g.origin!==r)return;S();try{o.close()}catch{}h({token:g.token,expires_at:g.expires_at,reader:g.reader})},v=setInterval(()=>{let d=!1;try{d=o.closed}catch{}if(!d)return;clearInterval(v),setTimeout(()=>{if(p)return;S(),u(new c(0,"sign_in_cancelled"))},300)},500);window.addEventListener("message",f)})}function x(e){return`yuva:${e}`}function w(e,t){return`yuva:reader:${e} ${t}`}function k(){if(typeof crypto.randomUUID==="function")return crypto.randomUUID();return Array.from(crypto.getRandomValues(new Uint8Array(16)),(e)=>e.toString(16).padStart(2,"0")).join("")}function _(e){try{let t=(e.split(".")[1]??"").replace(/-/g,"+").replace(/_/g,"/"),n=JSON.parse(atob(t));return typeof n.sub==="string"?n.sub:null}catch{return null}}function M(){let e=globalThis.location;if(!e||!/^https?:$/.test(e.protocol))return{};let t=e.origin+e.pathname;if(t.length>2000)return{};let n=Array.from(globalThis.document?.title.trim()??"").slice(0,300).join("").trim();return n?{page_url:t,page_title:n}:{page_url:t}}function U(){try{let t=globalThis.localStorage;if(t)return t}catch{}let e=new Map;return{getItem:(t)=>e.get(t)??null,setItem:(t,n)=>void e.set(t,n)}}function y(e){let t=new URLSearchParams;for(let[s,i]of Object.entries(e))if(i!==void 0)t.set(s,String(i));let n=t.toString();return n?`?${n}`:""}function E(e){return e.replace(/"/g,"%22").replace(/\r/g,"%0D").replace(/\n/g,"%0A")}function O(e,t,n){let s=[];for(let[i,r]of e)s.push(`--${n}\r
2
2
  Content-Disposition: form-data; name="${i}"\r
3
3
  \r
4
4
  ${r}\r
@@ -8,4 +8,4 @@ Content-Type: ${i.type||"application/octet-stream"}\r
8
8
  \r
9
9
  `,i,`\r
10
10
  `)}return s.push(`--${n}--\r
11
- `),new Blob(s)}class D{server;channel;#s;#o;#p;#t;#a;#r=null;#n=null;#g=null;#m=null;#i=null;#c;#C=new Map;constructor(e){this.server=e.server.replace(/\/+$/,""),this.channel=e.channel,this.#s=e.fetch??((t,n)=>fetch(t,n)),this.#o=e.WebSocket??globalThis.WebSocket,this.#p=e.storage??U(),this.#t=e.identityToken??null,this.#a=e.idempotencyKeys??typeof globalThis.document>"u"}get session(){return this.#n}get token(){return this.#r}get connected(){return this.#i?.connected??!1}on(e,t){let n=this.#C.get(e);if(!n)this.#C.set(e,n=new Set);return n.add(t),()=>void n.delete(t)}#l(e,t){for(let n of this.#C.get(e)??[])n(t)}stored(){try{let e=this.#p.getItem(x(this.channel));return e?JSON.parse(e):{}}catch{return{}}}#y(e){try{this.#p.setItem(x(this.channel),JSON.stringify(e))}catch{}}channelSettings(){return this.#h(`/client/v1/channels/${encodeURIComponent(this.channel)}`)}ratePage(e){return this.#h(`/client/v1/channels/${encodeURIComponent(this.channel)}/page-ratings`,{method:"POST",json:e})}lists(){return P(this.#s,this.server,this.channel)}subscribe(e){return b(this.#s,this.server,this.channel,e)}subscriptions(){return this.#e("/client/v1/subscriptions")}subscribeList(e,t){return this.#e(`/client/v1/subscriptions/${encodeURIComponent(e)}`,{method:"PUT",json:t})}unsubscribeList(e){return this.#e(`/client/v1/subscriptions/${encodeURIComponent(e)}`,{method:"DELETE"})}setIdentityToken(e){this.#t=e,this.reset()}start(){if(this.#n)return Promise.resolve(this.#n);return this.#g??=this.#P(!1).then((e)=>(this.#l("session",{session:e,renewed:!1}),e)).finally(()=>{this.#g=null}),this.#g}async refresh(){let e=await this.#e("/client/v1/session");return this.#n={...this.#n,...e},this.#l("session",{session:this.#n,renewed:!1}),this.#n}reset(){this.#i?.stop(),this.#i?.reset(),this.#g=null,this.#m=null,this.#r=null,this.#n=null}async signOut(){let e=this.#r;this.reset();let t=this.stored();if(delete t.session,this.#y(t),e)await this.#h("/client/v1/session",{method:"DELETE",token:e}).catch(()=>{return})}async connect(){if(!this.#o)throw Error("Yuva: no WebSocket in this runtime; pass options.WebSocket");if(await this.start(),this.#i??=new C(this.server,this.#o,{token:()=>this.#r,event:(e)=>{if(e.type==="ready")this.#l("connection",{state:"open",attempt:0});this.#l("event",e)},sessionEnded:()=>void this.#v().catch(()=>this.#i?.nudge()),reconnecting:(e)=>{if(this.#l("connection",{state:"reconnecting",attempt:e}),e===2)this.#e("/client/v1/session").catch(()=>{return})}}),!this.#i.connected)this.#l("connection",{state:"connecting",attempt:0});this.#i.start()}disconnect(){this.#i?.stop(),this.#l("connection",{state:"closed",attempt:0})}reconnect(){this.#i?.nudge()}listConversations(e={}){return this.#e(`/client/v1/conversations${y({...e})}`)}getConversation(e){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}`)}startConversation(e){let t=e.page_url===void 0?{...e,...M()}:e;return this.#e("/client/v1/conversations",this.#S(t))}listMessages(e,t={}){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/messages${y({...t})}`)}sendMessage(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/messages`,this.#S(t))}markRead(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/read`,{method:"POST",json:t?{message_id:t}:{}})}rate(e,t,n){let s={rating:t,comment:n?.trim()||void 0};return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/rating`,{method:"POST",json:s})}setTyping(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/typing`,{method:"POST",json:{typing:t}})}setEmail(e){return this.#e("/client/v1/contact/email",{method:"PUT",json:{email:e}})}attachment(e){return this.#e(`/client/v1/attachments/${encodeURIComponent(e)}`,{blob:!0})}sendFeedback(e){let t=e.client_id??k();return this.#e("/client/v1/feedback",{method:"POST",headers:this.#f(t),json:{...e,client_id:t}})}get reader(){if(this.#c===void 0)try{let e=this.#p.getItem(w(this.server,this.channel));this.#c=e?JSON.parse(e):null}catch{this.#c=null}if(this.#c&&Date.parse(this.#c.expires_at)<=Date.now()+30000)this.#d(null);return this.#c}#d(e){let t=this.#c?.token!==e?.token;this.#c=e;try{this.#p.setItem(w(this.server,this.channel),e?JSON.stringify(e):"")}catch{}if(t)this.#l("reader",e)}readerSignIn(e){return R(this.server,this.channel,e).then((t)=>(this.#d(t),t))}setReader(e){this.#d(e)}async readerSignOut(){let e=this.reader?.token;if(this.#d(null),e)await this.#h("/client/v1/reader-token",{method:"DELETE",token:e}).catch(()=>{return})}listDiscussions(e,t={}){return this.#u(`/client/v1/channels/${encodeURIComponent(this.channel)}/discussions${y({page:e,...t})}`,{},!1)}getDiscussion(e){return this.#u(`/client/v1/channels/${encodeURIComponent(this.channel)}/discussions/${encodeURIComponent(e)}`,{},!1)}startDiscussion(e){return this.#u("/client/v1/discussions",{method:"POST",json:e})}replyToDiscussion(e,t){return this.#u(`/client/v1/discussions/${encodeURIComponent(e)}/posts`,{method:"POST",json:t})}editDiscussionPost(e,t){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}`,{method:"PATCH",json:t})}deleteDiscussionPost(e){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}`,{method:"DELETE"})}voteDiscussionPost(e,t=!0){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}/vote`,{method:t?"PUT":"DELETE"})}followDiscussion(e,t=!0){return this.#u(`/client/v1/discussions/${encodeURIComponent(e)}/follow`,{method:t?"PUT":"DELETE"})}acceptDiscussionAnswer(e,t){let n=`/client/v1/discussions/${encodeURIComponent(e)}/answer`;return this.#u(n,t?{method:"PUT",json:{post_id:t}}:{method:"DELETE"})}async discussionWriter(){if(this.reader)return"reader";if(this.#n)return this.#n.contact.identified?"contact":null;return await this.#t?.()?"contact":null}async#u(e,t,n=!0){let s=this.reader;if(s)try{return await this.#h(e,{...t,token:s.token})}catch(r){if(!(r instanceof c)||r.status!==401||this.#c?.token!==s.token)throw r;if(this.#d(null),n)throw new c(403,"sign_in_required")}if(await this.discussionWriter()==="contact")return this.#e(e,t);if(n)throw new c(403,"sign_in_required");return this.#h(e,t)}#f(e){return this.#a&&/^[\x20-\x7e]{1,255}$/.test(e)?{"Idempotency-Key":e}:{}}#S({body:e,subject:t,files:n=[],client_id:s=k(),...i}){let r=this.#f(s),a=i.page_url??void 0,l=a?i.page_title:void 0;if(n.length===0)return{method:"POST",headers:r,json:{body:e,subject:t,client_id:s,page_url:a,page_title:l}};let o=[];if(t)o.push(["subject",t]);if(e)o.push(["body",e]);if(o.push(["client_id",s]),a)o.push(["page_url",a]);if(l)o.push(["page_title",l]);let h=`yuva-${s.replace(/[^\w-]/g,"").slice(0,60)}-${s.length}`;return r["Content-Type"]=`multipart/form-data; boundary=${h}`,{method:"POST",headers:r,body:O(o,n,h)}}#h(e,t){return m(this.#s,this.server,e,t)}async#e(e,t={},n=!0){if(!this.#r)await this.start();try{return await this.#h(e,{...t,token:this.#r})}catch(s){if(!n||!(s instanceof c)||s.status!==401)throw s;return await this.#v(),this.#e(e,t,!1)}}#v(){return this.#m??=(async()=>{let e=await this.#P(!0);if(this.#i)this.#i.stop(),this.#i.reset(),this.#i.start();this.#l("session",{session:e,renewed:!0})})().finally(()=>{this.#m=null}),this.#m}async#P(e){let t=this.stored(),n=await this.#t?.()||null,s=n?_(n):null,i=t.session;if(!e&&i&&i.sub===s&&Date.parse(i.expires_at)>Date.now()+60000)try{let o=await this.#h("/client/v1/session",{token:i.token});return this.#b(o,i.token,s)}catch(o){if(!(o instanceof c)||o.status!==401&&o.status!==403)throw o}let r=await this.#h("/client/v1/session",{method:"POST",json:{channel_key:this.channel,identity_token:n??void 0,visitor_id:t.visitor_id}}),{token:a,...l}=r;return this.#b(l,a,s)}#b(e,t,n){this.#r=t,this.#n=e;let s=this.stored();if(s.session={token:t,expires_at:e.expires_at,sub:n},e.visitor_id)s.visitor_id=e.visitor_id;else if(e.contact.identified)delete s.visitor_id;return this.#y(s),e}}function L(e){return new D(e)}export{L as createYuvaClient};
11
+ `),new Blob(s)}class D{server;channel;#s;#o;#p;#t;#a;#r=null;#n=null;#g=null;#m=null;#i=null;#c;#C=new Map;constructor(e){this.server=e.server.replace(/\/+$/,""),this.channel=e.channel,this.#s=e.fetch??((t,n)=>fetch(t,n)),this.#o=e.WebSocket??globalThis.WebSocket,this.#p=e.storage??U(),this.#t=e.identityToken??null,this.#a=e.idempotencyKeys??typeof globalThis.document>"u"}get session(){return this.#n}get token(){return this.#r}get connected(){return this.#i?.connected??!1}on(e,t){let n=this.#C.get(e);if(!n)this.#C.set(e,n=new Set);return n.add(t),()=>void n.delete(t)}#l(e,t){for(let n of this.#C.get(e)??[])n(t)}stored(){try{let e=this.#p.getItem(x(this.channel));return e?JSON.parse(e):{}}catch{return{}}}#y(e){try{this.#p.setItem(x(this.channel),JSON.stringify(e))}catch{}}channelSettings(){return this.#h(`/client/v1/channels/${encodeURIComponent(this.channel)}`)}ratePage(e){return this.#h(`/client/v1/channels/${encodeURIComponent(this.channel)}/page-ratings`,{method:"POST",json:e})}lists(){return P(this.#s,this.server,this.channel)}subscribe(e){return b(this.#s,this.server,this.channel,e)}subscriptions(){return this.#e("/client/v1/subscriptions")}subscribeList(e,t){return this.#e(`/client/v1/subscriptions/${encodeURIComponent(e)}`,{method:"PUT",json:t})}unsubscribeList(e){return this.#e(`/client/v1/subscriptions/${encodeURIComponent(e)}`,{method:"DELETE"})}setIdentityToken(e){this.#t=e,this.reset()}start(){if(this.#n)return Promise.resolve(this.#n);return this.#g??=this.#P(!1).then((e)=>(this.#l("session",{session:e,renewed:!1}),e)).finally(()=>{this.#g=null}),this.#g}async refresh(){let e=await this.#e("/client/v1/session");return this.#n={...this.#n,...e},this.#l("session",{session:this.#n,renewed:!1}),this.#n}reset(){this.#i?.stop(),this.#i?.reset(),this.#g=null,this.#m=null,this.#r=null,this.#n=null}async signOut(){let e=this.#r;this.reset();let t=this.stored();if(delete t.session,this.#y(t),e)await this.#h("/client/v1/session",{method:"DELETE",token:e}).catch(()=>{return})}async connect(){if(!this.#o)throw Error("Yuva: no WebSocket in this runtime; pass options.WebSocket");if(await this.start(),this.#i??=new C(this.server,this.#o,{token:()=>this.#r,event:(e)=>{if(e.type==="ready")this.#l("connection",{state:"open",attempt:0});this.#l("event",e)},sessionEnded:()=>void this.#v().catch(()=>this.#i?.nudge()),reconnecting:(e)=>{if(this.#l("connection",{state:"reconnecting",attempt:e}),e===2)this.#e("/client/v1/session").catch(()=>{return})}}),!this.#i.connected)this.#l("connection",{state:"connecting",attempt:0});this.#i.start()}disconnect(){this.#i?.stop(),this.#l("connection",{state:"closed",attempt:0})}reconnect(){this.#i?.nudge()}listConversations(e={}){return this.#e(`/client/v1/conversations${y({...e})}`)}getConversation(e){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}`)}startConversation(e){let t=e.page_url===void 0?{...e,...M()}:e;return this.#e("/client/v1/conversations",this.#f(t))}listMessages(e,t={}){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/messages${y({...t})}`)}sendMessage(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/messages`,this.#f(t))}markRead(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/read`,{method:"POST",json:t?{message_id:t}:{}})}rate(e,t,n){let s={rating:t,comment:n?.trim()||void 0};return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/rating`,{method:"POST",json:s})}setTyping(e,t){return this.#e(`/client/v1/conversations/${encodeURIComponent(e)}/typing`,{method:"POST",json:{typing:t}})}setEmail(e){return this.#e("/client/v1/contact/email",{method:"PUT",json:{email:e}})}attachment(e){return this.#e(`/client/v1/attachments/${encodeURIComponent(e)}`,{blob:!0})}sendFeedback(e){let t=e.client_id??k();return this.#e("/client/v1/feedback",{method:"POST",headers:this.#S(t),json:{...e,client_id:t}})}get reader(){if(this.#c===void 0)try{let e=this.#p.getItem(w(this.server,this.channel));this.#c=e?JSON.parse(e):null}catch{this.#c=null}if(this.#c&&Date.parse(this.#c.expires_at)<=Date.now()+30000)this.#d(null);return this.#c}#d(e){let t=this.#c?.token!==e?.token;this.#c=e;try{this.#p.setItem(w(this.server,this.channel),e?JSON.stringify(e):"")}catch{}if(t)this.#l("reader",e)}readerSignIn(e){return R(this.server,this.channel,e).then((t)=>(this.#d(t),t))}setReader(e){this.#d(e)}async readerSignOut(){let e=this.reader?.token;if(this.#d(null),e)await this.#h("/client/v1/reader-token",{method:"DELETE",token:e}).catch(()=>{return})}listDiscussions(e,t={}){return this.#u(`/client/v1/channels/${encodeURIComponent(this.channel)}/discussions${y({page:e,...t})}`,{},!1)}getDiscussion(e){return this.#u(`/client/v1/channels/${encodeURIComponent(this.channel)}/discussions/${encodeURIComponent(e)}`,{},!1)}startDiscussion(e){return this.#u("/client/v1/discussions",{method:"POST",json:e})}replyToDiscussion(e,t){return this.#u(`/client/v1/discussions/${encodeURIComponent(e)}/posts`,{method:"POST",json:t})}editDiscussionPost(e,t){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}`,{method:"PATCH",json:t})}deleteDiscussionPost(e){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}`,{method:"DELETE"})}voteDiscussionPost(e,t=!0){return this.#u(`/client/v1/discussion-posts/${encodeURIComponent(e)}/vote`,{method:t?"PUT":"DELETE"})}followDiscussion(e,t=!0){return this.#u(`/client/v1/discussions/${encodeURIComponent(e)}/follow`,{method:t?"PUT":"DELETE"})}acceptDiscussionAnswer(e,t){let n=`/client/v1/discussions/${encodeURIComponent(e)}/answer`;return this.#u(n,t?{method:"PUT",json:{post_id:t}}:{method:"DELETE"})}async discussionWriter(){if(this.reader)return"reader";if(this.#n)return this.#n.contact.identified?"contact":null;return await this.#t?.()?"contact":null}async#u(e,t,n=!0){let s=this.reader;if(s)try{return await this.#h(e,{...t,token:s.token})}catch(r){if(!(r instanceof c)||r.status!==401||this.#c?.token!==s.token)throw r;if(this.#d(null),n)throw new c(403,"sign_in_required")}if(await this.discussionWriter()==="contact")return this.#e(e,t);if(n)throw new c(403,"sign_in_required");return this.#h(e,t)}#S(e){return this.#a&&/^[\x20-\x7e]{1,255}$/.test(e)?{"Idempotency-Key":e}:{}}#f({body:e,subject:t,files:n=[],client_id:s=k(),...i}){let r=this.#S(s),a=i.page_url??void 0,l=a?i.page_title:void 0;if(n.length===0)return{method:"POST",headers:r,json:{body:e,subject:t,client_id:s,page_url:a,page_title:l}};let o=[];if(t)o.push(["subject",t]);if(e)o.push(["body",e]);if(o.push(["client_id",s]),a)o.push(["page_url",a]);if(l)o.push(["page_title",l]);let h=`yuva-${s.replace(/[^\w-]/g,"").slice(0,60)}-${s.length}`;return r["Content-Type"]=`multipart/form-data; boundary=${h}`,{method:"POST",headers:r,body:O(o,n,h)}}#h(e,t){return m(this.#s,this.server,e,t)}async#e(e,t={},n=!0){if(!this.#r)await this.start();try{return await this.#h(e,{...t,token:this.#r})}catch(s){if(!n||!(s instanceof c)||s.status!==401)throw s;return await this.#v(),this.#e(e,t,!1)}}#v(){return this.#m??=(async()=>{let e=await this.#P(!0);if(this.#i)this.#i.stop(),this.#i.reset(),this.#i.start();this.#l("session",{session:e,renewed:!0})})().finally(()=>{this.#m=null}),this.#m}async#P(e){let t=this.stored(),n=await this.#t?.()||null,s=n?_(n):null,i=t.session;if(!e&&i&&i.sub===s&&Date.parse(i.expires_at)>Date.now()+60000)try{let o=await this.#h("/client/v1/session",{token:i.token});return this.#b(o,i.token,s)}catch(o){if(!(o instanceof c)||o.status!==401&&o.status!==403)throw o}let r=await this.#h("/client/v1/session",{method:"POST",json:{channel_key:this.channel,identity_token:n??void 0,visitor_id:t.visitor_id}}),{token:a,...l}=r;return this.#b(l,a,s)}#b(e,t,n){this.#r=t,this.#n=e;let s=this.stored();if(s.session={token:t,expires_at:e.expires_at,sub:n},e.visitor_id)s.visitor_id=e.visitor_id;else if(e.contact.identified)delete s.visitor_id;return this.#y(s),e}}function L(e){return new D(e)}export{L as createYuvaClient};