softchatjs-core
Version:
Javascript client for JS based frameworks
2 lines • 36 kB
JavaScript
import ie from"moment";function Q(i,t=0){let e=BigInt(t),n=BigInt(t),o=BigInt("0x87c37b91114253d5"),s=BigInt("0x4cf5ad432745937f"),a=i.length,d=a&15,r=a-d;for(let h=0;h<r;h+=16){let m=BigInt(i.charCodeAt(h))|BigInt(i.charCodeAt(h+1))<<BigInt(8)|BigInt(i.charCodeAt(h+2))<<BigInt(16)|BigInt(i.charCodeAt(h+3))<<BigInt(24)|BigInt(i.charCodeAt(h+4))<<BigInt(32)|BigInt(i.charCodeAt(h+5))<<BigInt(40)|BigInt(i.charCodeAt(h+6))<<BigInt(48)|BigInt(i.charCodeAt(h+7))<<BigInt(56),p=BigInt(i.charCodeAt(h+8))|BigInt(i.charCodeAt(h+9))<<BigInt(8)|BigInt(i.charCodeAt(h+10))<<BigInt(16)|BigInt(i.charCodeAt(h+11))<<BigInt(24)|BigInt(i.charCodeAt(h+12))<<BigInt(32)|BigInt(i.charCodeAt(h+13))<<BigInt(40)|BigInt(i.charCodeAt(h+14))<<BigInt(48)|BigInt(i.charCodeAt(h+15))<<BigInt(56);m=m*o,m=m<<BigInt(31)|m>>BigInt(33),m=m*s,e^=m,e=e<<BigInt(27)|e>>BigInt(37),e=e+n,e=e*BigInt(5)+BigInt("0x52dce729"),p=p*s,p=p<<BigInt(33)|p>>BigInt(31),p=p*o,n^=p,n=n<<BigInt(31)|n>>BigInt(33),n=e+n,n=n*BigInt(5)+BigInt("0x38495ab5")}let g=BigInt(0),c=BigInt(0);switch(d){case 15:c^=BigInt(i.charCodeAt(r+14))<<BigInt(48);case 14:c^=BigInt(i.charCodeAt(r+13))<<BigInt(40);case 13:c^=BigInt(i.charCodeAt(r+12))<<BigInt(32);case 12:c^=BigInt(i.charCodeAt(r+11))<<BigInt(24);case 11:c^=BigInt(i.charCodeAt(r+10))<<BigInt(16);case 10:c^=BigInt(i.charCodeAt(r+9))<<BigInt(8);case 9:c^=BigInt(i.charCodeAt(r+8)),c=c*s,c=c<<BigInt(33)|c>>BigInt(31),c=c*o,n^=c;case 8:g^=BigInt(i.charCodeAt(r+7))<<BigInt(56);case 7:g^=BigInt(i.charCodeAt(r+6))<<BigInt(48);case 6:g^=BigInt(i.charCodeAt(r+5))<<BigInt(40);case 5:g^=BigInt(i.charCodeAt(r+4))<<BigInt(32);case 4:g^=BigInt(i.charCodeAt(r+3))<<BigInt(24);case 3:g^=BigInt(i.charCodeAt(r+2))<<BigInt(16);case 2:g^=BigInt(i.charCodeAt(r+1))<<BigInt(8);case 1:g^=BigInt(i.charCodeAt(r)),g=g*o,g=g<<BigInt(31)|g>>BigInt(33),g=g*s,e^=g}return e^=BigInt(a),n^=BigInt(a),e+=n,n+=e,e^=e>>BigInt(33),e=e*BigInt("0xff51afd7ed558ccd"),e^=e>>BigInt(33),e=e*BigInt("0xc4ceb9fe1a85ec53"),e^=e>>BigInt(33),n^=n>>BigInt(33),n=n*BigInt("0xff51afd7ed558ccd"),n^=n>>BigInt(33),n=n*BigInt("0xc4ceb9fe1a85ec53"),n^=n>>BigInt(33),e+=n,n+=e,(e&BigInt("0xFFFFFFFFFFFFFFFF")).toString(16)}function A(i,t,e){let o=[i,t].sort().join("_");return Q(`${e}:${o}`)}var u=()=>{let i="",t="abcdef0123456789";for(let e=0;e<32;e++){let n=Math.floor(Math.random()*t.length),o=t.charAt(n);(e===8||e===12||e===16||e===20)&&(i+="-"),i+=o}return i};var l=()=>({createdAt:new Date,updatedAt:new Date});var C=class C{constructor(t,e){this.connection=t,this.participants=e}static getInstance(t,e){return C.conversation||(C.conversation=new C(t,e)),C.conversation}generateConversation(t,e){let n=l(),o=this.participants.map(r=>r.uid),s={id:u(),uid:this.connection.userMeta.uid,participantId:this.connection.userMeta.uid,participantDetails:{...this.connection.userMeta,...n},...n},a=this.participants.map(r=>({id:u(),uid:r.uid,participantId:r.uid,participantDetails:{...r,...n},...n})),d=[s,...a];return{name:t,participants:[this.connection.userMeta.uid,...o],admins:[this.connection.userMeta.uid],conversationId:e,messages:[],conversationType:"broadcast-chat",participantList:d,meta:null,groupMeta:null,...n}}create(t=`${this.participants.length} Recipients`){try{if(!this.connection)throw new Error("Inialize uesr before calling method");let e=u(),n=this.generateConversation(t,e),o={action:"createBroadcastList",message:{conversationId:e,name:t,participants:this.participants,token:this.connection.wsAccessConfig.token,user:this.connection.userMeta}};return this.connection.socket.send(JSON.stringify(o)),this.connection.broadcastListMeta[e]={conversation:n,lastMessage:null,unread:[]},this.reset(),this.connection.emit("broadcast_list_meta_changed",{broadcastListMeta:this.connection.broadcastListMeta}),{[e]:{conversation:n,lastMessage:null,unread:[]}}}catch(e){e instanceof Error&&console.error(e.message)}}reset(){C.conversation=null}};C.conversation=null;var N=C;import w from"axios";var I="https://api.softchatjs.com";var M=async i=>{try{let e=(await w({url:i.endpoint,method:i.method,headers:{"Cache-Control":"no-cache",accessToken:i.token||"","Content-Type":"application/json",...i.headers},data:i.method==="POST"?i.body:void 0,responseType:"json",timeout:3e4})).data;return typeof e=="object"&&e&&"success"in e?e:{...e,success:!1}}catch(t){throw console.log(t,"fetch error"),w.isAxiosError(t)&&t.response?new Error(`HTTP error! Status: ${t.response.status}`):new Error("An unknown error occurred.")}};async function U({userId:i,subId:t,projectId:e}){return await M({endpoint:`${I}/auth/session`,body:{userId:i,projectId:e,subId:t},method:"POST"})}async function x(i){return await M({endpoint:`${I}/conversations`,body:{},method:"GET",token:i})}async function H(i,t){return await M({endpoint:`${I}/conversation/${t}`,body:{},method:"GET",token:i})}async function j(i){return await M({endpoint:`${I}/broadcastlists`,body:{},method:"GET",token:i})}async function V(i,t,e){return await M({endpoint:`${I}/messages/${t}${e?"?page="+e:""}`,body:{},method:"GET",token:i})}async function F(i,t,e){return await M({endpoint:`${I}/broadcastlist/messages/${t}${e?"?page="+e:""}`,body:{},method:"GET",token:i})}async function W(i){return await M({endpoint:`${I}/gifs/trending`,body:{},method:"GET",token:i})}async function J(i,t){return await M({endpoint:`${I}/upload`,body:t,method:"POST",token:i})}async function D(i,t){return await M({endpoint:`${I}/presigned-url`,body:t,method:"POST",token:i})}import R from"moment";var $=1e3,T=class i{constructor(t,e){this.rotateAndInsertMessageList=(t,e)=>{var n=[...t];if(t.length>=25){var n=[...t];return n.unshift(),n.push(e),n}return n.push(e),n};this.showTypingIndicator=(t,e)=>{e==="START"?this.connection.emit("started_typing",{conversationId:t}):(this._clearActiveTypingIndicator(t),this.idleTimers[t]=setTimeout(()=>{this.connection.emit("stopped_typing",{conversationId:t})},4e3))};this.connection=t,this.idleTimers={},this.screen="conversations"}static getInstace(t,e){return i.message_client?(e&&(i.message_client.connection.activeConversationId=e),i.message_client):(i.message_client=new i(t,e),i.message_client)}getPublicMethods(){return{getMessages:this.getMessages.bind(this),sendMessage:this.sendMessage.bind(this),editMessage:this.editMessage.bind(this),sendTypingNotification:this.sendTypingNotification.bind(this),reactToMessage:this.reactToMessage.bind(this),uploadAttachment:this.uploadAttachment.bind(this)}}getConversationType(t){try{return this.connection.conversationListMeta[t||this.connection.activeConversationId].conversation.conversationType}catch{return"private-chat"}}_createMessage(t){try{if(t){let o={action:"sendMessage",message:{messageId:t.messageId,from:this.connection.userMeta.uid,to:t.to,conversationType:this.getConversationType(),message:{...t,messageState:3},user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}};if(this.connection.emit("new_message",{message:{...t,reactions:[],messageState:2}}),this.connection.socket&&this.connection.socket?.readyState===WebSocket.OPEN){this.connection.socket.send(JSON.stringify(o)),this.connection.emit("edited_message",{message:{...t,reactions:[],messageState:3}});var e=this.connection.conversationListMeta[t.conversationId],n=this.rotateAndInsertMessageList(e.conversation.messages,{...t,reactions:[],messageState:3});let s=e.unread;this.connection.conversationListMeta[t.conversationId]={conversation:{...e.conversation,messages:n},lastMessage:{...t},unread:s},this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}else this.connection.emit("edited_message",{message:{...t,reactions:[],messageState:1}}),this.connection.conversationListMeta[t.conversationId]={conversation:this.connection.conversationListMeta[t.conversationId].conversation,lastMessage:{...t,messageState:1},unread:[]},this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}}catch(o){o instanceof Error&&(console.error(o),this.connection.emit("deleted_message",{message:{...t,reactions:[],messageState:1}}))}}editConversationListMetaMessage({isBroadcast:t,updatedMessage:e}){var n=t?this.connection.broadcastListMeta[e.conversationId]:this.connection.conversationListMeta[e.conversationId],o=e.messageId;if(n){var s=n.conversation.messages.find(r=>r.messageId===o);if(s){var a={...s,message:e.textMessage,lastEdited:new Date},d=n.conversation.messages.map(r=>r.messageId===o?a:r);t?(this.connection.broadcastListMeta[e.conversationId]={conversation:{...n.conversation,messages:d},lastMessage:null,unread:[]},this.connection.emit("broadcast_list_meta_changed",{broadcastListMeta:this.connection.broadcastListMeta})):(this.connection.conversationListMeta[e.conversationId]={conversation:{...n.conversation,messages:d},lastMessage:{...a},unread:n.unread},this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta}))}}}_editMessage(t){try{if(t){let e={...t,message:t.textMessage,lastEdited:new Date};if(this.connection.emit("edited_message",{message:e}),this.editConversationListMetaMessage({isBroadcast:!1,updatedMessage:e}),this.editConversationListMetaMessage({isBroadcast:!0,updatedMessage:e}),this.connection.socket){let n={action:"editMessage",message:{...e,token:this.connection.wsAccessConfig.token,isBroadcast:t.isBroadcast,user:this.connection.userMeta}};this.connection.socket.send(JSON.stringify(n))}}}catch(e){console.error(e)}}_updateMessageReactions(t,e,n,o){try{if(this.connection.emit("edited_message",{message:{messageId:e,reactions:n}}),o?.ws){let c={action:"sendMessageReaction",message:{conversationId:t,messageId:e,from:this.connection.userMeta.uid,to:o.to,reactions:n,token:this.connection.wsAccessConfig.token,user:this.connection.userMeta}};this.connection.socket.send(JSON.stringify(c))}var s=this.connection.conversationListMeta[t],a=s?.lastMessage;if(a&&a.messageId===e){var d={...a,reactions:n},r=this.rotateAndInsertMessageList(s.conversation.messages,d),g={conversation:{...s.conversation,messages:r},unread:s.unread,lastMessage:{...d}};this.connection.conversationListMeta[t]=g,this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}}catch(c){c instanceof Error}}storeEditedMessage(t){let e=this.connection.conversationMap[t.conversationId];if(e){var n=e.messages.find(o=>o.messageId===t.messageId);if(n){let o={...n,message:t.textMessage,lastEdited:new Date};this.connection.emit("edited_message",{message:o})}}}_sendTypingNotification(t){this.connection.socket&&this.connection.socket.send(JSON.stringify({action:"userTyping",message:{uid:t,conversationId:this.connection.activeConversationId,action:"START",conversationType:this.getConversationType(this.connection.activeConversationId),user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}}))}_sendStoppedTypingNotification(t){this.connection.socket&&this.connection.socket.send(JSON.stringify({action:"userTyping",message:{uid:t,conversationId:this.connection.activeConversationId,action:"STOP",conversationType:this.getConversationType(this.connection.activeConversationId),user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}}))}addMessageToConversation(t,e){try{let n=this.connection.conversationMap[t.conversationId];if(n){let o=[...n.messages,{...t,messageState:e==="chat"?5:3}];this.connection.conversationMap[t.conversationId]={...n,messages:o},this.connection.emit("new_message",{message:{...t,messageState:e==="chat"?5:3}});let s=[...this.connection.conversationListMeta[t.conversationId].unread];t.conversationId!==this.connection.activeConversationId&&s.push(t.messageId);let a={conversation:{...this.connection.conversationListMeta[t.conversationId].conversation,messages:o},lastMessage:{...t},unread:s};this.connection.conversationListMeta[t.conversationId]=a,this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}}catch(n){console.error(n)}}sendReadNotification(t){this.connection.socket&&this.connection.socket.send(JSON.stringify({action:"readMessages",message:{...t,user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}}))}_clearActiveTypingIndicator(t,e){clearTimeout(this.idleTimers[t]),delete this.idleTimers[t],e===!0&&this.connection.emit("stopped_typing",{conversationId:t})}_updateConversationListMetaMessages(){}readMessages(t,e){if(this.connection.socket){let n={action:"readMessages",message:{...e,user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}};this.connection.socket.send(JSON.stringify(n));let o=this.connection.conversationListMeta[t];if(o){let s={...this.connection.conversationListMeta,[t]:{...o,unread:[]}};this.connection.conversationListMeta=s,this.connection.emit("conversation_list_meta_changed",{conversationListMeta:s})}}}clearUserUnreadNotifications(t,e){for(var n=0,o=e.length;n<o;)this.connection.emit("edited_message",{message:{messageId:e[n],messageState:5}}),n++}wsOnError(t){this.connection.emit("connection_changed",{isConnected:!1,connecting:!1,fetchingConversations:!1})}deleteMessageFromConversationMeta(t,e){try{let a=this.connection.conversationListMeta[t];var n=e===a.lastMessage?.messageId;if(a){let d=a.conversation.messages.filter(r=>r.messageId!==e);var o=d[d.length-1],s={...a,conversation:{...a.conversation,messages:d}};n&&(s.lastMessage=o||null),this.connection.conversationListMeta[t]=s,this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}else throw new Error(`Conversation with ID ${t} not found.`)}catch(a){a instanceof Error&&console.error(a.message)}}reactToMessage({conversationId:t,messageId:e,reactions:n,to:o}){this.connection&&this._updateMessageReactions(t,e,n,{ws:!0,to:o})}sendMessage(t){if(this.connection){let o=u();var e=l(),n={...this.connection.userMeta,...e};let s={...t,quotedMessageId:t?.quotedMessage?.messageId,from:n.uid,lastEdited:null,messageState:2,messageOwner:n,messageId:o,...e};this._createMessage(s)}}updateBroadcastList(t){try{if(this.connection.socket&&this.connection.socket?.readyState===WebSocket.OPEN){let e={action:"deleteBroadcastList",message:{broadcastListId:t.broadcastListId,participants:t.participants,name:t.name,user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}};this.connection.socket.send(JSON.stringify(e))}else console.error("Failed to send broadcast")}catch(e){e instanceof Error&&console.error(e.message)}}deleteBroadcastList(t){try{if(this.connection.socket&&this.connection.socket?.readyState===WebSocket.OPEN){let e={action:"updateUserBroadcastList",message:{broadcastListId:t.broadcastListId,participants:t.participants,name:t.name,user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}};this.connection.socket.send(JSON.stringify(e)),this.connection.broadcastListMeta[t.broadcastListId]&&(delete this.connection.broadcastListMeta[t.broadcastListId],this.connection.emit("broadcast_list_meta_changed",{broadcastListMeta:this.connection.broadcastListMeta}))}else console.error("Failed to send broadcast")}catch(e){e instanceof Error&&console.error(e.message)}}broadcastMessage({broadcastListId:t,participantsIds:e,newMessage:n}){try{if(this.connection.socket&&this.connection.socket?.readyState===WebSocket.OPEN){let g=u();var o=l(),s={...this.connection.userMeta,...o};let c={...n,quotedMessageId:n?.quotedMessage?.messageId,from:s.uid,lastEdited:null,messageState:3,messageOwner:s,messageId:g,isBroadcast:!0,broadcastListId:t,...o},h={action:"sendMessageToBroadcastList",message:{broadcastListId:t,messageId:g,from:s.uid,to:e,shouldEdit:!1,conversationType:"broadcast-chat",message:c,user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}};var a=this.connection.broadcastListMeta[t],d=[...a.conversation.messages];d.push(c);var r={conversation:{...a.conversation,messages:d},lastMessage:null,unread:[]};this.connection.broadcastListMeta[t]=r,this.connection.socket.send(JSON.stringify(h)),e.map(m=>{let p=A(m,s.uid,this.connection.projectConfig.projectId);this.connection.emit("new_message",{message:{...c,conversationId:p,reactions:[]}});var S=this.connection.conversationListMeta[p];S&&(this.connection.conversationListMeta[p]={conversation:{...S.conversation,messages:[...S.conversation.messages,{...c,conversationId:p,reactions:[]}]},lastMessage:{...c,conversationId:p,reactions:[]},unread:S.unread})}),this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta}),this.connection.emit("new_message",{message:{...c,conversationId:t,reactions:[]}}),this.connection.emit("broadcast_list_meta_changed",{broadcastListMeta:this.connection.broadcastListMeta})}else console.error("Failed to send broadcast")}catch(g){g instanceof Error&&console.error(g.message)}}editMessage(t){this.connection&&this._editMessage({...t,from:this.connection.userMeta.uid})}sendTypingNotification(t){this.connection&&this._sendTypingNotification(t)}sendStoppedTypingNotification(t){this.connection&&this._sendStoppedTypingNotification(t)}deleteMessage(t,e,n){this.connection&&(this.connection.socket.send(JSON.stringify({action:"deleteMessage",message:{messageId:t,to:e,conversationId:n,conversationType:this.getConversationType(),user:this.connection.userMeta,token:this.connection.wsAccessConfig.token}})),this.connection.emit("deleted_message",{message:{conversationId:n,messageId:t}}),this.deleteMessageFromConversationMeta(n,t))}async getMessages(t){if(this.connection)try{let e=await V(this.connection.wsAccessConfig.token,this.connection.activeConversationId,t);return e.success?[...e.data.messages].sort((o,s)=>{let a=R(o.createdAt).valueOf(),d=R(s.createdAt).valueOf();return a-d}):[]}catch(e){return console.error(e),[]}else return[]}async getBroadcastListMessages(t){if(this.connection)try{let e=await F(this.connection.wsAccessConfig.token,this.connection.activeConversationId,t);return e.success?[...e.data.messages].sort((o,s)=>{let a=R(o.createdAt).valueOf(),d=R(s.createdAt).valueOf();return a-d}):[]}catch(e){return console.error(e),[]}else return[]}async getConversation(t){if(this.connection)try{let e=await H(this.connection.wsAccessConfig.token,t);return e.success?e.data.conversation:null}catch{return null}else return null}async getEmojiList(){if(this.connection)try{return(await W(this.connection.wsAccessConfig.token)).data.gifs}catch{return[]}else return[]}async uploadAttachment({base64:t,fileKey:e}){if(this.connection)try{return await J(this.connection.wsAccessConfig?.token,{base64:t,conversationId:this.connection.activeConversationId,key:e})}catch(n){n instanceof Error&&console.error(n.message)}else throw new Error("No connection established")}isReadableStream(t){return t&&typeof t.pipe=="function"}async uploadFile(t,e){try{let n=await D(this.connection.wsAccessConfig?.token,{base64:"",conversationId:this.connection.activeConversationId,key:u(),mediaType:e.mimeType,uid:this.connection.userMeta.uid,ext:e.ext}),o,s=0;if(typeof t=="string")o=await(await fetch(t)).blob(),s=o.size;else if(t instanceof File)o=t,s=t.size;else if(Buffer.isBuffer(t))o=new Blob([t],{type:e.mimeType}),s=t.length;else if(this.isReadableStream(t)){let a=[],d=0;for await(let g of t)a.push(g),d+=g.length;let r=Buffer.concat(a);o=new Blob([r],{type:e.mimeType}),s=d}return await fetch(n.data.uploadUrl,{method:"PUT",body:o,headers:{"Content-Type":e.mimeType}}),{link:n.data.s3Link,success:n.success,fileSize:s}}catch(n){return console.log(n),console.error("Error uploading file: ",n),{link:"",success:!1,fileSize:""}}}async uploadAttachmentV2({base64:t,fileKey:e,mediaType:n,mimeType:o}){if(this.connection)try{let s=await D(this.connection.wsAccessConfig?.token,{base64:t,conversationId:this.connection.activeConversationId,key:u(),mediaType:n,uid:this.connection.userMeta.uid,ext:""}),a=await fetch(s.data.uploadUrl,{method:"PUT",body:{base64:t,fileKey:e,mediaType:n},headers:{"Content-Type":o}});return s}catch(s){s instanceof Error&&console.error(s.message)}else throw new Error("No connection established")}async setActiveConversation(){if(this.connection)this.connection.screen="chat",this.screen="chat";else throw new Error("No connection established")}async unSetActiveConversation(){if(this.connection)this.connection.activeConversationId="",this.connection.screen="conversations",this.screen="conversations";else throw new Error("No connection established")}messageEventHandler(t){try{if(!t)return null;var e=JSON.parse(t.data);let s=e.action;if(this.screen==="chat"&&this.connection.activeConversationId===e?.message?.conversationId){if(s==="incomingMessage"){let{message:a}=JSON.parse(t.data);this._clearActiveTypingIndicator(this.connection.activeConversationId,!0),this.sendReadNotification({uid:a.from,messageIds:[a.messageId]})}if(s==="messagesRead"){let{message:a}=e;this.screen==="chat"&&this.connection.activeConversationId===a.conversationId&&setTimeout(()=>{this.clearUserUnreadNotifications(a.conversationId,a.messageIds)},$)}}switch(s){case"messagesRead":let{message:a}=e;this.connection.conversationMap[a.conversationId]&&this.screen==="chat"&&setTimeout(()=>{this.clearUserUnreadNotifications(a.conversationId,a.messageIds)},$);break;case"incomingMessage":let{message:r}=e;var n=r.message;let g=this.connection.conversationMap[n.conversationId];if(this._clearActiveTypingIndicator(n.conversationId,!0),g)this.addMessageToConversation(n,this.screen);else{let Y=r.conversationType==="private-chat"?A(n.from,n.to,this.connection.projectConfig.projectId):r.message.conversationId,E={...n,messageId:u(),messageState:3,createdAt:new Date};var o={participants:[E.from,E.to],conversationId:A(E.from,E.to,this.connection.projectConfig.projectId),messages:[E],admins:[E.from],meta:null,groupMeta:null,conversationType:r.conversationType,participantList:[{id:u(),uid:E.from,connectionId:"--",participantId:E.from,projectId:"--",participantDetails:{...r.senderMeta,...l()},...l()},{id:u(),uid:E.to,connectionId:"--",participantId:E.to,projectId:"--",participantDetails:{...this.connection.userMeta,...l()},...l()}],...l()};let q={conversation:o,lastMessage:E,unread:[]};this.connection.conversationListMeta[Y]=q,this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta})}break;case"userIsTyping":let{message:c}=e;this.showTypingIndicator(c.conversationId,c.action);break;case"newMessageReaction":let{message:h}=e;this._updateMessageReactions(h.conversationId,h.messageId,h.reactions);break;case"sendMessageError":let{message:m}=e;console.error("Failed to send message, please try again",m);break;case"editedMessage":let{message:p}=e;this._clearActiveTypingIndicator(p.conversationId,!0),this.storeEditedMessage(p);break;case"deletedMessage":let{message:S}=e;this.connection.emit("deleted_message",{message:S}),this.deleteMessageFromConversationMeta(S.conversationId,S.messageId);break;case"acknowledgeHealthCheck":console.info("HEALTH_CHECK: ok!");break;default:console.log("Unknown action recieved")}this.connection.socket.onerror=a=>{this.wsOnError(a)}}catch(s){console.error(s)}}};import k from"isomorphic-ws";import X from"events";import K from"moment";var ee={id:"",uid:"",username:"",firstname:"",lastname:"",profileUrl:"",color:"",custom:{}};var f={NO_CONNECTION:{connecting:!1,isConnected:!1,fetchingConversations:!1},GETTING_CONVERSATIONS:{connecting:!0,isConnected:!1,fetchingConversations:!0},SOCKET_CONNECTING:{connecting:!0,isConnected:!1,fetchingConversations:!1},SOCKET_CONNECTED:{connecting:!1,isConnected:!0,fetchingConversations:!1}},y=class i extends X{constructor(t){super(),this.connecting=!1,this.socket=null,this.conversations=[],this.conversationMap={},this.conversationListMeta={},this.broadcastListMeta={},this.wsAccessConfig={url:"",token:""},this.retry_delay_ms=5e3,this.max_retry_count=5,this.health_check_interval=3e4,this.retry_count=0,this.userMeta=ee,this.projectConfig={projectId:t.projectId,subId:t.subId},this.activeConversationId="",this.screen="conversations",this.healthCheckRef=void 0,this.shouldReconnect=!0,this.connectionState=f.NO_CONNECTION,this.notificationConfig={type:null,token:null}}static getInstance(t){return i.connection||(i.connection=new i(t)),i.connection}updateConnectionState(t){this.connectionState=t,this.emit("connection_changed",t)}async _getConversations({token:t}){try{if(this.userMeta){this.updateConnectionState(f.GETTING_CONVERSATIONS);let n=await x(t);if(n.success){let o=n.data.conversations.reduce((s,a)=>{var d=this.sortConversationMessages([a]),r=d[0].messages,g=r[r.length-1];return s[a.conversationId]={conversation:d[0],lastMessage:g,unread:this._getUreadMessageIds(this.userMeta.uid,r)},s},{});var e=n.data.conversations.reduce((s,a)=>(s[a.conversationId]=a,s),{});this.conversationMap=e,this.emit("conversation_list_meta_changed",{conversationListMeta:o}),this.conversationListMeta=o,this.conversations=n.data.conversations}else console.error("An error occurred while fetching conversations")}else throw new Error("User not initialized")}catch(n){n instanceof Error&&console.error(n)}finally{}}async _getBroadcastLists({token:t}){try{if(this.userMeta){let e=await j(t);if(e.success){let n=e.data.conversations.reduce((o,s)=>{var a=this.sortConversationMessages([s]),d=a[0].messages,r=d[d.length-1];return o[s.conversationId]={conversation:a[0],lastMessage:r,unread:[]},o},{});this.emit("broadcast_list_meta_changed",{broadcastListMeta:n}),this.broadcastListMeta=n}else console.error("An error occurred while fetching broadcast lists")}else throw new Error("User not initialized")}catch(e){e instanceof Error&&console.error(e)}finally{}}async _initiateConnection(t,e){try{if(this.shouldReconnect=!0,this.userMeta=t,e?.connectionConfig?.reset&&(this.retry_count=0),!this.userMeta?.uid)return null;clearTimeout(this.retryRef),clearTimeout(this.retryRef),e?.notificationConfig&&(this.notificationConfig=e.notificationConfig);let n=await U({userId:this.userMeta.uid,projectId:this.projectConfig.projectId,subId:this.projectConfig.subId});if(n.success){this.wsAccessConfig={url:n.data.wsURI,token:n.data.token},await Promise.all([await this._getConversations({token:n.data.token}),await this._getBroadcastLists({token:n.data.token})]),this.updateConnectionState(f.SOCKET_CONNECTING);let o=JSON.stringify({from:this.userMeta.uid,to:"",action:"initialize",userMeta:{...this.userMeta},newConversation:!0,recipientMeta:{},projectId:this.projectConfig.projectId,notification:this.notificationConfig});if(this.socket&&this.socket.readyState===k.OPEN)this.socket.send(o),this.updateConnectionState(f.SOCKET_CONNECTED);else{this.socket&&this.socket.close();let s=new k(`wss://${this.wsAccessConfig.url}`);s.onopen=()=>{console.log("socket opened"),this.socket=s,s.send(o),this.setupEventHandlers(),this.connecting=!1,this.updateConnectionState(f.SOCKET_CONNECTED),this.emit("conversation_list_changed",{conversations:this.conversations}),this.retry_count=0}}}else this.updateConnectionState(f.NO_CONNECTION)}catch(n){console.error("Connection error:",n),this.updateConnectionState(f.NO_CONNECTION),console.warn("Connection error. Attempting to reconnect..."),this.retryConnection()}finally{}}sortMesssages(t){var e=t.sort((n,o)=>{let s=new Date(n.createdAt).getTime();return new Date(o.createdAt).getTime()-s});return e}sortConversationMessages(t){return t.map(e=>{let n=[...e.messages].sort((o,s)=>{let a=K(o.createdAt).valueOf(),d=K(s.createdAt).valueOf();return a-d});return{...e,messages:n}})}_getUreadMessageIds(t,e){var n=[];return e.map(o=>{o.messageState===3&&o.from!==t&&n.push(o.messageId)}),n}_wsDisconnect(t){try{if(this.socket){this.shouldReconnect=t?.shouldReconnect??!0;let e=JSON.stringify({action:"clearUserSession",message:{projectId:this.projectConfig.projectId,from:this.userMeta.uid,user:this.userMeta}});this.socket.send(e),this.socket.close(),this.conversationMap={},this.conversationListMeta={},this.broadcastListMeta={},this.updateConnectionState(f.NO_CONNECTION)}}catch(e){e instanceof Error&&console.error(e.message)}}startHealthCheck(){this.socket&&(this.healthCheckRef&&clearInterval(this.healthCheckRef),this.healthCheckRef=setInterval(()=>{if(this.socket?.readyState===k.OPEN){let t=JSON.stringify({action:"healthCheck",message:{message:"Hello!",from:this.userMeta.uid,token:this.wsAccessConfig.token,user:this.userMeta}});this.socket.send(t),this.emit("conversation_list_meta_changed",{conversationListMeta:this.conversationListMeta})}},3e4))}retryConnection(){if(this.retry_count>=this.max_retry_count)return console.warn("Connection attempt failed after multiple retries. Please check your network settings or try again.");this.updateConnectionState(f.SOCKET_CONNECTING),this.connectionState.isConnected||(this.retryRef=setTimeout(()=>{this._initiateConnection(this.userMeta),this.retry_count+=1},5e3))}setupEventHandlers(){this.socket&&(this.socket.onmessage=t=>{T.getInstace(this,"").messageEventHandler(t)},this.socket.onerror=t=>{this.shouldReconnect&&(console.error("Socket error. Attempting to reconnect... Event: ",t),this.retryConnection())},this.socket.onclose=()=>{this.shouldReconnect&&(console.warn("Socket closed. Attempting to reconnect..."),this.retryConnection())},this.startHealthCheck())}};var G=(e=>(e.USER_NOT_INITIATED="Unable to call method, call (initializeUser) method first, Err callingfunction: ",e.CONVERSATION_NOT_PREPARED="Method newConversation() on conversation was not called",e))(G||{}),B=(i,t)=>G[i]+t;var z={id:"",username:"",email:"",firstname:"",lastname:"",profileImgUrl:"",phone:"",profileBannerUrl:"",custom:{}},v=class v{constructor(t,e,n){this.connection=t,this.participants=[],this.otherParticipant=null,this.conversationType="private-chat",Array.isArray(e)?(this.conversationType="group-chat",this.participants=e.map(o=>({...z,...o})),this.groupMeta=n):(this.otherParticipant={...z,...e},this.conversationType="private-chat",this.groupMeta=null)}static getInstance(t,e,n){return v.conversation||(v.conversation=new v(t,e,n)),v.conversation}generateConversation(t,e,n,o){let s=l(),a=e.map(c=>c.uid),d={id:u(),uid:this.connection.userMeta.uid,participantId:this.connection.userMeta.uid,participantDetails:{...this.connection.userMeta,...s},...s},r=e.map(c=>({id:u(),uid:c.uid,participantId:c.uid,participantDetails:{...c,...s},...s})),g=[d,...r];return{participants:[this.connection.userMeta.uid,...a],admins:[this.connection.userMeta.uid],conversationId:t,messages:n.message.length>0?[n]:[],conversationType:o,participantList:g,meta:null,groupMeta:o==="group-chat"?this.groupMeta:null,...s}}create(t){try{let n=u(),o=u(),s={messageId:n,from:this.connection.userMeta.uid,to:[{}],conversationType:this.conversationType,groupMeta:this.groupMeta||{groupName:"My group",groupIcon:"https://picsum.photos/200/300",groupBanner:"https://picsum.photos/200/300"},senderMeta:this.connection.userMeta,participantIds:[],message:{message:t||"",messageId:n,messageState:3,conversationId:"",from:this.connection.userMeta.uid,to:"",attachmentType:"none",messageOwner:{...this.connection.userMeta,meta:this.connection.userMeta,...l()},attachedMedia:[],quotedMessageId:"",quotedMessage:null,reactions:[],lastEdited:null,...l()},token:this.connection.wsAccessConfig.token};if(this.conversationType==="group-chat"){if(this.participants.length===0)throw new Error("Method newConversation() on conversation was not called");let a=this.participants.map(d=>d.uid);s.message.conversationId=o,s.to=this.participants,s.participantIds=[...a,this.connection.userMeta.uid],this.sendMessage(s,o,this.participants,"group-chat")}else{if(!this.otherParticipant)throw new Error("Method newConversation() on conversation was not called");let a=A(this.connection.userMeta.uid,this.otherParticipant.uid,this.connection.projectConfig.projectId);s.message.conversationId=a,s.message.to=this.otherParticipant.uid,s.to=[this.otherParticipant],s.participantIds=[this.otherParticipant.uid,this.connection.userMeta.uid];var e=this.sendMessage(s,a,[this.otherParticipant],"private-chat");return e}}catch(n){n instanceof Error&&console.error(n.message)}}sendMessage(t,e,n,o){try{let g={action:"createConversation",message:t,user:this.connection.userMeta};var s;if(this.connection.socket){if(this.connection.socket.send(JSON.stringify(g)),this.connection.conversationListMeta[e]){let c=this.connection.conversationListMeta[e];var d=[...c.conversation.messages];t.message.message.length>0&&d.unshift(t.message);var r={conversation:{...c.conversation,messages:d},lastMessage:t.message,unread:[]};this.connection.conversationListMeta[e]=r,s=r}else{let c=this.generateConversation(e,n,t.message,o);var a=t.message.message.length>0;this.connection.conversationListMeta[e]={conversation:c,lastMessage:a?t.message:null,unread:[]},s={conversation:c,lastMessage:t.message,unread:[]}}return this.connection.emit("conversation_list_meta_changed",{conversationListMeta:this.connection.conversationListMeta}),this.reset(),s}}catch(g){g instanceof Error&&console.error(g.message)}}reset(){v.conversation=null}};v.conversation=null;var _=v;import te from"isomorphic-ws";var P=class i{constructor(t,e){this.subId=t,this.projectId=e,this.chatUserId="",this.connection=null}static getInstance({projectId:t,subId:e}){return i.client_instance||(i.client_instance=new i(e,t)),i.client_instance}initializeUser(t,e){if(t&&i.client_instance){let n=y.getInstance(i.client_instance);this.connection=n,this.connection.updateConnectionState(f.GETTING_CONVERSATIONS),n._initiateConnection(t,e),this.chatUserId=t.uid}}disconnect(){if(this.connection)return this.connection._wsDisconnect({shouldReconnect:!1});throw new Error(B("USER_NOT_INITIATED","disconnect"))}retryConnection(){if(this.connection)this.connection.socket?.readyState!==te.OPEN&&(console.info("Retrying connection..."),this.connection.userMeta&&(this.connection.emit("connection_changed",{connecting:!0,isConnected:!1,fetchingConversations:!0}),this.connection._initiateConnection(this.connection.userMeta,{connectionConfig:{reset:!0},notificationConfig:this.connection.notificationConfig})));else throw new Error(B("USER_NOT_INITIATED","retryConnection"))}getConnectionStatus(){return this.connection?this.connection.connectionState:f.NO_CONNECTION}subscribe(t,e){if(this.connection)this.connection.on(t,e);else throw new Error("Unable to subscribe for events, create a connection first")}unsubscribe(t,e){this.connection&&this.connection.off(t,e)}unsubscribeAll(t){this.connection&&this.connection.removeAllListeners(t)}getConversations(){return this.connection?JSON.parse(JSON.stringify(this.connection.conversationListMeta)):(console.warn("No connection available, initialize user before calling method"),{})}getBroadcastLists(){return this.connection?JSON.parse(JSON.stringify(this.connection.broadcastListMeta)):(console.warn("No connection available, initialize user before calling method"),{})}newConversation(t,e){if(this.connection)return _.getInstance(this.connection,t,e);throw new Error("No connection available")}newBroadcastList(t){if(this.connection)return N.getInstance(this.connection,t);throw new Error("No connection available")}messageClient(t){if(this.connection){let e=T.getInstace(this.connection,t);return{getMessages:e.getMessages.bind(e),getBroadcastListMessages:e.getBroadcastListMessages.bind(e),getConversation:e.getConversation.bind(e),sendMessage:e.sendMessage.bind(e),broadcastMessage:e.broadcastMessage.bind(e),editMessage:e.editMessage.bind(e),sendTypingNotification:e.sendTypingNotification.bind(e),sendStoppedTypingNotification:e.sendStoppedTypingNotification.bind(e),reactToMessage:e.reactToMessage.bind(e),uploadFile:e.uploadFile.bind(e),setActiveConversation:e.setActiveConversation.bind(e),unSetActiveConversation:e.unSetActiveConversation.bind(e),getEmojiList:e.getEmojiList.bind(e),deleteMessage:e.deleteMessage.bind(e),readMessages:e.readMessages.bind(e)}}else throw new Error("No connection available")}};export{P as default};
//# sourceMappingURL=ChatClient.mjs.map