useyuva 0.0.12 → 0.0.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +244 -2
- package/dist/esm/chat.js +2 -2
- package/dist/esm/docs.js +4 -4
- package/dist/esm/h3.js +1 -0
- package/dist/esm/{index-c6q8br7d.js → index-9vqd1b2a.js} +1 -1
- package/dist/esm/index-qcd538se.js +2 -0
- package/dist/esm/index-r9f9ttb2.js +2 -0
- package/dist/esm/nitro/module.js +39 -0
- package/dist/esm/nitro/runtime/core.js +64 -0
- package/dist/esm/nitro/runtime/define.js +3 -0
- package/dist/esm/nitro/runtime/identity.js +3 -0
- package/dist/esm/nitro/runtime/plugin.js +3 -0
- package/dist/esm/nitro/runtime/webhook.js +3 -0
- package/dist/esm/nitro/setup.js +65 -0
- package/dist/esm/nuxt/module.js +64 -2
- package/dist/esm/nuxt/runtime/components.js +8 -1
- package/dist/esm/server.js +1 -0
- package/dist/esm/subscribe.js +2 -2
- package/dist/esm/{thread-btm71nxt.js → thread-gx5pssds.js} +1 -1
- package/dist/esm/{yuva-chat-kf9vz8r3.js → yuva-chat-025wzr6w.js} +2 -2
- package/dist/types/h3.d.ts +36 -0
- package/dist/types/nitro/module.d.ts +8 -0
- package/dist/types/nitro/runtime/core.d.ts +41 -0
- package/dist/types/nitro/runtime/define.d.ts +21 -0
- package/dist/types/nitro/setup.d.ts +36 -0
- package/dist/types/nuxt/module.d.ts +17 -3
- package/dist/types/server/analytics.d.ts +52 -0
- package/dist/types/server/encoding.d.ts +6 -0
- package/dist/types/server/identity.d.ts +14 -0
- package/dist/types/server/webhook.d.ts +28 -0
- package/dist/types/server.d.ts +3 -0
- package/dist/types/styles.d.ts +2 -0
- package/dist/yuva-chat.js +6 -6
- package/dist/yuva-docs.js +6 -6
- package/dist/yuva-subscribe.js +2 -2
- package/dist/yuva.js +2 -2
- package/package.json +26 -2
- package/dist/esm/index-98r96a7e.js +0 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{randomId2,createYuvaClient2}from"./index-6brgxahe.js";import{richText}from"./index-jdxce2se.js";import{ApiError2}from"./index-gk84nm8f.js";import{launcherOf,readStored,writeStored}from"./index-
|
|
1
|
+
import{randomId2,createYuvaClient2}from"./index-6brgxahe.js";import{richText}from"./index-jdxce2se.js";import{ApiError2}from"./index-gk84nm8f.js";import{addStyles,launcherOf,readStored,writeStored}from"./index-r9f9ttb2.js";import{setupI18n}from"@lingui/core";var messages=JSON.parse(`{"-HY5kX":["New conversation"],"-f5Tkb":["Bad"],"09Tv5j":["Reconnecting…"],"0XGLbP":["Your sign-in has expired. Reload the page and try again."],"1EICzz":["We're away right now"],"4TqZiz":["Could not send your rating. Try again."],"6Uau97":["Skip"],"6gRgw8":["Retry"],"6lGaum":["Seen"],"ASr-r0":["Show older conversations"],"Amai22":["Chat is not available right now."],"E_qvzP":["Enter a valid e-mail address."],"GQVIIl":["You seem to be offline."],"JkW3Ph":["This file type is not accepted."],"JlFcis":["Send"],"KDw4GX":["Try again"],"M62PBt":["Nobody is available right now. Leave your e-mail and we'll send the reply there too."],"N7m8E-":["Attach files"],"NBdIgR":["Comment"],"OEEQKT":["Good"],"Pwqkdw":["Loading…"],"PxYAul":["Typing…"],"RzWUUK":["Write a message…"],"S63MQu":["All conversations"],"SOk0EB":["Thanks for your feedback"],"Sad2tK":["Sending…"],"SdV5Cn":["Send us a message and we will reply here."],"UY1vmE":["Attachment"],"VggdQJ":["Usually replies in ",["duration"]],"XJURKP":["E-mail address"],"YyNOE7":["Conversation"],"ZxJcgC":["Could not save your e-mail address. Try again."],"axQ1h6":["Anything you'd like to add? (optional)"],"eOu9Px":["The file is too large."],"h69WC6":["Sent"],"iGNUZJ":["Thanks! We'll e-mail you at ",["known"]," if you're gone when we reply."],"meAa31":["No conversations yet"],"nhTADq":["We'll reply as soon as we can"],"njBr8W":["you@example.com"],"oXOSPE":["Online"],"t7TeQU":["Messages"],"tHaDPf":[["name"]," is typing…"],"tfDRzk":["Save"],"tzsBOP":["Too many attempts. Wait a moment and try again."],"uA8iBc":["How did we do?"],"upFvcp":["Not sent."],"w61W3L":["Remove ",["0"]],"xDAtGP":["Message"],"ydzYKJ":["You:"],"yz7wBu":["Close"],"zLzEI3":["Sign in to chat with us."]}`);var messages2=JSON.parse('{"-HY5kX":["Neue Unterhaltung"],"-f5Tkb":["Schlecht"],"09Tv5j":["Verbindung wird wiederhergestellt…"],"0XGLbP":["Ihre Anmeldung ist abgelaufen. Laden Sie die Seite neu und versuchen Sie es erneut."],"1EICzz":["Wir sind gerade nicht da"],"4TqZiz":["Ihre Bewertung konnte nicht gesendet werden. Versuchen Sie es erneut."],"6Uau97":["Überspringen"],"6gRgw8":["Erneut versuchen"],"6lGaum":["Gesehen"],"ASr-r0":["Ältere Unterhaltungen anzeigen"],"Amai22":["Der Chat ist gerade nicht verfügbar."],"E_qvzP":["Geben Sie eine gültige E-Mail-Adresse ein."],"GQVIIl":["Sie scheinen offline zu sein."],"JkW3Ph":["Dieser Dateityp wird nicht akzeptiert."],"JlFcis":["Senden"],"KDw4GX":["Erneut versuchen"],"M62PBt":["Gerade ist niemand erreichbar. Hinterlassen Sie Ihre E-Mail-Adresse, dann senden wir die Antwort auch dorthin."],"N7m8E-":["Dateien anhängen"],"NBdIgR":["Kommentar"],"OEEQKT":["Gut"],"Pwqkdw":["Wird geladen…"],"PxYAul":["Schreibt…"],"RzWUUK":["Nachricht schreiben…"],"S63MQu":["Alle Unterhaltungen"],"SOk0EB":["Danke für Ihr Feedback"],"Sad2tK":["Wird gesendet…"],"SdV5Cn":["Schreiben Sie uns, wir antworten hier."],"UY1vmE":["Anhang"],"VggdQJ":["Übliche Antwortzeit: ",["duration"]],"XJURKP":["E-Mail-Adresse"],"YyNOE7":["Unterhaltung"],"ZxJcgC":["Ihre E-Mail-Adresse konnte nicht gespeichert werden. Versuchen Sie es erneut."],"axQ1h6":["Möchten Sie noch etwas ergänzen? (optional)"],"eOu9Px":["Die Datei ist zu groß."],"h69WC6":["Gesendet"],"iGNUZJ":["Danke! Falls Sie nicht mehr da sind, wenn wir antworten, schreiben wir Ihnen an ",["known"],"."],"meAa31":["Noch keine Unterhaltungen"],"nhTADq":["Wir antworten so schnell wie möglich"],"njBr8W":["sie@beispiel.de"],"oXOSPE":["Online"],"t7TeQU":["Nachrichten"],"tHaDPf":[["name"]," schreibt…"],"tfDRzk":["Speichern"],"tzsBOP":["Zu viele Versuche. Warten Sie einen Moment und versuchen Sie es erneut."],"uA8iBc":["Wie zufrieden waren Sie?"],"upFvcp":["Nicht gesendet."],"w61W3L":[["0"]," entfernen"],"xDAtGP":["Nachricht"],"ydzYKJ":["Sie:"],"yz7wBu":["Schließen"],"zLzEI3":["Melden Sie sich an, um mit uns zu chatten."]}');var messages3=JSON.parse('{"-HY5kX":["Yeni konuşma"],"-f5Tkb":["Kötü"],"09Tv5j":["Yeniden bağlanıyor…"],"0XGLbP":["Oturumunuzun süresi doldu. Sayfayı yenileyip tekrar deneyin."],"1EICzz":["Şu anda uzaktayız"],"4TqZiz":["Değerlendirmeniz gönderilemedi. Tekrar deneyin."],"6Uau97":["Geç"],"6gRgw8":["Tekrar dene"],"6lGaum":["Görüldü"],"ASr-r0":["Eski konuşmaları göster"],"Amai22":["Sohbet şu anda kullanılamıyor."],"E_qvzP":["Geçerli bir e-posta adresi girin."],"GQVIIl":["Çevrimdışı görünüyorsunuz."],"JkW3Ph":["Bu dosya türü kabul edilmiyor."],"JlFcis":["Gönder"],"KDw4GX":["Tekrar dene"],"M62PBt":["Şu anda müsait kimse yok. E-posta adresinizi bırakın, yanıtı oraya da gönderelim."],"N7m8E-":["Dosya ekle"],"NBdIgR":["Yorum"],"OEEQKT":["İyi"],"Pwqkdw":["Yükleniyor…"],"PxYAul":["Yazıyor…"],"RzWUUK":["Bir mesaj yazın…"],"S63MQu":["Tüm konuşmalar"],"SOk0EB":["Geri bildiriminiz için teşekkürler"],"Sad2tK":["Gönderiliyor…"],"SdV5Cn":["Bize bir mesaj gönderin, yanıtımız burada görünecek."],"UY1vmE":["Ek"],"VggdQJ":["Genellikle ",["duration"]," içinde yanıt verir"],"XJURKP":["E-posta adresi"],"YyNOE7":["Konuşma"],"ZxJcgC":["E-posta adresiniz kaydedilemedi. Tekrar deneyin."],"axQ1h6":["Eklemek istediğiniz bir şey var mı? (isteğe bağlı)"],"eOu9Px":["Dosya çok büyük."],"h69WC6":["Gönderildi"],"iGNUZJ":["Teşekkürler! Yanıtladığımızda burada değilseniz ",["known"]," adresine e-posta göndereceğiz."],"meAa31":["Henüz konuşma yok"],"nhTADq":["En kısa sürede yanıt vereceğiz"],"njBr8W":["siz@ornek.com"],"oXOSPE":["Çevrimiçi"],"t7TeQU":["Mesajlar"],"tHaDPf":[["name"]," yazıyor…"],"tfDRzk":["Kaydet"],"tzsBOP":["Çok fazla deneme. Biraz bekleyip tekrar deneyin."],"uA8iBc":["Nasıldık?"],"upFvcp":["Gönderilemedi."],"w61W3L":[["0"]," kaldır"],"xDAtGP":["Mesaj"],"ydzYKJ":["Siz:"],"yz7wBu":["Kapat"],"zLzEI3":["Bizimle sohbet etmek için giriş yapın."]}');var styles=`
|
|
2
2
|
[hidden] { display: none !important; }
|
|
3
3
|
.header {
|
|
4
4
|
display: flex;
|
|
@@ -190,4 +190,4 @@ import{randomId2,createYuvaClient2}from"./index-6brgxahe.js";import{richText}fro
|
|
|
190
190
|
.banner { padding: 6px 12px; background: var(--yuva-soft); color: var(--yuva-muted); font-size: 13px; text-align: center; }
|
|
191
191
|
@media (max-width: 480px) { .composer textarea, .card input, .card textarea { font-size: 16px; } }
|
|
192
192
|
.sr { position: absolute; inline-size: 1px; block-size: 1px; overflow: hidden; clip-path: inset(50%); white-space: nowrap; }
|
|
193
|
-
`;var catalogs={en:messages,tr:messages3,de:messages2},maxFiles=10,groupGap=300000,icons={close:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>',back:'<svg class="flip" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg>',attach:'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 11.5l-8.3 8.3a5 5 0 01-7-7L13 4.5a3.3 3.3 0 014.7 4.7l-8.3 8.3a1.7 1.7 0 01-2.4-2.4L14.5 7.6"/></svg>',send:'<svg class="flip" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M3.4 20.4l17.5-7.5a1 1 0 000-1.8L3.4 3.6a1 1 0 00-1.4 1.2L4.5 12l-2.5 7.2a1 1 0 001.4 1.2zM4.5 12h7"/></svg>',file:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z M14 3v4h4"/></svg>'};function el(tag,className,text){let element=document.createElement(tag);if(className)element.className=className;if(text!==void 0)element.textContent=text;return element}function iconButton(icon,label,onClick,className="icon"){let button=el("button",className);return button.type="button",button.innerHTML=icon,button.setAttribute("aria-label",label),button.title=label,button.addEventListener("click",onClick),button}var time=(value)=>Date.parse(value),byCreated=(a,b)=>time(a.created_at)-time(b.created_at),byActivity=(a,b)=>time(b.last_message_at??b.created_at)-time(a.last_message_at??a.created_at),authorKey=(m)=>m.author.type==="contact"?"contact":`${m.author.type}:${m.author.name??""}`,isImage=(a)=>/^image\/(png|jpeg|gif|webp)$/.test(a.content_type);class Chat{#host;#i18n;#client;#inbox=null;#contact=null;#phase="loading";#error="";#starting=null;#beginning=null;#conversations=new Map;#conversationCursor;#threads=new Map;#pending=[];#typing=new Map;#view=null;#reconnecting=!1;#files=[];#typingSentAt=0;#typingIdle=null;#blobs=new Map;#blobLoads=new Map;#avatars=new Map;#emailSaved=!1;#emailError="";#connectedBefore=!1;#ratings=new Map;#rateCard=el("div","card rate");#rateComment=el("textarea");#rateKey="";#rateFor=null;#header=el("header","header");#banner=el("div","banner");#body=el("div","body");#scroll=el("div","scroll");#email=el("div","card");#emailInput=el("input");#composer=el("div","composer");#chips=el("div","chips");#textarea=el("textarea");#fileInput=el("input");#sendButton;#attachButton;#live=el("div","sr");#scrollThread;#atEnd=!0;constructor(host){this.#host=host;let{server,channel}=host.config();this.#client=createYuvaClient2({server,channel:channel??"",identityToken:()=>host.identityToken()}),this.#client.on("event",(message)=>this.#event(message)),this.#client.on("connection",({state,attempt})=>{if(state!=="reconnecting")return;this.#reconnecting=attempt>0,this.#renderBanner()}),this.#client.on("session",({session,renewed})=>{if(this.#setInbox(session.inbox),this.#contact=session.contact,renewed)this.#reload();else if(!this.#beginning)this.#client.connect().catch(()=>{return})}),this.#setLocale(),this.#live.setAttribute("aria-live","polite"),this.#scroll.addEventListener("scroll",()=>{if(this.#atEnd=this.#scroll.scrollHeight-this.#scroll.scrollTop-this.#scroll.clientHeight<48,this.#scroll.scrollTop<60&&this.#view?.kind==="thread"&&this.#view.id)this.#loadMessages(this.#view.id,!0)}),this.#textarea.rows=1,this.#textarea.addEventListener("keydown",(event)=>{if(event.key==="Enter"&&!event.shiftKey&&!event.isComposing)event.preventDefault(),this.#send()}),this.#textarea.addEventListener("input",()=>{this.#autosize(),this.#syncSend(),this.#typingInput()}),this.#textarea.addEventListener("paste",(event)=>{let files=Array.from(event.clipboardData?.files??[]);if(files.length===0)return;event.preventDefault(),this.#addFiles(files)}),this.#fileInput.type="file",this.#fileInput.multiple=!0,this.#fileInput.hidden=!0,this.#fileInput.addEventListener("change",()=>{this.#addFiles(Array.from(this.#fileInput.files??[])),this.#fileInput.value=""}),this.#attachButton=iconButton(icons.attach,"",()=>this.#fileInput.click()),this.#sendButton=iconButton(icons.send,"",()=>void this.#send(),"icon send");let form=el("form");form.addEventListener("submit",(event)=>{event.preventDefault(),this.#send()}),form.append(this.#attachButton,this.#textarea,this.#sendButton,this.#fileInput),this.#composer.append(this.#chips,form),this.#emailInput.type="email",this.#emailInput.required=!0,this.#emailInput.autocomplete="email",this.#rateComment.rows=2,this.#rateComment.maxLength=2000,this.#rateComment.dir="auto",document.addEventListener("visibilitychange",this.#onVisible),window.addEventListener("online",this.#onVisible),this.#renderAll(),this.#start()}update(){this.#setLocale(),this.#renderAll()}opened(){if(this.#phase==="error"){this.#starting=null,this.#start();return}if(this.#phase==="ready")this.#client.token?this.#refreshSession():this.#preview().then(()=>this.#render()).catch(()=>{return});if(this.#render(),this.#scrollToEnd(),this.#markRead(),this.#host.config().layout==="launcher")this.#textarea.focus({preventScroll:!0})}closed(){this.#stopTyping()}identityChanged(){this.#reset(),this.#start()}async signOut(){let signingOut=this.#client.signOut();if(this.#reset(),await signingOut,this.#host.isOpen())this.#start();else this.#render()}destroy(){this.#client.reset(),this.#stopTyping(),document.removeEventListener("visibilitychange",this.#onVisible),window.removeEventListener("online",this.#onVisible);for(let url of this.#blobs.values())URL.revokeObjectURL(url)}#reset(){this.#client.reset(),this.#starting=null,this.#beginning=null,this.#inbox=null,this.#contact=null,this.#phase="loading",this.#conversations.clear(),this.#threads.clear(),this.#pending=[],this.#ratings.clear(),this.#rateKey="",this.#view=null,this.#connectedBefore=!1,this.#host.setUnread(0)}#onVisible=()=>{if(document.visibilityState!=="visible")return;this.#client.reconnect(),this.#markRead(),this.#refreshInbox()};#setLocale(){let{locale}=this.#host.config();this.#i18n=setupI18n({locale,messages:{[locale]:catalogs[locale]??messages}})}#t(descriptor){return this.#i18n._(descriptor)}#start(){return this.#starting??=(async()=>{this.#phase="loading",this.#render();let{channel}=this.#host.config();if(!channel)throw new ApiError2(0,"not_configured");if(await this.#host.identityToken()||readStored(channel).session)await this.#begin();else if(await this.#preview(),!this.#inbox?.chat.allow_anonymous)throw new ApiError2(403,"anonymous_not_allowed");if(this.#phase="ready",!this.#view){let list=this.#sorted();if(this.#view=list.length>1?{kind:"list"}:{kind:"thread",id:list[0]?.id??null},this.#view.kind==="thread"&&this.#view.id)await this.#loadMessages(this.#view.id)}this.#render(),this.#scrollToEnd(),this.#markRead()})().catch((error)=>{if(this.#starting=null,this.#refusal(error))return;this.#phase="error",this.#error=error instanceof ApiError2?error.code:"error",this.#render()}),this.#starting}async#preview(){let inbox=await this.#fetchInbox();if(!this.#client.token)this.#setInbox(inbox)}#fetchInbox(){if(!this.#host.config().channel)throw new ApiError2(0,"not_configured");return this.#client.channelSettings()}#setInbox(inbox){let{channel}=this.#host.config();this.#inbox=inbox;let launcher=launcherOf(inbox);if(this.#host.setLauncher(launcher),channel)writeStored(channel,{...readStored(channel),launcher})}async#refreshInbox(){if(this.#phase!=="ready")return;try{this.#setInbox(await this.#fetchInbox()),this.#render()}catch(error){this.#refusal(error,!0)}}#refusal(error,channelRequest=!this.#client.token){let refused=error instanceof ApiError2&&(error.code==="origin_not_allowed"||error.status===404&&channelRequest);if(refused)this.#host.refused();return refused}#begin(){return this.#beginning??=(async()=>{await this.#client.start(),await this.#loadConversations(),await this.#client.connect()})().finally(()=>{this.#beginning=null}),this.#beginning}async#refreshSession(){try{await this.#client.refresh(),this.#render()}catch{}}async#loadConversations(more=!1){let page=await this.#client.listConversations({limit:50,cursor:more?this.#conversationCursor:void 0});if(!more)this.#conversations.clear();for(let conversation of page.items)this.#conversations.set(conversation.id,conversation);this.#conversationCursor=page.next_cursor,this.#syncUnread()}async#reload(){await this.#loadConversations();let current=this.#view?.kind==="thread"?this.#view.id:null;for(let id of this.#threads.keys())if(id!==current)this.#threads.delete(id);if(current)this.#threads.delete(current),await this.#loadMessages(current);this.#render()}async#loadMessages(id,older=!1){let thread=this.#threads.get(id);if(!thread)thread={messages:[],complete:!1,loading:!1},this.#threads.set(id,thread);if(thread.loading||older&&(thread.complete||!thread.cursor))return;thread.loading=!0;let before=this.#scroll.scrollHeight-this.#scroll.scrollTop;try{let page=await this.#client.listMessages(id,{order:"desc",limit:30,cursor:older?thread.cursor:void 0}),known=new Set(thread.messages.map((m)=>m.id));thread.messages=[...thread.messages,...page.items.filter((m)=>!known.has(m.id))].sort(byCreated),thread.cursor=page.next_cursor,thread.complete=!page.next_cursor}finally{thread.loading=!1}if(older)this.#render(),this.#scroll.scrollTop=this.#scroll.scrollHeight-before}#event(message){switch(message.type){case"ready":if(this.#reconnecting=!1,this.#renderBanner(),this.#connectedBefore)this.#refreshInbox();this.#connectedBefore=!0;return;case"inbox.updated":{let asked=this.#inbox?.ask_for_rating;if(this.#setInbox(message.data),asked!==void 0&&asked!==message.data.ask_for_rating)this.#loadConversations().then(()=>this.#render()).catch(()=>{return});break}case"resync_required":this.#reload();return;case"presence":if(this.#inbox)this.#inbox={...this.#inbox,presence:message.data};break;case"conversation.created":if(!this.#conversations.has(message.data.id))this.#conversations.set(message.data.id,message.data);if(this.#view?.kind==="thread"&&this.#view.id===null&&this.#conversations.size>1)this.#view=this.#pending.some((p)=>p.conversation===null)?this.#view:{kind:"list"};this.#syncUnread();break;case"conversation.updated":{let conversation=this.#conversations.get(message.data.id),{status,can_rate,rating}=message.data;if(conversation)this.#conversations.set(conversation.id,{...conversation,status,can_rate,rating});if(!can_rate)this.#ratings.delete(message.data.id);break}case"message.created":case"message.updated":this.#upsertMessage(message.data,message.type==="message.created");break;case"read":{let conversation=this.#conversations.get(message.data.conversation_id),previous=conversation?.last_read_by_member_at;if(conversation&&(!previous||time(message.data.read_at)>time(previous)))this.#conversations.set(conversation.id,{...conversation,last_read_by_member_at:message.data.read_at});break}case"typing":{let id=message.data.conversation_id,previous=this.#typing.get(id);if(previous)clearTimeout(previous.timer);if(message.data.typing){let name=message.data.author.name??"";this.#typing.set(id,{name,timer:setTimeout(()=>this.#typing.delete(id)&&this.#render(),8000)})}else this.#typing.delete(id);break}}this.#render()}#upsertMessage(message,created){let id=message.conversation_id,thread=this.#threads.get(id);if(thread){let index=thread.messages.findIndex((m)=>m.id===message.id);if(index>=0)thread.messages[index]=message;else thread.messages=[...thread.messages,message].sort(byCreated)}if(message.client_id)this.#pending=this.#pending.filter((p)=>p.client_id!==message.client_id);let conversation=this.#conversations.get(id);if(!conversation){this.#client.getConversation(id).then((c)=>{this.#conversations.set(c.id,c),this.#syncUnread(),this.#render()}).catch(()=>{return});return}if(created){let text=message.body.replace(/\s+/g," ").trim();if(this.#conversations.set(id,{...conversation,last_message:{id:message.id,author_type:message.author.type,text:text.length>140?`${text.slice(0,139)}…`:text,created_at:message.created_at},last_message_at:message.created_at,unread:conversation.unread||message.author.type!=="contact"}),message.author.type!=="contact"){let typing=this.#typing.get(id);if(typing)clearTimeout(typing.timer);this.#typing.delete(id),this.#announce(message)}}this.#syncUnread(),this.#markRead()}#announce(message){this.#live.textContent=`${message.author.name||this.#inbox?.name||""}: ${message.body.slice(0,200)}`}#syncUnread(){let count=0;for(let conversation of this.#conversations.values())if(conversation.unread)count++;this.#host.setUnread(count)}#visibleThread(){if(!this.#host.isOpen()||document.visibilityState!=="visible")return null;return this.#view?.kind==="thread"?this.#view.id:null}#markRead(){let id=this.#visibleThread(),conversation=id?this.#conversations.get(id):void 0;if(!id||!conversation?.unread)return;this.#conversations.set(id,{...conversation,unread:!1}),this.#syncUnread(),this.#client.markRead(id).catch(()=>{let current=this.#conversations.get(id);if(current)this.#conversations.set(id,{...current,unread:!0});this.#syncUnread()})}#addFiles(files){this.#files=[...this.#files,...files].slice(0,maxFiles),this.#renderChips(),this.#syncSend(),this.#textarea.focus()}#autosize(){if(this.#textarea.style.blockSize="",this.#textarea.value==="")return;this.#textarea.style.blockSize="auto",this.#textarea.style.blockSize=`${Math.max(38,Math.min(this.#textarea.scrollHeight,140))}px`}#syncSend(){this.#sendButton.disabled=this.#textarea.value.trim()===""&&this.#files.length===0}#typingInput(){let id=this.#view?.kind==="thread"?this.#view.id:null;if(!id||this.#textarea.value.trim()===""){this.#stopTyping();return}if(Date.now()-this.#typingSentAt>3000)this.#typingSentAt=Date.now(),this.#client.setTyping(id,!0).catch(()=>{return});if(this.#typingIdle)clearTimeout(this.#typingIdle);this.#typingIdle=setTimeout(()=>this.#stopTyping(),4000)}#stopTyping(){if(this.#typingIdle)clearTimeout(this.#typingIdle);if(this.#typingIdle=null,this.#typingSentAt===0)return;this.#typingSentAt=0;let id=this.#view?.kind==="thread"?this.#view.id:null;if(id)this.#client.setTyping(id,!1).catch(()=>{return})}async#send(){if(this.#phase!=="ready"||this.#view?.kind!=="thread")return;let body=this.#textarea.value.trim(),files=this.#files;if(!body&&files.length===0)return;if(this.#view.id===null&&this.#pending.some((p)=>p.conversation===null))return;this.#stopTyping(),this.#textarea.value="",this.#files=[],this.#autosize(),this.#renderChips(),this.#syncSend();let pending={client_id:randomId2(),conversation:this.#view.id,body,files,state:"sending"};this.#pending.push(pending),this.#render(),this.#scrollToEnd(),await this.#deliver(pending)}async#deliver(pending){pending.state="sending",this.#render();let input={body:pending.body,files:pending.files,client_id:pending.client_id};try{if(pending.conversation===null){let created=await this.#client.startConversation(input),id=created.conversation.id;if(!this.#conversations.has(id))this.#conversations.set(id,created.conversation);if(!this.#threads.has(id))this.#threads.set(id,{messages:[],complete:!0,loading:!1});if(this.#view?.kind==="thread"&&this.#view.id===null)this.#view={kind:"thread",id};this.#upsertMessage(created.message,!1)}else{let message=await this.#client.sendMessage(pending.conversation,input);this.#upsertMessage(message,!0)}this.#pending=this.#pending.filter((p)=>p!==pending)}catch(error){let status=error instanceof ApiError2?error.status:0;pending.state=status===413||status===415?"refused":"failed",pending.status=status}this.#render(),this.#scrollToEnd()}async rate(id,rating,comment){try{let conversation=await this.#client.rate(id,rating,comment);return this.#conversations.set(conversation.id,conversation),this.#ratings.delete(id),this.#render(),conversation}catch(error){if(error instanceof ApiError2&&error.status===409){let current=await this.#client.getConversation(id).catch(()=>null);if(current)this.#conversations.set(current.id,current);this.#ratings.delete(id),this.#render()}throw error}}#choose(id,choice){if(this.#ratings.get(id)?.state==="sending")return;if(this.#ratings.set(id,{choice,state:"choosing"}),this.#render(),this.#rateComment.focus({preventScroll:!0}),this.#atEnd)this.#scrollToEnd()}async#submitRating(id,withComment){let draft=this.#ratings.get(id);if(!draft||draft.state==="sending")return;draft.state="sending",this.#render();try{await this.rate(id,draft.choice,withComment?this.#rateComment.value:void 0),this.#rateComment.value=""}catch(error){if(error instanceof ApiError2&&error.status===409)return;draft.state="failed",this.#render()}}async#saveEmail(){let email=this.#emailInput.value.trim();if(!email||!this.#emailInput.checkValidity()){this.#emailError=this.#t({id:"E_qvzP"}),this.#renderEmail();return}try{this.#contact=await this.#client.setEmail(email),this.#emailSaved=!0,this.#emailError=""}catch{this.#emailError=this.#t({id:"ZxJcgC"})}this.#renderEmail()}#attachmentUrl(attachment){let cached=this.#blobs.get(attachment.id);if(cached)return Promise.resolve(cached);let load=this.#blobLoads.get(attachment.id);if(!load)load=this.#client.attachment(attachment.id).then((blob)=>{let url=URL.createObjectURL(blob);return this.#blobs.set(attachment.id,url),url}),load.catch(()=>this.#blobLoads.delete(attachment.id)),this.#blobLoads.set(attachment.id,load);return load}async#download(attachment){let url=await this.#attachmentUrl(attachment),a=el("a");a.href=url,a.download=attachment.filename,a.rel="noopener",a.click()}#sorted(){return[...this.#conversations.values()].sort(byActivity)}#nobodyAvailable(){let inbox=this.#inbox;if(!inbox)return!1;return!inbox.open_now||inbox.mode==="async"||!inbox.presence?.available}#scrollToEnd(){this.#atEnd=!0,this.#scroll.scrollTop=this.#scroll.scrollHeight,requestAnimationFrame(()=>{if(this.#atEnd)this.#scroll.scrollTop=this.#scroll.scrollHeight})}#renderAll(){this.#textarea.placeholder=this.#t({id:"RzWUUK"}),this.#textarea.setAttribute("aria-label",this.#t({id:"xDAtGP"})),this.#attachButton.setAttribute("aria-label",this.#t({id:"N7m8E-"})),this.#attachButton.title=this.#t({id:"N7m8E-"}),this.#sendButton.setAttribute("aria-label",this.#t({id:"JlFcis"})),this.#sendButton.title=this.#t({id:"JlFcis"}),this.#emailInput.placeholder=this.#t({id:"njBr8W"}),this.#emailInput.setAttribute("aria-label",this.#t({id:"XJURKP"})),this.#syncSend(),this.#renderChips(),this.#render()}#render(){let panel=this.#host.panel;if(panel.childElementCount===0){let style=el("style");style.textContent=styles,panel.append(style,this.#header,this.#banner,this.#body,this.#live),this.#header.id="yuva-title",panel.setAttribute("aria-labelledby","yuva-title")}if(this.#renderHeader(),this.#renderBanner(),this.#phase!=="ready"){this.#scrollThread=void 0;let center=el("div","center");if(this.#phase==="loading")center.append(el("p","hint",this.#t({id:"Pwqkdw"})));else{center.append(el("p","empty",this.#errorText()));let retry=el("button","primary",this.#t({id:"KDw4GX"}));retry.type="button",retry.addEventListener("click",()=>{this.#starting=null,this.#start()}),center.append(retry)}this.#body.replaceChildren(center);return}if(this.#view?.kind==="list")this.#renderList();else this.#renderThread()}#errorText(){switch(this.#error){case"anonymous_not_allowed":return this.#t({id:"zLzEI3"});case"invalid_identity_token":return this.#t({id:"0XGLbP"});case"rate_limited":return this.#t({id:"tzsBOP"});case"network":return this.#t({id:"GQVIIl"});default:return this.#t({id:"Amai22"})}}#renderHeader(){let{layout}=this.#host.config(),inbox=this.#inbox,children=[],view=this.#view;if(this.#phase==="ready"&&view?.kind==="thread"&&(this.#conversations.size>1||view.id===null&&this.#conversations.size>0))children.push(iconButton(icons.back,this.#t({id:"S63MQu"}),()=>{this.#stopTyping(),this.#view={kind:"list"},this.#render()}));let heading=el("div","heading");if(heading.append(el("h2","title",inbox?.name||this.#t({id:"t7TeQU"}))),inbox){let status=el("div","status");if(inbox.mode==="live"&&inbox.open_now&&inbox.presence?.available){let avatars=el("div","avatars");for(let member of inbox.presence?.members.slice(0,3)??[]){let avatar=el("span","avatar",member.initials||"•");avatar.title=member.name,avatars.append(avatar)}status.append(avatars,el("span","dot"),el("span","",this.#t({id:"oXOSPE"})))}else if(!inbox.open_now||inbox.mode==="live")status.append(el("span","dot away"),el("span","",this.#t({id:"1EICzz"})));else status.append(el("span","",this.#replyTime(inbox.expected_reply_minutes)));heading.append(status)}if(children.push(heading),layout==="launcher")children.push(iconButton(icons.close,this.#t({id:"yz7wBu"}),()=>this.#host.close()));this.#header.replaceChildren(...children)}#replyTime(minutes){if(!minutes)return this.#t({id:"nhTADq"});let{locale}=this.#host.config(),[value,unit]=minutes<60?[minutes,"minute"]:minutes<1440?[Math.round(minutes/60),"hour"]:[Math.round(minutes/1440),"day"],duration=new Intl.NumberFormat(locale,{style:"unit",unit,unitDisplay:"long"}).format(value);return this.#t({id:"VggdQJ",values:{duration}})}#renderBanner(){this.#banner.hidden=!this.#reconnecting,this.#banner.textContent=this.#t({id:"09Tv5j"})}#renderList(){this.#scrollThread=void 0;let{locale}=this.#host.config(),list=el("ul","list"),today=new Date().toDateString();for(let conversation of this.#sorted()){let button=el("button",conversation.unread?"item unread":"item");button.type="button";let main=el("div","item-main"),top=el("div","item-top");top.append(el("span","item-subject",conversation.subject||this.#inbox?.name||this.#t({id:"YyNOE7"})));let at=new Date(conversation.last_message_at??conversation.created_at);top.append(el("span","item-time",new Intl.DateTimeFormat(locale,at.toDateString()===today?{timeStyle:"short"}:{month:"short",day:"numeric"}).format(at)));let preview=conversation.last_message?`${conversation.last_message.author_type==="contact"?this.#t({id:"ydzYKJ"})+" ":""}${conversation.last_message.text||this.#t({id:"UY1vmE"})}`:"",previewLine=el("div","item-preview",preview.replace(/\*\*|`/g,""));if(previewLine.dir="auto",main.append(top,previewLine),button.append(main),conversation.unread)button.append(el("span","unread-dot"));button.addEventListener("click",()=>void this.#openThread(conversation.id));let item=el("li");item.append(button),list.append(item)}if(this.#conversationCursor){let more=el("button","link",this.#t({id:"ASr-r0"}));more.type="button",more.style.margin="8px auto",more.style.display="block",more.addEventListener("click",()=>void this.#loadConversations(!0).then(()=>this.#render())),list.append(more)}let start=el("button","primary",this.#t({id:"-HY5kX"}));start.type="button",start.addEventListener("click",()=>{this.#view={kind:"thread",id:null},this.#render(),this.#textarea.focus()}),this.#body.replaceChildren(list,start)}async#openThread(id){if(this.#view={kind:"thread",id},this.#render(),!this.#threads.get(id)?.complete&&!this.#threads.get(id)?.messages.length)await this.#loadMessages(id).catch(()=>{return});this.#render(),this.#scrollToEnd(),this.#markRead()}#avatar(author){let avatar=el("span","avatar",author.initials||""),url=author.avatar_url,state=url?this.#avatars.get(url):!1;if(!url||state===!1)return avatar;let img=el("img");if(img.alt="",img.referrerPolicy="no-referrer",state)return img.src=url,avatar.replaceChildren(img),avatar;return img.addEventListener("load",()=>{if(this.#avatars.set(url,!0),avatar.isConnected)avatar.replaceChildren(img)}),img.addEventListener("error",()=>this.#avatars.set(url,!1)),img.src=url,avatar}#renderThread(){let view=this.#view;if(view?.kind!=="thread")return;let id=view.id,sameThread=this.#scrollThread===id,atEnd=this.#atEnd,thread=id?this.#threads.get(id):void 0,messages=thread?.messages??[],pending=this.#pending.filter((p)=>p.conversation===id),nodes=[],greeting=this.#inbox?.chat.greeting;if(!thread||thread.complete){if(greeting){let bubble=el("div","bubble greeting");bubble.append(richText(greeting)),nodes.push(bubble)}else if(messages.length===0&&pending.length===0){let center=el("div","center");center.append(el("p","empty",this.#t({id:"meAa31"})),el("p","hint",this.#t({id:"SdV5Cn"}))),nodes.push(center)}}else if(thread.loading)nodes.push(el("p","hint",this.#t({id:"Pwqkdw"})));messages.forEach((message,i)=>{let previous=messages[i-1],next=messages[i+1]??(pending.length>0?null:void 0),mine=message.author.type==="contact",starts=!previous||authorKey(previous)!==authorKey(message)||time(message.created_at)-time(previous.created_at)>groupGap,ends=next===void 0||(next===null?!mine:authorKey(next)!==authorKey(message)||time(next.created_at)-time(message.created_at)>groupGap);if(!mine&&starts&&message.author.name)nodes.push(el("div","author",message.author.name));let row=el("div",`row ${mine?"mine":"theirs"}${starts&&i>0?" group-gap":""}`);if(!mine){let avatar=this.#avatar(message.author);if(!ends)avatar.style.visibility="hidden";row.append(avatar)}let bubble=el("div","bubble");if(bubble.dir="auto",bubble.title=new Date(message.created_at).toLocaleString(this.#host.config().locale),message.body.trim())bubble.append(richText(message.body));if(message.attachments.length>0)bubble.append(this.#renderAttachments(message.attachments));if(row.append(bubble),nodes.push(row),ends){let meta=this.#formatTime(message.created_at);if(mine&&i===messages.length-1&&pending.length===0){let readAt=id?this.#conversations.get(id)?.last_read_by_member_at:void 0,seen=readAt&&time(readAt)>=time(message.created_at);meta+=` · ${seen?this.#t({id:"6lGaum"}):this.#t({id:"h69WC6"})}`}let line=el("div","meta",meta);if(!mine)line.style.alignSelf="flex-start";if(!mine)line.style.marginInlineStart="36px";nodes.push(line)}});let conversation=id?this.#conversations.get(id):void 0,rate=conversation?this.#renderRating(conversation):null;if(rate)nodes.push(rate);pending.forEach((item,i)=>{let row=el("div",`row mine${i===0&&messages.length>0&&messages[messages.length-1]?.author.type!=="contact"?" group-gap":""}`),bubble=el("div","bubble");if(bubble.dir="auto",item.body)bubble.append(richText(item.body));if(item.files.length>0){let files=el("div","files");for(let file of item.files)files.append(el("span","file",file.name||"image"));bubble.append(files)}if(row.append(bubble),nodes.push(row),item.state==="failed"){let line=el("div","meta failed",`${this.#t({id:"upFvcp"})} `),retry=el("button","link",this.#t({id:"6gRgw8"}));retry.type="button",retry.addEventListener("click",()=>void this.#deliver(item)),line.append(retry),nodes.push(line)}else if(item.state==="refused"){let reason=item.status===413?this.#t({id:"eOu9Px"}):this.#t({id:"JkW3Ph"});nodes.push(el("div","meta failed",`${this.#t({id:"upFvcp"})} ${reason}`))}else if(i===pending.length-1)nodes.push(el("div","meta",this.#t({id:"Sad2tK"})))});let typing=id?this.#typing.get(id):void 0;if(typing){let line=el("div","typing");line.append(el("i"),el("i"),el("i"));let name=typing.name;line.append(el("span","",name?this.#t({id:"tHaDPf",values:{name}}):this.#t({id:"PxYAul"}))),nodes.push(line)}let focused=this.#scroll.getRootNode().activeElement===this.#rateComment,{selectionStart,selectionEnd}=this.#rateComment;if(this.#scroll.replaceChildren(...nodes),focused&&this.#rateComment.isConnected)this.#rateComment.focus({preventScroll:!0}),this.#rateComment.setSelectionRange(selectionStart,selectionEnd);if(this.#renderEmail(),this.#body.firstChild!==this.#scroll)this.#body.replaceChildren(this.#scroll,this.#email,this.#composer);if(this.#scrollThread=id,!sameThread||atEnd)this.#scrollToEnd()}#renderRating(conversation){let rated=conversation.status==="closed"?conversation.rating:void 0,draft=conversation.can_rate&&this.#inbox?.ask_for_rating?this.#ratings.get(conversation.id):void 0;if(!rated&&!(conversation.can_rate&&this.#inbox?.ask_for_rating))return null;let card=this.#rateCard,key=[conversation.id,rated,draft?.choice,draft?.state,this.#host.config().locale].join(":");if(key===this.#rateKey)return card;if(this.#rateKey=key,this.#rateFor!==conversation.id)this.#rateFor=conversation.id,this.#rateComment.value="";let question=this.#t({id:"uA8iBc"});card.setAttribute("role","group"),card.setAttribute("aria-label",question);let choices=el("div","choices");for(let value of["good","bad"]){if(rated&&rated!==value)continue;let button=el("button","choice",value==="good"?"\uD83D\uDC4D":"\uD83D\uDC4E");button.type="button";let label=value==="good"?this.#t({id:"OEEQKT"}):this.#t({id:"-f5Tkb"});button.setAttribute("aria-label",label),button.title=label,button.setAttribute("aria-pressed",String((rated??draft?.choice)===value)),button.disabled=!!rated||draft?.state==="sending",button.addEventListener("click",()=>this.#choose(conversation.id,value)),choices.append(button)}if(rated)return card.replaceChildren(choices,el("p","",this.#t({id:"SOk0EB"}))),card;if(card.replaceChildren(el("p","",question),choices),!draft)return card;this.#rateComment.placeholder=this.#t({id:"axQ1h6"}),this.#rateComment.setAttribute("aria-label",this.#t({id:"NBdIgR"})),this.#rateComment.disabled=draft.state==="sending";let form=el("form");form.addEventListener("submit",(event)=>{event.preventDefault(),this.#submitRating(conversation.id,!0)});let skip=el("button","link",this.#t({id:"6Uau97"}));skip.type="button",skip.disabled=draft.state==="sending",skip.addEventListener("click",()=>void this.#submitRating(conversation.id,!1));let send=el("button","",draft.state==="sending"?this.#t({id:"Sad2tK"}):this.#t({id:"JlFcis"}));send.type="submit",send.disabled=draft.state==="sending";let actions=el("div","actions");if(actions.append(skip,send),form.append(this.#rateComment,actions),card.append(form),draft.state==="failed")card.append(el("p","error",this.#t({id:"4TqZiz"})));return card}#renderAttachments(attachments){let files=el("div","files");for(let attachment of attachments)if(isImage(attachment)){let img=el("img");img.alt=attachment.filename;let cached=this.#blobs.get(attachment.id);if(cached)img.src=cached;else this.#attachmentUrl(attachment).then((url)=>{img.src=url}).catch(()=>{return});img.addEventListener("load",()=>{if(this.#atEnd)this.#scroll.scrollTop=this.#scroll.scrollHeight}),img.addEventListener("click",()=>void this.#download(attachment)),files.append(img)}else{let button=el("button","file");button.type="button",button.innerHTML=icons.file,button.append(el("span","",attachment.filename)),button.addEventListener("click",()=>void this.#download(attachment)),files.append(button)}return files}#formatTime(value){return new Intl.DateTimeFormat(this.#host.config().locale,{timeStyle:"short"}).format(new Date(value))}#renderEmail(){let contact=this.#contact,chat=this.#inbox?.chat,sent=(this.#view?.kind==="thread"?this.#view.id:null)!==null||this.#pending.length>0,known=contact?.email||contact?.typed_email,show=!!chat?.ask_email_offline&&this.#nobodyAvailable()&&sent&&(!known||this.#emailSaved);if(this.#email.hidden=!show,!show)return;if(known&&this.#emailSaved){this.#email.replaceChildren(el("p","",this.#t({id:"iGNUZJ",values:{known}})));return}if(this.#email.querySelector("form")){let error=this.#email.querySelector(".error");if(error)error.textContent=this.#emailError;else if(this.#emailError)this.#email.append(el("p","error",this.#emailError));return}let form=el("form");form.noValidate=!0,form.addEventListener("submit",(event)=>{event.preventDefault(),this.#saveEmail()});let save=el("button","",this.#t({id:"tfDRzk"}));if(save.type="submit",form.append(this.#emailInput,save),this.#email.replaceChildren(el("p","",this.#t({id:"M62PBt"})),form),this.#emailError)this.#email.append(el("p","error",this.#emailError))}#renderChips(){this.#chips.hidden=this.#files.length===0,this.#chips.replaceChildren(...this.#files.map((file,index)=>{let chip=el("span","chip");return chip.append(el("span","",file.name||"image"),iconButton(icons.close,this.#t({id:"w61W3L",values:{0:file.name}}),()=>{this.#files=this.#files.filter((_,i)=>i!==index),this.#renderChips(),this.#syncSend()})),chip}))}}function mount(host){return new Chat(host)}export{mount};
|
|
193
|
+
`;var catalogs={en:messages,tr:messages3,de:messages2},maxFiles=10,groupGap=300000,icons={close:'<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" aria-hidden="true"><path d="M6 6l12 12M18 6L6 18"/></svg>',back:'<svg class="flip" width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M15 6l-6 6 6 6"/></svg>',attach:'<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20 11.5l-8.3 8.3a5 5 0 01-7-7L13 4.5a3.3 3.3 0 014.7 4.7l-8.3 8.3a1.7 1.7 0 01-2.4-2.4L14.5 7.6"/></svg>',send:'<svg class="flip" width="20" height="20" viewBox="0 0 24 24" fill="currentColor" aria-hidden="true"><path d="M3.4 20.4l17.5-7.5a1 1 0 000-1.8L3.4 3.6a1 1 0 00-1.4 1.2L4.5 12l-2.5 7.2a1 1 0 001.4 1.2zM4.5 12h7"/></svg>',file:'<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linejoin="round" aria-hidden="true"><path d="M14 3H6v18h12V7z M14 3v4h4"/></svg>'};function el(tag,className,text){let element=document.createElement(tag);if(className)element.className=className;if(text!==void 0)element.textContent=text;return element}function iconButton(icon,label,onClick,className="icon"){let button=el("button",className);return button.type="button",button.innerHTML=icon,button.setAttribute("aria-label",label),button.title=label,button.addEventListener("click",onClick),button}var time=(value)=>Date.parse(value),byCreated=(a,b)=>time(a.created_at)-time(b.created_at),byActivity=(a,b)=>time(b.last_message_at??b.created_at)-time(a.last_message_at??a.created_at),authorKey=(m)=>m.author.type==="contact"?"contact":`${m.author.type}:${m.author.name??""}`,isImage=(a)=>/^image\/(png|jpeg|gif|webp)$/.test(a.content_type);class Chat{#host;#i18n;#client;#inbox=null;#contact=null;#phase="loading";#error="";#starting=null;#beginning=null;#conversations=new Map;#conversationCursor;#threads=new Map;#pending=[];#typing=new Map;#view=null;#reconnecting=!1;#files=[];#typingSentAt=0;#typingIdle=null;#blobs=new Map;#blobLoads=new Map;#avatars=new Map;#emailSaved=!1;#emailError="";#connectedBefore=!1;#ratings=new Map;#rateCard=el("div","card rate");#rateComment=el("textarea");#rateKey="";#rateFor=null;#header=el("header","header");#banner=el("div","banner");#body=el("div","body");#scroll=el("div","scroll");#email=el("div","card");#emailInput=el("input");#composer=el("div","composer");#chips=el("div","chips");#textarea=el("textarea");#fileInput=el("input");#sendButton;#attachButton;#live=el("div","sr");#scrollThread;#atEnd=!0;constructor(host){this.#host=host;let{server,channel}=host.config();this.#client=createYuvaClient2({server,channel:channel??"",identityToken:()=>host.identityToken()}),this.#client.on("event",(message)=>this.#event(message)),this.#client.on("connection",({state,attempt})=>{if(state!=="reconnecting")return;this.#reconnecting=attempt>0,this.#renderBanner()}),this.#client.on("session",({session,renewed})=>{if(this.#setInbox(session.inbox),this.#contact=session.contact,renewed)this.#reload();else if(!this.#beginning)this.#client.connect().catch(()=>{return})}),this.#setLocale(),this.#live.setAttribute("aria-live","polite"),this.#scroll.addEventListener("scroll",()=>{if(this.#atEnd=this.#scroll.scrollHeight-this.#scroll.scrollTop-this.#scroll.clientHeight<48,this.#scroll.scrollTop<60&&this.#view?.kind==="thread"&&this.#view.id)this.#loadMessages(this.#view.id,!0)}),this.#textarea.rows=1,this.#textarea.addEventListener("keydown",(event)=>{if(event.key==="Enter"&&!event.shiftKey&&!event.isComposing)event.preventDefault(),this.#send()}),this.#textarea.addEventListener("input",()=>{this.#autosize(),this.#syncSend(),this.#typingInput()}),this.#textarea.addEventListener("paste",(event)=>{let files=Array.from(event.clipboardData?.files??[]);if(files.length===0)return;event.preventDefault(),this.#addFiles(files)}),this.#fileInput.type="file",this.#fileInput.multiple=!0,this.#fileInput.hidden=!0,this.#fileInput.addEventListener("change",()=>{this.#addFiles(Array.from(this.#fileInput.files??[])),this.#fileInput.value=""}),this.#attachButton=iconButton(icons.attach,"",()=>this.#fileInput.click()),this.#sendButton=iconButton(icons.send,"",()=>void this.#send(),"icon send");let form=el("form");form.addEventListener("submit",(event)=>{event.preventDefault(),this.#send()}),form.append(this.#attachButton,this.#textarea,this.#sendButton,this.#fileInput),this.#composer.append(this.#chips,form),this.#emailInput.type="email",this.#emailInput.required=!0,this.#emailInput.autocomplete="email",this.#rateComment.rows=2,this.#rateComment.maxLength=2000,this.#rateComment.dir="auto",document.addEventListener("visibilitychange",this.#onVisible),window.addEventListener("online",this.#onVisible),this.#renderAll(),this.#start()}update(){this.#setLocale(),this.#renderAll()}opened(){if(this.#phase==="error"){this.#starting=null,this.#start();return}if(this.#phase==="ready")this.#client.token?this.#refreshSession():this.#preview().then(()=>this.#render()).catch(()=>{return});if(this.#render(),this.#scrollToEnd(),this.#markRead(),this.#host.config().layout==="launcher")this.#textarea.focus({preventScroll:!0})}closed(){this.#stopTyping()}identityChanged(){this.#reset(),this.#start()}async signOut(){let signingOut=this.#client.signOut();if(this.#reset(),await signingOut,this.#host.isOpen())this.#start();else this.#render()}destroy(){this.#client.reset(),this.#stopTyping(),document.removeEventListener("visibilitychange",this.#onVisible),window.removeEventListener("online",this.#onVisible);for(let url of this.#blobs.values())URL.revokeObjectURL(url)}#reset(){this.#client.reset(),this.#starting=null,this.#beginning=null,this.#inbox=null,this.#contact=null,this.#phase="loading",this.#conversations.clear(),this.#threads.clear(),this.#pending=[],this.#ratings.clear(),this.#rateKey="",this.#view=null,this.#connectedBefore=!1,this.#host.setUnread(0)}#onVisible=()=>{if(document.visibilityState!=="visible")return;this.#client.reconnect(),this.#markRead(),this.#refreshInbox()};#setLocale(){let{locale}=this.#host.config();this.#i18n=setupI18n({locale,messages:{[locale]:catalogs[locale]??messages}})}#t(descriptor){return this.#i18n._(descriptor)}#start(){return this.#starting??=(async()=>{this.#phase="loading",this.#render();let{channel}=this.#host.config();if(!channel)throw new ApiError2(0,"not_configured");if(await this.#host.identityToken()||readStored(channel).session)await this.#begin();else if(await this.#preview(),!this.#inbox?.chat.allow_anonymous)throw new ApiError2(403,"anonymous_not_allowed");if(this.#phase="ready",!this.#view){let list=this.#sorted();if(this.#view=list.length>1?{kind:"list"}:{kind:"thread",id:list[0]?.id??null},this.#view.kind==="thread"&&this.#view.id)await this.#loadMessages(this.#view.id)}this.#render(),this.#scrollToEnd(),this.#markRead()})().catch((error)=>{if(this.#starting=null,this.#refusal(error))return;this.#phase="error",this.#error=error instanceof ApiError2?error.code:"error",this.#render()}),this.#starting}async#preview(){let inbox=await this.#fetchInbox();if(!this.#client.token)this.#setInbox(inbox)}#fetchInbox(){if(!this.#host.config().channel)throw new ApiError2(0,"not_configured");return this.#client.channelSettings()}#setInbox(inbox){let{channel}=this.#host.config();this.#inbox=inbox;let launcher=launcherOf(inbox);if(this.#host.setLauncher(launcher),channel)writeStored(channel,{...readStored(channel),launcher})}async#refreshInbox(){if(this.#phase!=="ready")return;try{this.#setInbox(await this.#fetchInbox()),this.#render()}catch(error){this.#refusal(error,!0)}}#refusal(error,channelRequest=!this.#client.token){let refused=error instanceof ApiError2&&(error.code==="origin_not_allowed"||error.status===404&&channelRequest);if(refused)this.#host.refused();return refused}#begin(){return this.#beginning??=(async()=>{await this.#client.start(),await this.#loadConversations(),await this.#client.connect()})().finally(()=>{this.#beginning=null}),this.#beginning}async#refreshSession(){try{await this.#client.refresh(),this.#render()}catch{}}async#loadConversations(more=!1){let page=await this.#client.listConversations({limit:50,cursor:more?this.#conversationCursor:void 0});if(!more)this.#conversations.clear();for(let conversation of page.items)this.#conversations.set(conversation.id,conversation);this.#conversationCursor=page.next_cursor,this.#syncUnread()}async#reload(){await this.#loadConversations();let current=this.#view?.kind==="thread"?this.#view.id:null;for(let id of this.#threads.keys())if(id!==current)this.#threads.delete(id);if(current)this.#threads.delete(current),await this.#loadMessages(current);this.#render()}async#loadMessages(id,older=!1){let thread=this.#threads.get(id);if(!thread)thread={messages:[],complete:!1,loading:!1},this.#threads.set(id,thread);if(thread.loading||older&&(thread.complete||!thread.cursor))return;thread.loading=!0;let before=this.#scroll.scrollHeight-this.#scroll.scrollTop;try{let page=await this.#client.listMessages(id,{order:"desc",limit:30,cursor:older?thread.cursor:void 0}),known=new Set(thread.messages.map((m)=>m.id));thread.messages=[...thread.messages,...page.items.filter((m)=>!known.has(m.id))].sort(byCreated),thread.cursor=page.next_cursor,thread.complete=!page.next_cursor}finally{thread.loading=!1}if(older)this.#render(),this.#scroll.scrollTop=this.#scroll.scrollHeight-before}#event(message){switch(message.type){case"ready":if(this.#reconnecting=!1,this.#renderBanner(),this.#connectedBefore)this.#refreshInbox();this.#connectedBefore=!0;return;case"inbox.updated":{let asked=this.#inbox?.ask_for_rating;if(this.#setInbox(message.data),asked!==void 0&&asked!==message.data.ask_for_rating)this.#loadConversations().then(()=>this.#render()).catch(()=>{return});break}case"resync_required":this.#reload();return;case"presence":if(this.#inbox)this.#inbox={...this.#inbox,presence:message.data};break;case"conversation.created":if(!this.#conversations.has(message.data.id))this.#conversations.set(message.data.id,message.data);if(this.#view?.kind==="thread"&&this.#view.id===null&&this.#conversations.size>1)this.#view=this.#pending.some((p)=>p.conversation===null)?this.#view:{kind:"list"};this.#syncUnread();break;case"conversation.updated":{let conversation=this.#conversations.get(message.data.id),{status,can_rate,rating}=message.data;if(conversation)this.#conversations.set(conversation.id,{...conversation,status,can_rate,rating});if(!can_rate)this.#ratings.delete(message.data.id);break}case"message.created":case"message.updated":this.#upsertMessage(message.data,message.type==="message.created");break;case"read":{let conversation=this.#conversations.get(message.data.conversation_id),previous=conversation?.last_read_by_member_at;if(conversation&&(!previous||time(message.data.read_at)>time(previous)))this.#conversations.set(conversation.id,{...conversation,last_read_by_member_at:message.data.read_at});break}case"typing":{let id=message.data.conversation_id,previous=this.#typing.get(id);if(previous)clearTimeout(previous.timer);if(message.data.typing){let name=message.data.author.name??"";this.#typing.set(id,{name,timer:setTimeout(()=>this.#typing.delete(id)&&this.#render(),8000)})}else this.#typing.delete(id);break}}this.#render()}#upsertMessage(message,created){let id=message.conversation_id,thread=this.#threads.get(id);if(thread){let index=thread.messages.findIndex((m)=>m.id===message.id);if(index>=0)thread.messages[index]=message;else thread.messages=[...thread.messages,message].sort(byCreated)}if(message.client_id)this.#pending=this.#pending.filter((p)=>p.client_id!==message.client_id);let conversation=this.#conversations.get(id);if(!conversation){this.#client.getConversation(id).then((c)=>{this.#conversations.set(c.id,c),this.#syncUnread(),this.#render()}).catch(()=>{return});return}if(created){let text=message.body.replace(/\s+/g," ").trim();if(this.#conversations.set(id,{...conversation,last_message:{id:message.id,author_type:message.author.type,text:text.length>140?`${text.slice(0,139)}…`:text,created_at:message.created_at},last_message_at:message.created_at,unread:conversation.unread||message.author.type!=="contact"}),message.author.type!=="contact"){let typing=this.#typing.get(id);if(typing)clearTimeout(typing.timer);this.#typing.delete(id),this.#announce(message)}}this.#syncUnread(),this.#markRead()}#announce(message){this.#live.textContent=`${message.author.name||this.#inbox?.name||""}: ${message.body.slice(0,200)}`}#syncUnread(){let count=0;for(let conversation of this.#conversations.values())if(conversation.unread)count++;this.#host.setUnread(count)}#visibleThread(){if(!this.#host.isOpen()||document.visibilityState!=="visible")return null;return this.#view?.kind==="thread"?this.#view.id:null}#markRead(){let id=this.#visibleThread(),conversation=id?this.#conversations.get(id):void 0;if(!id||!conversation?.unread)return;this.#conversations.set(id,{...conversation,unread:!1}),this.#syncUnread(),this.#client.markRead(id).catch(()=>{let current=this.#conversations.get(id);if(current)this.#conversations.set(id,{...current,unread:!0});this.#syncUnread()})}#addFiles(files){this.#files=[...this.#files,...files].slice(0,maxFiles),this.#renderChips(),this.#syncSend(),this.#textarea.focus()}#autosize(){if(this.#textarea.style.blockSize="",this.#textarea.value==="")return;this.#textarea.style.blockSize="auto",this.#textarea.style.blockSize=`${Math.max(38,Math.min(this.#textarea.scrollHeight,140))}px`}#syncSend(){this.#sendButton.disabled=this.#textarea.value.trim()===""&&this.#files.length===0}#typingInput(){let id=this.#view?.kind==="thread"?this.#view.id:null;if(!id||this.#textarea.value.trim()===""){this.#stopTyping();return}if(Date.now()-this.#typingSentAt>3000)this.#typingSentAt=Date.now(),this.#client.setTyping(id,!0).catch(()=>{return});if(this.#typingIdle)clearTimeout(this.#typingIdle);this.#typingIdle=setTimeout(()=>this.#stopTyping(),4000)}#stopTyping(){if(this.#typingIdle)clearTimeout(this.#typingIdle);if(this.#typingIdle=null,this.#typingSentAt===0)return;this.#typingSentAt=0;let id=this.#view?.kind==="thread"?this.#view.id:null;if(id)this.#client.setTyping(id,!1).catch(()=>{return})}async#send(){if(this.#phase!=="ready"||this.#view?.kind!=="thread")return;let body=this.#textarea.value.trim(),files=this.#files;if(!body&&files.length===0)return;if(this.#view.id===null&&this.#pending.some((p)=>p.conversation===null))return;this.#stopTyping(),this.#textarea.value="",this.#files=[],this.#autosize(),this.#renderChips(),this.#syncSend();let pending={client_id:randomId2(),conversation:this.#view.id,body,files,state:"sending"};this.#pending.push(pending),this.#render(),this.#scrollToEnd(),await this.#deliver(pending)}async#deliver(pending){pending.state="sending",this.#render();let input={body:pending.body,files:pending.files,client_id:pending.client_id};try{if(pending.conversation===null){let created=await this.#client.startConversation(input),id=created.conversation.id;if(!this.#conversations.has(id))this.#conversations.set(id,created.conversation);if(!this.#threads.has(id))this.#threads.set(id,{messages:[],complete:!0,loading:!1});if(this.#view?.kind==="thread"&&this.#view.id===null)this.#view={kind:"thread",id};this.#upsertMessage(created.message,!1)}else{let message=await this.#client.sendMessage(pending.conversation,input);this.#upsertMessage(message,!0)}this.#pending=this.#pending.filter((p)=>p!==pending)}catch(error){let status=error instanceof ApiError2?error.status:0;pending.state=status===413||status===415?"refused":"failed",pending.status=status}this.#render(),this.#scrollToEnd()}async rate(id,rating,comment){try{let conversation=await this.#client.rate(id,rating,comment);return this.#conversations.set(conversation.id,conversation),this.#ratings.delete(id),this.#render(),conversation}catch(error){if(error instanceof ApiError2&&error.status===409){let current=await this.#client.getConversation(id).catch(()=>null);if(current)this.#conversations.set(current.id,current);this.#ratings.delete(id),this.#render()}throw error}}#choose(id,choice){if(this.#ratings.get(id)?.state==="sending")return;if(this.#ratings.set(id,{choice,state:"choosing"}),this.#render(),this.#rateComment.focus({preventScroll:!0}),this.#atEnd)this.#scrollToEnd()}async#submitRating(id,withComment){let draft=this.#ratings.get(id);if(!draft||draft.state==="sending")return;draft.state="sending",this.#render();try{await this.rate(id,draft.choice,withComment?this.#rateComment.value:void 0),this.#rateComment.value=""}catch(error){if(error instanceof ApiError2&&error.status===409)return;draft.state="failed",this.#render()}}async#saveEmail(){let email=this.#emailInput.value.trim();if(!email||!this.#emailInput.checkValidity()){this.#emailError=this.#t({id:"E_qvzP"}),this.#renderEmail();return}try{this.#contact=await this.#client.setEmail(email),this.#emailSaved=!0,this.#emailError=""}catch{this.#emailError=this.#t({id:"ZxJcgC"})}this.#renderEmail()}#attachmentUrl(attachment){let cached=this.#blobs.get(attachment.id);if(cached)return Promise.resolve(cached);let load=this.#blobLoads.get(attachment.id);if(!load)load=this.#client.attachment(attachment.id).then((blob)=>{let url=URL.createObjectURL(blob);return this.#blobs.set(attachment.id,url),url}),load.catch(()=>this.#blobLoads.delete(attachment.id)),this.#blobLoads.set(attachment.id,load);return load}async#download(attachment){let url=await this.#attachmentUrl(attachment),a=el("a");a.href=url,a.download=attachment.filename,a.rel="noopener",a.click()}#sorted(){return[...this.#conversations.values()].sort(byActivity)}#nobodyAvailable(){let inbox=this.#inbox;if(!inbox)return!1;return!inbox.open_now||inbox.mode==="async"||!inbox.presence?.available}#scrollToEnd(){this.#atEnd=!0,this.#scroll.scrollTop=this.#scroll.scrollHeight,requestAnimationFrame(()=>{if(this.#atEnd)this.#scroll.scrollTop=this.#scroll.scrollHeight})}#renderAll(){this.#textarea.placeholder=this.#t({id:"RzWUUK"}),this.#textarea.setAttribute("aria-label",this.#t({id:"xDAtGP"})),this.#attachButton.setAttribute("aria-label",this.#t({id:"N7m8E-"})),this.#attachButton.title=this.#t({id:"N7m8E-"}),this.#sendButton.setAttribute("aria-label",this.#t({id:"JlFcis"})),this.#sendButton.title=this.#t({id:"JlFcis"}),this.#emailInput.placeholder=this.#t({id:"njBr8W"}),this.#emailInput.setAttribute("aria-label",this.#t({id:"XJURKP"})),this.#syncSend(),this.#renderChips(),this.#render()}#render(){let panel=this.#host.panel;if(panel.childElementCount===0){let fallback=addStyles(panel.getRootNode(),styles);panel.append(...fallback?[fallback]:[],this.#header,this.#banner,this.#body,this.#live),this.#header.id="yuva-title",panel.setAttribute("aria-labelledby","yuva-title")}if(this.#renderHeader(),this.#renderBanner(),this.#phase!=="ready"){this.#scrollThread=void 0;let center=el("div","center");if(this.#phase==="loading")center.append(el("p","hint",this.#t({id:"Pwqkdw"})));else{center.append(el("p","empty",this.#errorText()));let retry=el("button","primary",this.#t({id:"KDw4GX"}));retry.type="button",retry.addEventListener("click",()=>{this.#starting=null,this.#start()}),center.append(retry)}this.#body.replaceChildren(center);return}if(this.#view?.kind==="list")this.#renderList();else this.#renderThread()}#errorText(){switch(this.#error){case"anonymous_not_allowed":return this.#t({id:"zLzEI3"});case"invalid_identity_token":return this.#t({id:"0XGLbP"});case"rate_limited":return this.#t({id:"tzsBOP"});case"network":return this.#t({id:"GQVIIl"});default:return this.#t({id:"Amai22"})}}#renderHeader(){let{layout}=this.#host.config(),inbox=this.#inbox,children=[],view=this.#view;if(this.#phase==="ready"&&view?.kind==="thread"&&(this.#conversations.size>1||view.id===null&&this.#conversations.size>0))children.push(iconButton(icons.back,this.#t({id:"S63MQu"}),()=>{this.#stopTyping(),this.#view={kind:"list"},this.#render()}));let heading=el("div","heading");if(heading.append(el("h2","title",inbox?.name||this.#t({id:"t7TeQU"}))),inbox){let status=el("div","status");if(inbox.mode==="live"&&inbox.open_now&&inbox.presence?.available){let avatars=el("div","avatars");for(let member of inbox.presence?.members.slice(0,3)??[]){let avatar=el("span","avatar",member.initials||"•");avatar.title=member.name,avatars.append(avatar)}status.append(avatars,el("span","dot"),el("span","",this.#t({id:"oXOSPE"})))}else if(!inbox.open_now||inbox.mode==="live")status.append(el("span","dot away"),el("span","",this.#t({id:"1EICzz"})));else status.append(el("span","",this.#replyTime(inbox.expected_reply_minutes)));heading.append(status)}if(children.push(heading),layout==="launcher")children.push(iconButton(icons.close,this.#t({id:"yz7wBu"}),()=>this.#host.close()));this.#header.replaceChildren(...children)}#replyTime(minutes){if(!minutes)return this.#t({id:"nhTADq"});let{locale}=this.#host.config(),[value,unit]=minutes<60?[minutes,"minute"]:minutes<1440?[Math.round(minutes/60),"hour"]:[Math.round(minutes/1440),"day"],duration=new Intl.NumberFormat(locale,{style:"unit",unit,unitDisplay:"long"}).format(value);return this.#t({id:"VggdQJ",values:{duration}})}#renderBanner(){this.#banner.hidden=!this.#reconnecting,this.#banner.textContent=this.#t({id:"09Tv5j"})}#renderList(){this.#scrollThread=void 0;let{locale}=this.#host.config(),list=el("ul","list"),today=new Date().toDateString();for(let conversation of this.#sorted()){let button=el("button",conversation.unread?"item unread":"item");button.type="button";let main=el("div","item-main"),top=el("div","item-top");top.append(el("span","item-subject",conversation.subject||this.#inbox?.name||this.#t({id:"YyNOE7"})));let at=new Date(conversation.last_message_at??conversation.created_at);top.append(el("span","item-time",new Intl.DateTimeFormat(locale,at.toDateString()===today?{timeStyle:"short"}:{month:"short",day:"numeric"}).format(at)));let preview=conversation.last_message?`${conversation.last_message.author_type==="contact"?this.#t({id:"ydzYKJ"})+" ":""}${conversation.last_message.text||this.#t({id:"UY1vmE"})}`:"",previewLine=el("div","item-preview",preview.replace(/\*\*|`/g,""));if(previewLine.dir="auto",main.append(top,previewLine),button.append(main),conversation.unread)button.append(el("span","unread-dot"));button.addEventListener("click",()=>void this.#openThread(conversation.id));let item=el("li");item.append(button),list.append(item)}if(this.#conversationCursor){let more=el("button","link",this.#t({id:"ASr-r0"}));more.type="button",more.style.margin="8px auto",more.style.display="block",more.addEventListener("click",()=>void this.#loadConversations(!0).then(()=>this.#render())),list.append(more)}let start=el("button","primary",this.#t({id:"-HY5kX"}));start.type="button",start.addEventListener("click",()=>{this.#view={kind:"thread",id:null},this.#render(),this.#textarea.focus()}),this.#body.replaceChildren(list,start)}async#openThread(id){if(this.#view={kind:"thread",id},this.#render(),!this.#threads.get(id)?.complete&&!this.#threads.get(id)?.messages.length)await this.#loadMessages(id).catch(()=>{return});this.#render(),this.#scrollToEnd(),this.#markRead()}#avatar(author){let avatar=el("span","avatar",author.initials||""),url=author.avatar_url,state=url?this.#avatars.get(url):!1;if(!url||state===!1)return avatar;let img=el("img");if(img.alt="",img.referrerPolicy="no-referrer",state)return img.src=url,avatar.replaceChildren(img),avatar;return img.addEventListener("load",()=>{if(this.#avatars.set(url,!0),avatar.isConnected)avatar.replaceChildren(img)}),img.addEventListener("error",()=>this.#avatars.set(url,!1)),img.src=url,avatar}#renderThread(){let view=this.#view;if(view?.kind!=="thread")return;let id=view.id,sameThread=this.#scrollThread===id,atEnd=this.#atEnd,thread=id?this.#threads.get(id):void 0,messages=thread?.messages??[],pending=this.#pending.filter((p)=>p.conversation===id),nodes=[],greeting=this.#inbox?.chat.greeting;if(!thread||thread.complete){if(greeting){let bubble=el("div","bubble greeting");bubble.append(richText(greeting)),nodes.push(bubble)}else if(messages.length===0&&pending.length===0){let center=el("div","center");center.append(el("p","empty",this.#t({id:"meAa31"})),el("p","hint",this.#t({id:"SdV5Cn"}))),nodes.push(center)}}else if(thread.loading)nodes.push(el("p","hint",this.#t({id:"Pwqkdw"})));messages.forEach((message,i)=>{let previous=messages[i-1],next=messages[i+1]??(pending.length>0?null:void 0),mine=message.author.type==="contact",starts=!previous||authorKey(previous)!==authorKey(message)||time(message.created_at)-time(previous.created_at)>groupGap,ends=next===void 0||(next===null?!mine:authorKey(next)!==authorKey(message)||time(next.created_at)-time(message.created_at)>groupGap);if(!mine&&starts&&message.author.name)nodes.push(el("div","author",message.author.name));let row=el("div",`row ${mine?"mine":"theirs"}${starts&&i>0?" group-gap":""}`);if(!mine){let avatar=this.#avatar(message.author);if(!ends)avatar.style.visibility="hidden";row.append(avatar)}let bubble=el("div","bubble");if(bubble.dir="auto",bubble.title=new Date(message.created_at).toLocaleString(this.#host.config().locale),message.body.trim())bubble.append(richText(message.body));if(message.attachments.length>0)bubble.append(this.#renderAttachments(message.attachments));if(row.append(bubble),nodes.push(row),ends){let meta=this.#formatTime(message.created_at);if(mine&&i===messages.length-1&&pending.length===0){let readAt=id?this.#conversations.get(id)?.last_read_by_member_at:void 0,seen=readAt&&time(readAt)>=time(message.created_at);meta+=` · ${seen?this.#t({id:"6lGaum"}):this.#t({id:"h69WC6"})}`}let line=el("div","meta",meta);if(!mine)line.style.alignSelf="flex-start";if(!mine)line.style.marginInlineStart="36px";nodes.push(line)}});let conversation=id?this.#conversations.get(id):void 0,rate=conversation?this.#renderRating(conversation):null;if(rate)nodes.push(rate);pending.forEach((item,i)=>{let row=el("div",`row mine${i===0&&messages.length>0&&messages[messages.length-1]?.author.type!=="contact"?" group-gap":""}`),bubble=el("div","bubble");if(bubble.dir="auto",item.body)bubble.append(richText(item.body));if(item.files.length>0){let files=el("div","files");for(let file of item.files)files.append(el("span","file",file.name||"image"));bubble.append(files)}if(row.append(bubble),nodes.push(row),item.state==="failed"){let line=el("div","meta failed",`${this.#t({id:"upFvcp"})} `),retry=el("button","link",this.#t({id:"6gRgw8"}));retry.type="button",retry.addEventListener("click",()=>void this.#deliver(item)),line.append(retry),nodes.push(line)}else if(item.state==="refused"){let reason=item.status===413?this.#t({id:"eOu9Px"}):this.#t({id:"JkW3Ph"});nodes.push(el("div","meta failed",`${this.#t({id:"upFvcp"})} ${reason}`))}else if(i===pending.length-1)nodes.push(el("div","meta",this.#t({id:"Sad2tK"})))});let typing=id?this.#typing.get(id):void 0;if(typing){let line=el("div","typing");line.append(el("i"),el("i"),el("i"));let name=typing.name;line.append(el("span","",name?this.#t({id:"tHaDPf",values:{name}}):this.#t({id:"PxYAul"}))),nodes.push(line)}let focused=this.#scroll.getRootNode().activeElement===this.#rateComment,{selectionStart,selectionEnd}=this.#rateComment;if(this.#scroll.replaceChildren(...nodes),focused&&this.#rateComment.isConnected)this.#rateComment.focus({preventScroll:!0}),this.#rateComment.setSelectionRange(selectionStart,selectionEnd);if(this.#renderEmail(),this.#body.firstChild!==this.#scroll)this.#body.replaceChildren(this.#scroll,this.#email,this.#composer);if(this.#scrollThread=id,!sameThread||atEnd)this.#scrollToEnd()}#renderRating(conversation){let rated=conversation.status==="closed"?conversation.rating:void 0,draft=conversation.can_rate&&this.#inbox?.ask_for_rating?this.#ratings.get(conversation.id):void 0;if(!rated&&!(conversation.can_rate&&this.#inbox?.ask_for_rating))return null;let card=this.#rateCard,key=[conversation.id,rated,draft?.choice,draft?.state,this.#host.config().locale].join(":");if(key===this.#rateKey)return card;if(this.#rateKey=key,this.#rateFor!==conversation.id)this.#rateFor=conversation.id,this.#rateComment.value="";let question=this.#t({id:"uA8iBc"});card.setAttribute("role","group"),card.setAttribute("aria-label",question);let choices=el("div","choices");for(let value of["good","bad"]){if(rated&&rated!==value)continue;let button=el("button","choice",value==="good"?"\uD83D\uDC4D":"\uD83D\uDC4E");button.type="button";let label=value==="good"?this.#t({id:"OEEQKT"}):this.#t({id:"-f5Tkb"});button.setAttribute("aria-label",label),button.title=label,button.setAttribute("aria-pressed",String((rated??draft?.choice)===value)),button.disabled=!!rated||draft?.state==="sending",button.addEventListener("click",()=>this.#choose(conversation.id,value)),choices.append(button)}if(rated)return card.replaceChildren(choices,el("p","",this.#t({id:"SOk0EB"}))),card;if(card.replaceChildren(el("p","",question),choices),!draft)return card;this.#rateComment.placeholder=this.#t({id:"axQ1h6"}),this.#rateComment.setAttribute("aria-label",this.#t({id:"NBdIgR"})),this.#rateComment.disabled=draft.state==="sending";let form=el("form");form.addEventListener("submit",(event)=>{event.preventDefault(),this.#submitRating(conversation.id,!0)});let skip=el("button","link",this.#t({id:"6Uau97"}));skip.type="button",skip.disabled=draft.state==="sending",skip.addEventListener("click",()=>void this.#submitRating(conversation.id,!1));let send=el("button","",draft.state==="sending"?this.#t({id:"Sad2tK"}):this.#t({id:"JlFcis"}));send.type="submit",send.disabled=draft.state==="sending";let actions=el("div","actions");if(actions.append(skip,send),form.append(this.#rateComment,actions),card.append(form),draft.state==="failed")card.append(el("p","error",this.#t({id:"4TqZiz"})));return card}#renderAttachments(attachments){let files=el("div","files");for(let attachment of attachments)if(isImage(attachment)){let img=el("img");img.alt=attachment.filename;let cached=this.#blobs.get(attachment.id);if(cached)img.src=cached;else this.#attachmentUrl(attachment).then((url)=>{img.src=url}).catch(()=>{return});img.addEventListener("load",()=>{if(this.#atEnd)this.#scroll.scrollTop=this.#scroll.scrollHeight}),img.addEventListener("click",()=>void this.#download(attachment)),files.append(img)}else{let button=el("button","file");button.type="button",button.innerHTML=icons.file,button.append(el("span","",attachment.filename)),button.addEventListener("click",()=>void this.#download(attachment)),files.append(button)}return files}#formatTime(value){return new Intl.DateTimeFormat(this.#host.config().locale,{timeStyle:"short"}).format(new Date(value))}#renderEmail(){let contact=this.#contact,chat=this.#inbox?.chat,sent=(this.#view?.kind==="thread"?this.#view.id:null)!==null||this.#pending.length>0,known=contact?.email||contact?.typed_email,show=!!chat?.ask_email_offline&&this.#nobodyAvailable()&&sent&&(!known||this.#emailSaved);if(this.#email.hidden=!show,!show)return;if(known&&this.#emailSaved){this.#email.replaceChildren(el("p","",this.#t({id:"iGNUZJ",values:{known}})));return}if(this.#email.querySelector("form")){let error=this.#email.querySelector(".error");if(error)error.textContent=this.#emailError;else if(this.#emailError)this.#email.append(el("p","error",this.#emailError));return}let form=el("form");form.noValidate=!0,form.addEventListener("submit",(event)=>{event.preventDefault(),this.#saveEmail()});let save=el("button","",this.#t({id:"tfDRzk"}));if(save.type="submit",form.append(this.#emailInput,save),this.#email.replaceChildren(el("p","",this.#t({id:"M62PBt"})),form),this.#emailError)this.#email.append(el("p","error",this.#emailError))}#renderChips(){this.#chips.hidden=this.#files.length===0,this.#chips.replaceChildren(...this.#files.map((file,index)=>{let chip=el("span","chip");return chip.append(el("span","",file.name||"image"),iconButton(icons.close,this.#t({id:"w61W3L",values:{0:file.name}}),()=>{this.#files=this.#files.filter((_,i)=>i!==index),this.#renderChips(),this.#syncSend()})),chip}))}}function mount(host){return new Chat(host)}export{mount};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { type EventHandlerRequest, type EventHandlerWithFetch, type H3Event, type Middleware } from "h3";
|
|
2
|
+
import type { ServerAnalytics, ServerEvent } from "./server/analytics.js";
|
|
3
|
+
import { type IdentityClaims } from "./server/identity.js";
|
|
4
|
+
import { type WebhookEvent, type WebhookEventType } from "./server/webhook.js";
|
|
5
|
+
export interface YuvaContext {
|
|
6
|
+
track(event: ServerEvent): void;
|
|
7
|
+
}
|
|
8
|
+
declare module "h3" {
|
|
9
|
+
interface H3EventContext {
|
|
10
|
+
yuva?: YuvaContext;
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
14
|
+
export interface YuvaIdentityHandlerOptions {
|
|
15
|
+
secret: string;
|
|
16
|
+
user: (event: H3Event) => MaybePromise<IdentityClaims | null | undefined>;
|
|
17
|
+
ttl?: number;
|
|
18
|
+
}
|
|
19
|
+
export declare function defineYuvaIdentityHandler({ secret, user, ttl, }: YuvaIdentityHandlerOptions): EventHandlerWithFetch<EventHandlerRequest, Promise<Response>>;
|
|
20
|
+
export type WebhookPayload<K extends WebhookEventType> = Extract<WebhookEvent, {
|
|
21
|
+
type: K;
|
|
22
|
+
}>;
|
|
23
|
+
export type YuvaWebhookHandlers = {
|
|
24
|
+
[K in WebhookEventType]?: (payload: WebhookPayload<K>, event: H3Event) => unknown;
|
|
25
|
+
};
|
|
26
|
+
export interface YuvaWebhookHandlerOptions {
|
|
27
|
+
secret: string;
|
|
28
|
+
tolerance?: number;
|
|
29
|
+
on: YuvaWebhookHandlers;
|
|
30
|
+
}
|
|
31
|
+
export declare function defineYuvaWebhookHandler({ secret, tolerance, on, }: YuvaWebhookHandlerOptions): EventHandlerWithFetch<EventHandlerRequest, Promise<Response>>;
|
|
32
|
+
export interface YuvaAnalyticsOptions {
|
|
33
|
+
analytics: ServerAnalytics;
|
|
34
|
+
}
|
|
35
|
+
export declare function defineYuvaAnalytics({ analytics }: YuvaAnalyticsOptions): Middleware;
|
|
36
|
+
export {};
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { NitroModule } from "nitro/types";
|
|
2
|
+
import { type YuvaServerOptions } from "./setup.js";
|
|
3
|
+
export interface YuvaNitroOptions extends YuvaServerOptions {
|
|
4
|
+
server?: string;
|
|
5
|
+
}
|
|
6
|
+
export declare function yuva(options?: YuvaNitroOptions): NitroModule;
|
|
7
|
+
declare const _default: NitroModule;
|
|
8
|
+
export default _default;
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
import type { YuvaServer } from "./define.js";
|
|
2
|
+
export interface YuvaServerRuntimeConfig {
|
|
3
|
+
server?: string;
|
|
4
|
+
identitySecret?: string;
|
|
5
|
+
webhookSecret?: string;
|
|
6
|
+
analytics?: {
|
|
7
|
+
apiKey?: string;
|
|
8
|
+
propertyId?: string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
export interface YuvaRuntimeConfig {
|
|
12
|
+
yuva?: YuvaServerRuntimeConfig;
|
|
13
|
+
public?: {
|
|
14
|
+
yuva?: {
|
|
15
|
+
server?: string;
|
|
16
|
+
analytics?: {
|
|
17
|
+
server?: string;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
export interface YuvaHookEvent {
|
|
23
|
+
context: Record<string, unknown>;
|
|
24
|
+
}
|
|
25
|
+
export interface YuvaHooks {
|
|
26
|
+
hook(name: string, fn: (...args: never[]) => unknown): unknown;
|
|
27
|
+
}
|
|
28
|
+
export interface YuvaAdapter {
|
|
29
|
+
server: YuvaServer<YuvaHookEvent>;
|
|
30
|
+
config(): YuvaRuntimeConfig;
|
|
31
|
+
defineHandler(handler: (event: YuvaHookEvent) => Promise<Response>): unknown;
|
|
32
|
+
toRequest(event: YuvaHookEvent): Request;
|
|
33
|
+
trackRequest(event: YuvaHookEvent): Request;
|
|
34
|
+
onResponse(hooks: YuvaHooks, fn: (event: YuvaHookEvent) => void): void;
|
|
35
|
+
waitUntil(event: YuvaHookEvent): ((promise: Promise<unknown>) => void) | undefined;
|
|
36
|
+
}
|
|
37
|
+
export declare function identityHandler(yuva: YuvaAdapter): unknown;
|
|
38
|
+
export declare function webhookHandler(yuva: YuvaAdapter): unknown;
|
|
39
|
+
export declare function analyticsPlugin(yuva: YuvaAdapter): (nitroApp: {
|
|
40
|
+
hooks: YuvaHooks;
|
|
41
|
+
}) => void;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { IdentityClaims, ServerEvent, WebhookEvent, WebhookEventType } from "../../server.js";
|
|
2
|
+
export interface YuvaServerTypes {
|
|
3
|
+
}
|
|
4
|
+
export type YuvaServerEvent = YuvaServerTypes extends {
|
|
5
|
+
event: infer E;
|
|
6
|
+
} ? E : import("h3").H3Event;
|
|
7
|
+
type MaybePromise<T> = T | Promise<T>;
|
|
8
|
+
export type YuvaServerWebhooks<E = YuvaServerEvent> = {
|
|
9
|
+
[K in WebhookEventType]?: (payload: Extract<WebhookEvent, {
|
|
10
|
+
type: K;
|
|
11
|
+
}>, event: E) => unknown;
|
|
12
|
+
};
|
|
13
|
+
export interface YuvaServer<E = YuvaServerEvent> {
|
|
14
|
+
user?: (event: E) => MaybePromise<IdentityClaims | null | undefined>;
|
|
15
|
+
webhooks?: YuvaServerWebhooks<E>;
|
|
16
|
+
}
|
|
17
|
+
export interface YuvaContext {
|
|
18
|
+
track(event: ServerEvent): void;
|
|
19
|
+
}
|
|
20
|
+
export declare function defineYuvaServer<E = YuvaServerEvent>(server: YuvaServer<E>): YuvaServer<E>;
|
|
21
|
+
export {};
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import type { YuvaServerRuntimeConfig } from "./runtime/core.js";
|
|
2
|
+
export type { YuvaServerRuntimeConfig };
|
|
3
|
+
export declare const IDENTITY_ROUTE = "/_yuva/identity";
|
|
4
|
+
export declare const WEBHOOK_ROUTE = "/_yuva/webhook";
|
|
5
|
+
export declare const SERVER_MODULE = "#yuva/server";
|
|
6
|
+
export interface YuvaServerOptions {
|
|
7
|
+
identitySecret?: string;
|
|
8
|
+
webhookSecret?: string;
|
|
9
|
+
analytics?: {
|
|
10
|
+
apiKey?: string;
|
|
11
|
+
propertyId?: string;
|
|
12
|
+
};
|
|
13
|
+
}
|
|
14
|
+
export interface YuvaServerParts {
|
|
15
|
+
identity: boolean;
|
|
16
|
+
webhook: boolean;
|
|
17
|
+
analytics: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function serverRuntimeConfig(current: YuvaServerRuntimeConfig | undefined, options: YuvaServerOptions & {
|
|
20
|
+
server?: string;
|
|
21
|
+
}): Required<Omit<YuvaServerRuntimeConfig, "analytics">> & {
|
|
22
|
+
analytics: {
|
|
23
|
+
apiKey: string;
|
|
24
|
+
propertyId: string;
|
|
25
|
+
};
|
|
26
|
+
};
|
|
27
|
+
export declare function serverParts(config: YuvaServerRuntimeConfig, env: Record<string, string | undefined>, prefix: string): YuvaServerParts;
|
|
28
|
+
export declare function findServerFile(dir: string): string | undefined;
|
|
29
|
+
export declare function runtimePath(name: "identity" | "webhook" | "plugin"): string;
|
|
30
|
+
export interface ServerModuleOptions {
|
|
31
|
+
nitro: number;
|
|
32
|
+
server: string | undefined;
|
|
33
|
+
runtimeConfig: string;
|
|
34
|
+
h3?: string;
|
|
35
|
+
}
|
|
36
|
+
export declare function serverModule({ nitro, server, runtimeConfig, h3 }: ServerModuleOptions): string;
|
|
@@ -1,18 +1,32 @@
|
|
|
1
1
|
import type { AnalyticsOptions } from "../analytics.js";
|
|
2
|
+
import { type YuvaServerRuntimeConfig } from "../nitro/setup.js";
|
|
2
3
|
export interface AnalyticsModuleOptions extends Omit<AnalyticsOptions, "server"> {
|
|
3
4
|
server?: string;
|
|
5
|
+
apiKey?: string;
|
|
6
|
+
propertyId?: string;
|
|
4
7
|
}
|
|
8
|
+
export type PublicAnalyticsOptions = Omit<AnalyticsModuleOptions, "apiKey" | "propertyId">;
|
|
5
9
|
export interface ModuleOptions {
|
|
6
10
|
server?: string;
|
|
7
11
|
channel?: string;
|
|
8
12
|
locale?: string;
|
|
9
13
|
analytics?: AnalyticsModuleOptions;
|
|
14
|
+
identitySecret?: string;
|
|
15
|
+
webhookSecret?: string;
|
|
16
|
+
}
|
|
17
|
+
export interface PublicModuleConfig {
|
|
18
|
+
server: string;
|
|
19
|
+
channel: string;
|
|
20
|
+
locale: string;
|
|
21
|
+
identity: string;
|
|
22
|
+
analytics?: PublicAnalyticsOptions;
|
|
10
23
|
}
|
|
11
24
|
declare module "@nuxt/schema" {
|
|
12
25
|
interface PublicRuntimeConfig {
|
|
13
|
-
yuva:
|
|
14
|
-
|
|
15
|
-
|
|
26
|
+
yuva: PublicModuleConfig;
|
|
27
|
+
}
|
|
28
|
+
interface RuntimeConfig {
|
|
29
|
+
yuva?: YuvaServerRuntimeConfig;
|
|
16
30
|
}
|
|
17
31
|
}
|
|
18
32
|
declare const _default: import("@nuxt/schema").NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
export declare const MAX_BATCH = 100;
|
|
2
|
+
export interface ServerAnalyticsConfig {
|
|
3
|
+
server: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
propertyId: string;
|
|
6
|
+
fetch?: typeof fetch;
|
|
7
|
+
flushInterval?: number;
|
|
8
|
+
queueSize?: number;
|
|
9
|
+
maxRetries?: number;
|
|
10
|
+
minBackoff?: number;
|
|
11
|
+
clientIP?: (request: Request) => string | null | undefined;
|
|
12
|
+
onError?: (error: Error) => void;
|
|
13
|
+
}
|
|
14
|
+
export interface ServerEvent {
|
|
15
|
+
name: string;
|
|
16
|
+
url?: string;
|
|
17
|
+
referrer?: string;
|
|
18
|
+
time?: Date;
|
|
19
|
+
props?: Record<string, string | number | boolean>;
|
|
20
|
+
revenue?: {
|
|
21
|
+
amount: string;
|
|
22
|
+
currency: string;
|
|
23
|
+
};
|
|
24
|
+
nonInteractive?: boolean;
|
|
25
|
+
consent?: boolean;
|
|
26
|
+
ip?: string;
|
|
27
|
+
userAgent?: string;
|
|
28
|
+
secChUaPlatform?: string;
|
|
29
|
+
secChUaMobile?: string;
|
|
30
|
+
acceptLanguage?: string;
|
|
31
|
+
visitorKey?: string;
|
|
32
|
+
persistentId?: string;
|
|
33
|
+
identityToken?: string;
|
|
34
|
+
}
|
|
35
|
+
export interface ServerAnalytics {
|
|
36
|
+
track(request: Request, event: ServerEvent): void;
|
|
37
|
+
send(event: ServerEvent): void;
|
|
38
|
+
flush(): Promise<Error | undefined>;
|
|
39
|
+
close(): Promise<Error | undefined>;
|
|
40
|
+
}
|
|
41
|
+
export declare class AnalyticsEventError extends Error {
|
|
42
|
+
readonly event: ServerEvent;
|
|
43
|
+
readonly detail: string;
|
|
44
|
+
constructor(event: ServerEvent, detail: string);
|
|
45
|
+
}
|
|
46
|
+
export declare class AnalyticsBatchError extends Error {
|
|
47
|
+
readonly status: number;
|
|
48
|
+
readonly body: string;
|
|
49
|
+
readonly events: number;
|
|
50
|
+
constructor(events: number, status: number, body: string, cause?: unknown);
|
|
51
|
+
}
|
|
52
|
+
export declare function createAnalytics(config: ServerAnalyticsConfig): ServerAnalytics;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const utf8: (text: string) => Uint8Array<ArrayBuffer>;
|
|
2
|
+
export declare function base64(bytes: Uint8Array): string;
|
|
3
|
+
export declare const base64url: (bytes: Uint8Array) => string;
|
|
4
|
+
export declare function decodeBase64(text: string): Uint8Array<ArrayBuffer> | undefined;
|
|
5
|
+
export declare const hmacKey: (key: Uint8Array<ArrayBuffer>, usages: KeyUsage[]) => Promise<CryptoKey>;
|
|
6
|
+
export declare function goJSON(value: unknown): string | undefined;
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export declare const DEFAULT_IDENTITY_TTL = 300;
|
|
2
|
+
export declare const MAX_IDENTITY_TTL = 600;
|
|
3
|
+
export interface IdentityClaims {
|
|
4
|
+
subject: string;
|
|
5
|
+
email?: string;
|
|
6
|
+
emailVerified?: boolean;
|
|
7
|
+
name?: string;
|
|
8
|
+
locale?: string;
|
|
9
|
+
attrs?: Record<string, unknown>;
|
|
10
|
+
id?: string;
|
|
11
|
+
issuedAt?: Date;
|
|
12
|
+
ttl?: number;
|
|
13
|
+
}
|
|
14
|
+
export declare function signIdentityToken(secret: string, claims: IdentityClaims): Promise<string>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { webhooks } from "../schema.gen.js";
|
|
2
|
+
type Payload<K extends keyof webhooks> = webhooks[K]["post"] extends {
|
|
3
|
+
requestBody: {
|
|
4
|
+
content: {
|
|
5
|
+
"application/json": infer Body;
|
|
6
|
+
};
|
|
7
|
+
};
|
|
8
|
+
} ? Body : never;
|
|
9
|
+
export type WebhookEventType = keyof webhooks;
|
|
10
|
+
export type WebhookEvent = {
|
|
11
|
+
[K in WebhookEventType]: Omit<Payload<K>, "type"> & {
|
|
12
|
+
type: K;
|
|
13
|
+
};
|
|
14
|
+
}[WebhookEventType];
|
|
15
|
+
export declare const DEFAULT_WEBHOOK_TOLERANCE = 300;
|
|
16
|
+
export type WebhookErrorCode = "invalid_secret" | "missing_headers" | "invalid_timestamp" | "timestamp_too_old" | "timestamp_too_new" | "invalid_signature";
|
|
17
|
+
export declare class WebhookVerificationError extends Error {
|
|
18
|
+
readonly code: WebhookErrorCode;
|
|
19
|
+
constructor(code: WebhookErrorCode);
|
|
20
|
+
}
|
|
21
|
+
export interface VerifyWebhookOptions {
|
|
22
|
+
tolerance?: number;
|
|
23
|
+
now?: Date;
|
|
24
|
+
}
|
|
25
|
+
export declare function signWebhook(secret: string, id: string, timestamp: Date, body: string | Uint8Array): Promise<string>;
|
|
26
|
+
export declare function verifyWebhookBody(secret: string, headers: Headers, body: Uint8Array, { tolerance, now }?: VerifyWebhookOptions): Promise<void>;
|
|
27
|
+
export declare function verifyWebhook<T = WebhookEvent>(secret: string, request: Request, options?: VerifyWebhookOptions): Promise<T>;
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
export { DEFAULT_IDENTITY_TTL, MAX_IDENTITY_TTL, signIdentityToken, type IdentityClaims } from "./server/identity.js";
|
|
2
|
+
export { DEFAULT_WEBHOOK_TOLERANCE, signWebhook, verifyWebhook, verifyWebhookBody, WebhookVerificationError, type VerifyWebhookOptions, type WebhookErrorCode, type WebhookEvent, type WebhookEventType, } from "./server/webhook.js";
|
|
3
|
+
export { AnalyticsBatchError, AnalyticsEventError, createAnalytics, MAX_BATCH, type ServerAnalytics, type ServerAnalyticsConfig, type ServerEvent, } from "./server/analytics.js";
|