UNPKG

@rongcloud/imkit-store

Version:

RongCloud IM UIKit Store

2 lines (1 loc) 35.7 kB
import{ConversationType as e,BaseMessage as t,sendMessage as s,getFileToken as i,getFileUrl as o,MessageType as r,addEventListener as n,Events as a,getHistoryMessages as h,ErrorCode as c,recallMessage as _,SentStatus as u,clearMessagesUnreadStatus as g,removeEventListener as d,getConversationList as S,NotificationLevel as l,sendSyncReadStatusMessage as E,removeMonitor as p,addMonitor as m,removeConversation as O,setConversationNotificationLevel as T,setConversationToTop as C,disconnect as f,__addSDKVersion as M,installPlugin as I}from"@rongcloud/imlib-next";import{isObject as N,ErrorCode as R,fixUrlProtocol as v,UploadMethod as y,ConversationType as A,RCConnectionStatus as U}from"@rongcloud/engine";import{makeAutoObservable as D,observable as G,runInAction as P,reaction as L,comparer as w}from"mobx";const F=e=>`[${e.targetId}][${e.conversationType}][${e.channelId||""}]`,V=e=>{const[t,s,i]=e.split("][");return{targetId:t.replace("[",""),conversationType:~~s,channelId:i.replace("]","")}},x=(e,t)=>e.targetId===t.targetId&&e.conversationType===t.conversationType&&(e.channelId===t.channelId||!t.channelId);e.PRIVATE,e.GROUP,e.SYSTEM;const $=(e,t)=>{const s=e.messageUId&&t.messageUId?"messageUId":"messageId";return e[s]===t[s]},q=e=>JSON.parse(JSON.stringify(e)),b=(e,t=new WeakMap)=>{if(null===e||"object"!=typeof e||!e)return e;if(t.has(e))return t.get(e);let s;if(e instanceof Date)s=new Date(e.getTime());else if(e instanceof RegExp)s=new RegExp(e);else if(e instanceof Map)s=new Map,t.set(e,s),e.forEach(((e,i)=>{s.set(i,b(e,t))}));else if(e instanceof Set)s=new Set,t.set(e,s),e.forEach((e=>{s.add(b(e,t))}));else if(Array.isArray(e)){s=[],t.set(e,s);for(let i=0;i<e.length;i++)s[i]=b(e[i],t)}else{s=Object.create(Object.getPrototypeOf(e)),t.set(e,s);for(const i in e)Object.prototype.hasOwnProperty.call(e,i)&&(s[i]=b(e[i],t))}return s};class k{queue=[];maxSize;constructor(e){this.maxSize=e,D(this)}push(e,t){this.queue.push(b(e)),t&&this._trimExcess(!0)}pop(){return this.queue.pop()}unshift(e,t){this.queue.unshift(...b(e)),t&&this._trimExcess(!1)}shift(){return this.queue.shift()}clear(){this.queue=[]}set(e,t=!0){this.queue=b(e),t&&this._trimExcess()}get(){return b(this.queue)}resetExcess(){this._trimExcess()}splice(e,t,...s){this.queue.splice(e,t,...b(s))}_trimExcess(e=!0){0!==this.maxSize&&(this.queue.length<this.maxSize||(e?this.queue.splice(0,this.queue.length-this.maxSize):this.queue.splice(this.maxSize,this.queue.length-this.maxSize)))}get length(){return this.queue.length}}class Q{maxKeySize;map=new Map;activeMap=new Map;constructor(e=30){this.maxKeySize=e,D(this,{map:G,activeMap:!1})}get(e){const t=this.map.get(e);if(t)return this.activeMap.set(e,Date.now()),t.get()}getQueue(e){const t=this.map.get(e);if(t)return this.activeMap.set(e,Date.now()),t}set(e,t,s=!0,i=30){const o=new k(i);o.set(t,s),this.map.set(e,o),this.activeMap.set(e,Date.now()),this.removeOverdueKey()}removeOverdueKey(){if(this.map.size<=this.maxKeySize)return;const e=Array.from(this.activeMap.entries());e.sort(((e,t)=>t[1]-e[1]));e.slice(this.maxKeySize).forEach((e=>{this.delete(e[0])}))}delete(e){this.map.get(e)?.clear(),this.map.delete(e),this.activeMap.delete(e)}resetAllExcess(){this.map.forEach((e=>{e.resetExcess()}))}resetExcess(e){this.map.get(e)?.resetExcess()}clear(){this.map.forEach((e=>{e.clear()})),this.map.clear(),this.activeMap.clear()}}var K,B,H;!function(e){e.K_INIT_O="K_INIT_O",e.K_NOTIFY_GET_CONVERSATIONS_O="K_NOTIFY-GET-CONVERSATIONS_O",e.K_REMOVE_CONVERSATION_O="K_REMOVE-CONVERSATION_O",e.K_OPEN_CONVERSATION_O="K_OPEN-CONVERSATION_O",e.K_USER_PROFILE_NOT_FOUND_O="K_USER-PROFILE-NOT-FOUND_O",e.K_GROUP_PROFILE_NOT_FOUND_O="K_GROUP-PROFILE-NOT-FOUND_O",e.K_SYSTEM_PROFILE_NOT_FOUND_O="K_SYSTEM-PROFILE-NOT-FOUND_O",e.S_UPDATE_CACHE_O="S_UPDATE-CACHE_O",e.S_GET_CONVERSATION_E="S_GET-CONVERSATION_E",e.S_GET_CONVERSATION_T="S_GET-CONVERSATION_T",e.S_GET_CONVERSATION_R="S_GET-CONVERSATION_R",e.S_PUSH_2_QUEUE_O="S_PUSH-2-QUEUE_O",e.S_TASK_QUEUE_EXECUTE_O="S_PICK-ITEM-FROM-QUEUE_O",e.S_SEND_MSG_T="S_SEND-MSG_T",e.S_SEND_MSG_R="S_SEND-MSG_R",e.S_SEND_MSG_E="S_SEND-MSG_E",e.L_PARSE_CONVERSATION_E="L_PARSE_CONVERSATION_E",e.S_GET_GROUP_MEMBERS_HOOK_T="S_GET-GROUP-MEMBERS-HOOK_T",e.S_GET_GROUP_MEMBERS_HOOK_R="S_GET-GROUP-MEMBERS-HOOK_R",e.S_GET_GROUP_MEMBERS_HOOK_E="S_GET-GROUP-MEMBERS-HOOK_E",e.S_PARSE_CONVERSATION_E="S_PARSE-CONVERSATION_E",e.S_REMOVE_CONVERSATION_O="S_REMOVE-CONVERSATION_O",e.S_UPDATE_CONVERSATION_O="S_UPDATE-CONVERSATION_O",e.S_INSERT_MESSAGE_O="S_INSERT-MESSAGE_O",e.S_UPDATE_MESSAGE_O="S_UPDATE-MESSAGE_O",e.S_REMOVE_MESSAGE_O="S_REMOVE-MESSAGE_O",e.S_RECALL_MESSAGE_O="S_RECALL-MESSAGE_O",e.S_GET_HISTORY_MESSAGE_O="S_GET-HISTORY-MESSAGE_O",e.S_SEND_MESSAGE_O="S_SEND-MESSAGE_O",e.S_FORWARD_MESSAGE_O="S_FORWARD-MESSAGE_O",e.S_CANCEL_SEND_MEDIA_MESSAGE_O="S_CANCEL-SEND-MEDIA-MESSAGE_O",e.S_GET_SELECTED_MESSAGES_O="S_GET-SELECTED-MESSAGES_O",e.S_SET_SELECTED_MESSAGES_O="S_SET-SELECTED-MESSAGES_O",e.S_ON_SEND_BEFORE_S="S_ON-SEND-BEFORE_S",e.S_CLEAR_UNREAD_COUNT_O="S_CLEAR-UNREAD-COUNT_O",e.S_CLEAR_MESSAGES_UNREAD_STATUS_T="S_CLEAR-MESSAGES-UNREAD-STATUS_T",e.S_CLEAR_MESSAGES_UNREAD_STATUS_R="S_CLEAR-MESSAGES-UNREAD-STATUS_R",e.S_REMOVE_CONVERSATION_T="S_REMOVE-CONVERSATION_T",e.S_REMOVE_CONVERSATION_R="S_REMOVE-CONVERSATION_R",e.S_SET_CONVERSATION_NOTIFICATION_LEVEL_T="S_SET-CONVERSATION-NOTIFICATION-LEVEL_T",e.S_SET_CONVERSATION_NOTIFICATION_LEVEL_R="S_SET-CONVERSATION-NOTIFICATION-LEVEL_R",e.S_SET_CONVERSATION_TO_TOP_T="S_SET-CONVERSATION-TO-TOP_T",e.S_SET_CONVERSATION_TO_TOP_R="S_SET-CONVERSATION-TO-TOP_R",e.S_RECALL_MESSAGE_T="S_RECALL-MESSAGE_T",e.S_RECALL_MESSAGE_R="S_RECALL-MESSAGE_R",e.S_RECEIVE_DISCONNECT_NOTIFICATION_O="S_RECEIVE-DISCONNECT-NOTIFICATION_O"}(K||(K={})),function(e){e[e.TASK_CANCEL=39001]="TASK_CANCEL"}(B||(B={}));class z{_parallel;_fps;_logger;_timestamps=[];_queue=[];_executing=[];_timer=-1;constructor(e=5,t=5,s){this._parallel=e,this._fps=t,this._logger=s}destroy(){clearTimeout(this._timer),this._timer=-1}async push(e){return new Promise((t=>{this._queue.push({params:e,resolve:t}),this._logger.info(K.S_PUSH_2_QUEUE_O,`${this._tag}: queue length: ${this._queue.length}`),this._execute()}))}async _execute(){if(this._paused||0===this._queue.length||this._executing.length>=this._parallel)return;if(this._timestamps.length>=this._fps)return void this._logger.warn(K.S_TASK_QUEUE_EXECUTE_O,`${this._tag}: trigger limiting`);-1===this._timer&&(this._timer=setTimeout((()=>{this._timestamps.length=0,this._timer=-1,this._execute()}),1e3));const e=this._queue.shift();this._executing.push(e),this._timestamps.push(Date.now()),this._logger.info(K.S_TASK_QUEUE_EXECUTE_O,`${this._tag}: queue length: ${this._queue.length}, executing length: ${this._executing.length}`);const t=this._handle(e.params);this._execute();const{code:s,data:i}=await t;e.code=s,e.result=i,this._checkResolve()}_checkResolve(){for(;this._executing.length&&void 0!==this._executing[0].code;){const{resolve:e,code:t,result:s}=this._executing.shift();e({code:t,data:s})}this._execute()}_paused=!1}class J extends z{_logger;_tag="MessageSendQueue";constructor(e){super(10,5,e),this._logger=e}async _handle(e){const{conversation:i,message:o,options:r}=e,{conversationType:n,targetId:a,channelId:h}=i,c=this._logger.createTraceId();this._logger.info(K.S_SEND_MSG_T,`type: ${o.messageType}, conversationType: ${n}, targetId: ${a}, channelId: ${h||""}`,c);const{isCounted:_,isPersited:u,content:g,messageType:d}=o,S=new t(d,g,u,_);if(N(S.content))try{S.content=q(S.content)}catch(e){this._logger.warn(K.S_SEND_MSG_E,e.message)}const{code:l,data:E}=await s(i,S,{...r,onSendBefore(e){o.messageId=e.messageId,r?.onSendBefore?.(e)}});return l!==R.SUCCESS?this._logger.warn(K.S_SEND_MSG_R,`code: ${l}`,c):this._logger.info(K.S_SEND_MSG_R,"success",c),{code:l,data:E}}}!function(e){e.ALIYUN="aliyun",e.S3="s3",e.STC="stc",e.MINIO="minio",e.QINIU="qiniu",e.BAIDU="baidu",e.RCX="rcx"}(H||(H={}));class Y{_url;_getFileToken;_serverType=0;constructor(e,t,s){this._url=e,this._getFileToken=t,this._serverType=s}prepareUpload(e){return this.prepareUploadData(e)}prepareMultipart(e){return this.prepareMultipartData(e)}}class j{uploadInfo;_abortStatus=!1;_requestData;constructor(e){this.uploadInfo=e}setRequestData(e){this._requestData=e}abort(){this._abortStatus=!0}isAbort(){return this._abortStatus}}const W={[H.QINIU]:class extends Y{async prepareUploadData(e){const{fileSize:t,fileType:s}=e;try{const e=await this._getFileToken(s,void 0,void 0,void 0),{code:t,data:i}=e;if(t!==R.SUCCESS)return{code:t,msg:i};const{token:o,fileName:r}=i,n={token:o,key:r};return{code:R.SUCCESS,data:{url:v(this._url),headers:{},body:n,fileName:r,uniqueName:r,uploadMethod:y.QINIU}}}catch(e){return console.error("QINIU prepareUploadData error",e),{code:e}}}prepareMultipartData(e){throw new Error("Method not implemented.")}}};async function X(e,t,s){const{serverType:r,customDomain:n,ossConfig:a,uploadServer:h,bosAddr:c}=t;if(!a||0===a.length)return{code:R.INVALID_PARAMETER_MEDIA_URL,msg:"ossConfig is empty"};const _=function(e,t,s,i,o){if(s)return[{type:H.RCX,url:s,p:"1"}];if(e)return JSON.parse(e).map((e=>{const t={type:H.QINIU,url:"",p:""};return Object.keys(e).forEach((s=>{"p"===s?t.p=e[s]:(t.type=s,t.url=e[s])})),t})).sort(((e,t)=>e.p-t.p));const r=[];return i&&r.push({type:H.QINIU,url:i,p:"1"}),o&&r.push({type:H.BAIDU,url:o,p:"2"}),r}(a,0,n,h,c);if(0===_.length)return{code:R.INVALID_PARAMETER_MEDIA_URL,msg:"uploadUrlList is empty"};const u=[];for(let t=0;t<_.length;t++){const n=_[t];if(!(n.type in W))continue;const a=new W[n.type](n.url,i,r),h=await a.prepareUpload(e);if(h.code===R.SUCCESS&&h.data)try{s.setRequestData(h.data);const{uploadMethod:t,uniqueName:i}=h.data,r=await s.execute(),{code:a,data:c,msg:_}=r;if(a===R.RC_FILE_SIZE_EXCEED_LIMIT)return{code:a,msg:"File size exceeds the limit"};if(a===R.INVALID_PARAMETER_SIZE_NOT_FOUND)return{code:a,msg:"File size not found"};if(s.isAbort())return{code:a,msg:_};if(a===R.SUCCESS&&c){let{downloadUrl:s,name:r}=c;if(!s){const n=await o(e.fileType,i||"",r,void 0,t),{code:a,data:h}=n;a===R.SUCCESS&&h&&(s=h.downloadUrl)}return s?{code:R.SUCCESS,data:{downloadUrl:s}}:{code:R.UPLOAD_FAIL,msg:"Get download url fail"}}u.push({type:n.type,url:n.url,code:r.code,msg:r.msg})}catch(e){u.push({type:n.type,url:n.url,code:R.UPLOAD_FAIL,msg:e instanceof Error?e.message:String(e)})}else u.push({type:n.type,url:n.url,code:h.code,msg:h.msg})}return{code:R.UPLOAD_FAIL,msg:`Failed to upload through all channels, msg: ${JSON.stringify(u)}`}}class Z extends z{_logger;constructor(e){super(2,5,e),this._logger=e}_tag="UploadQueue";_handle(e){const{info:t,config:s,request:i}=e;return X(t,s,i)}}class ee{_logger;rootStore;_context;#e=new Q(10);#t;#s;#i=new Map;#o={[r.IMAGE]:"imageUri",[r.SIGHT]:"sightUrl",[r.HQ_VOICE]:"remoteUrl",[r.GIF]:"remoteUrl",[r.FILE]:"fileUrl"};#r=[];constructor(e,t,s){this._logger=e,this.rootStore=t,this._context=s,D(this),n(a.MESSAGES,this.#n.bind(this)),this.#t=new J(this._logger),this.#s=new Z(this._logger)}getMessages(t){const s=this.#e.get(t);if(!s||0===s.length)return[];const{conversationType:i}=V(t);switch(i){case e.GROUP:return this.#a(s);case e.SYSTEM:return this.#h(s);default:return this.#c(s)}}#a(e){if(0===e.length)return[];const t=this.rootStore.appData.groupMembersCache.getGroupMemberMap(e[0].targetId);return e.map((e=>({...e,user:{nickname:t.get(e.senderUserId)?.user.nickname||"",portraitUri:t.get(e.senderUserId)?.user.portraitUri||"",groupNickname:t.get(e.senderUserId)?.groupNickname||""}})))}#c(e){return 0===e.length?[]:e.map((e=>{const t=this.rootStore.appData.getUserInfo(e.senderUserId);return{...e,user:{nickname:t?.name||"",portraitUri:t?.portraitUri||""}}}))}#h(e){if(0===e.length)return[];const t=this.rootStore.appData.getSystemProfile(e[0].senderUserId);return e.map((e=>({...e,user:{nickname:t?.name||"",portraitUri:t?.portraitUri||""}})))}#_=()=>{const e=this._context.getNaviInfo();if(e&&"ossConfig"in e)return e.ossConfig};async getHistoryMsgList(e,t,s,i=20){this._logger.info(K.S_GET_HISTORY_MESSAGE_O,`${e}, ${t}, ${s}, ${i}`);const{code:o,data:r}=await h(V(e),{timestamp:t,count:i});if(o===c.SUCCESS&&r){const{list:t}=r;P((()=>{s?this.#e.getQueue(e)?.unshift(t,!1):this.#e.set(e,t,!0)}))}return{code:o,data:r}}insertMessage(e,t=!0,s=!0){const i=F({conversationType:e.conversationType,targetId:e.targetId,channelId:e.channelId});e.messageId&&0!==e.messageId||(e.messageId=(()=>{let e=0;const t=((4294967295&Date.now())>>>0).toString(2),s=Math.floor(255*Math.random()),i=t+e.toString(2).padStart(11,"0")+s.toString(2).padStart(8,"0");return e=2047&++e,parseInt(i,2)})());const o=this.#e.get(i);let r=!1;return o&&(r=o.some((t=>$(t,e)))),s&&this._logger.info(K.S_INSERT_MESSAGE_O,`${i}, ${e.messageUId}, ${e.messageId}, isRepeat: ${r}`),r||this.#e.getQueue(i)?.push(e,t),e}updateCatchedMessage(e){const t=F({conversationType:e.conversationType,targetId:e.targetId,channelId:e.channelId});this._logger.info(K.S_UPDATE_MESSAGE_O,`${t}, ${e.messageUId}, ${e.messageId}, ${e.messageType}, ${e.senderUserId}, ${e.sentTime}, ${e.sentStatus}`);const s=this.#e.getQueue(t);if(!s)return;const i=s.get(),o=i.findIndex((t=>$(t,e)));-1!==o&&s.splice(o,1,{...e,sentTime:e.sentTime||i[o].sentTime})}removeCatchedMessage(e){const t=F({conversationType:e.conversationType,targetId:e.targetId,channelId:e.channelId});this._logger.info(K.S_REMOVE_MESSAGE_O,`${t}, ${e.messageUId}, ${e.messageId}`);const s=this.#e.getQueue(t);if(!s)return;const i=s.get().findIndex((t=>$(t,e)));-1!==i&&s.splice(i,1)}async recallMessage(e){const{conversationType:t,targetId:s,channelId:i}=e;return this._logger.info(K.S_RECALL_MESSAGE_O,`${t}, ${s}, ${i}, ${e.messageUId}`),_({conversationType:t,targetId:s,channelId:i},{messageUId:e.messageUId,sentTime:e.sentTime})}async sendMessage(e,t,s){return this._logger.info(K.S_SEND_MESSAGE_O,`${e}, ${t.messageType}, ${s?.messageId}`),this.#t.push({conversation:V(e),message:this.#u(V(e),t),options:s})}async sendMediaMessage(e){const{conversationKey:t,message:s,info:i,request:o,sendOptions:n}=e;if(s.messageType!==r.IMAGE&&s.messageType!==r.SIGHT&&s.messageType!==r.HQ_VOICE&&s.messageType!==r.GIF&&s.messageType!==r.FILE)return{code:c.INVALID_PARAMETER_MESSAGE_CONTENT,msg:"Invalid message type"};const a=i?.path,h=this.#u(V(t),s,n,a);let _,g;if(n?.messageId?(g=n.messageId,h.sentStatus=u.SENDING,this.updateCatchedMessage(h),_=h):(_=this.insertMessage(h,!1,!0),g=_.messageId),!g)return{code:c.UPLOAD_FAIL,msg:"Insert message failed"};this.#i.set(g,o);try{const e={ossConfig:this.#_()},r=await this.#s.push({info:i,request:o,config:e});if(r.code===c.SUCCESS&&r.data){const{data:e}=r,i=this.#o[s.messageType];if(i&&e?.downloadUrl){s.content[i]=e.downloadUrl;const o={...n||{},messageId:g};return await this.sendMessage(t,s,o)}this._logger.warn(K.S_SEND_MSG_E,`Cannot set media URL: propertyName=${i}, hasUrl=${!!e?.downloadUrl}`)}else this._logger.warn(K.S_SEND_MSG_E,`Media upload failed: code=${r.code}, error=${r.code}`)}catch(e){this._logger.error(K.S_SEND_MSG_E,`Exception in sendMediaMessage: ${e}`)}finally{this.#i.delete(g)}return _.sentStatus=u.FAILED,this.updateCatchedMessage(_),{code:c.UPLOAD_FAIL,msg:"Upload failed",data:_}}forwardMessage(e,t){return this._logger.info(K.S_FORWARD_MESSAGE_O,`${e}, ${t.messageType}, ${t.messageUId}`),this.#t.push({conversation:V(e),message:t})}cancelSendMediaMessage(e){this._logger.info(K.S_CANCEL_SEND_MEDIA_MESSAGE_O,`${e}`);const t=this.#i.get(e);t&&(t.abort(),this.#i.delete(e))}getSelectedMessages(){return this._logger.info(K.S_GET_SELECTED_MESSAGES_O),q(this.#r)}setSelectedMessages(e){this._logger.info(K.S_SET_SELECTED_MESSAGES_O,`${e.length}`),this.#r=e}clearExcessMessage(e){this.#e.resetExcess(e)}#n(e){e.messages.forEach((e=>{const{conversationType:t,targetId:s,channelId:i,isPersited:o}=e,n=F({conversationType:t,targetId:s,channelId:i});switch(e.messageType){case r.RECALL_MESSAGE_TYPE:this.removeCatchedMessage({...e,messageUId:e.content.messageUId});break;case"RC:SRSMsg":g({conversationType:t,targetId:s,channelId:i})}o&&this.insertMessage(e,n!==this.rootStore.conversationStore?.openedConversation?.key,!1)}))}#u(e,t,s,i){const{conversationType:o,targetId:r,channelId:n}=e,{isCounted:a,isPersited:h,content:c,messageType:_}=t;return{targetId:r,conversationType:o,messageDirection:1,messageType:_,sentTime:this._context.getServerTime(),isStatusMessage:s?.isStatusMessage,isCounted:a,isPersited:h,content:c,channelId:n||"",senderUserId:this._context.getCurrentId(),receivedTime:0,messageUId:"",sentStatus:u.SENDING,isOffLineMessage:!1,canIncludeExpansion:s?.canIncludeExpansion||!1,receivedStatus:0,isMentioned:s?.isMentioned,expansion:s?.expansion,messageId:s?.messageId,localTmpPath:i}}destroy(){d(a.MESSAGES,this.#n),this.clearMemoryData()}clearMemoryData(){this.#e.clear(),this.#t.destroy(),this.#s.destroy(),this.#i.clear(),this.#r=[]}}class te{#g;#d=null;#S=()=>{};#l=()=>{};#E=()=>{};#p=null;#m=!1;#O=null;#T=null;#C=!1;#f=0;list=[];#M=new Map;#I=[];constructor(t,s){this.#g=t,this.#d=s,D(this),n(a.CONNECTED,this._onConnected.bind(this)),n(a.CONVERSATION,this._onRecvConversationNtf.bind(this)),n(a.PULL_OFFLINE_MESSAGE_FINISHED,this._onPullOfflineMessageFinished.bind(this)),this.#S=this.#N(this.#g.getUsersCache(),e.PRIVATE),this.#l=this.#N(this.#g.getGroupsCache(),e.GROUP),this.#E=this.#N(this.#g.getSystemsCache(),e.SYSTEM)}#N(e,t){return L((()=>Array.from(e.entries())),(s=>{P((()=>{this.list.forEach((s=>{if(s.conversationType===t&&e.has(s.targetId)){const{data:t}=e.get(s.targetId);s.name=t.name||"",s.portraitUri=t.portraitUri||"",this.#M.set(s.key,s)}}))}))}),{fireImmediately:!1,equals:w.structural})}getCachedConversationList(){return this.list.slice()}getOpenedConversation(){return this.#p}destroy(){d(a.CONNECTED,(()=>this._getMoreRemoteConversation)),d(a.CONVERSATION,this._onRecvConversationNtf),d(a.PULL_OFFLINE_MESSAGE_FINISHED,this._onPullOfflineMessageFinished),this.#S(),this.#l(),this.#E(),this.clearMemoryData()}clearMemoryData(){this.#I.length=0,this.#m=!1,this.#C=!1,this.#p=null,this.#f=0,this.list.length=0,this.#M.clear(),this.#d?.info(K.S_RECEIVE_DISCONNECT_NOTIFICATION_O,"clear memory data")}_onRecvConversationNtf(e){this.#I.push(...e.conversationList),this._handleQueue()}_onPullOfflineMessageFinished(){this.#O&&(clearTimeout(this.#O),this.#O=null),this.#T&&(clearTimeout(this.#T),this.#T=null),this.#C||this._getMoreRemoteConversation(!1),this.#C=!0}_handleQueueDelay(){this.#T||(this.#T=setTimeout((()=>{this.#T=null,this._handleQueue()}),20))}_onConnected(){this.#f+=1,this.#m||this._getMoreRemoteConversation(!0)}async _getMoreRemoteConversation(e=!1,t=0){const s=0===t?20:200,{code:i,data:o}=await S({count:s,startTime:t});if(e&&this.#C)return;if(i!==c.SUCCESS&&!e)return this.#d?.error(K.S_GET_CONVERSATION_E,`get conversation list failed: code = ${i}, count = ${s}, startTime = ${t}`),void(this.#O=setTimeout((()=>this._getMoreRemoteConversation(e,t)),3e3));const r=o||[];if(0===r.length||e)return void this._onGetRemoteConversationListDone(e);const n=0===t&&!e;n&&(this.list.length=0);const a=this._parseConversationList(r);let h=t;if(h=this._handleNextRequestTimestamp(h,a),e||n){const e=a.filter((e=>!this.list.some((t=>t.key===e.key))));this.list.push(...e)}e||r.length<s?this._onGetRemoteConversationListDone(e):this.#O=setTimeout((()=>this._getMoreRemoteConversation(!1,h)),300)}_handleNextRequestTimestamp(e,t){return this._updatePositionToConversationList(t,!1),t.forEach((t=>{t.updateTime&&(e=0===e?t.updateTime:Math.min(t.updateTime,e))})),e}_updatePositionToConversationList(e,t=!0){const s=[...this.list];e.forEach((e=>{let i=s.findIndex((t=>x(t,e)));if(i>-1){if(!t)return{origin:i,current:i};s.splice(i,1)}const{isTop:o,updateTime:r}=e;let n=s.findIndex((e=>o?!e.isTop||r>e.updateTime:!e.isTop&&r>e.updateTime));-1===n&&(n=s.length),s.splice(n,0,e)})),this.list=s}_onGetRemoteConversationListDone(e){e||(this.#m=!0),this._handleQueue()}_handleQueue(){if(0===this.#I.length)return;if(this.list.length>=20&&!this.#m)return;const e=new Set,t=new Set,s=new Set,i=Number.MAX_SAFE_INTEGER,o=Date.now();if(this._handleQueueNotify((i=>{const{changeType:o,conversation:r}=i;1===o?(s.add(r),e.add(r)):2===o&&(t.add(r),e.add(r))}),e,i,o),t.size&&this._recalculatePosition(t),s.size){const e=[...s].filter((e=>!t.has(e)));e.length&&e.forEach((e=>{this.list.indexOf(e)>-1&&this.list.splice(this.list.indexOf(e),1,e)}))}this._handleQueueDelay()}_recalculatePosition(e){const t=[...e].sort(((e,t)=>e.updateTime-t.updateTime));this._updatePositionToConversationList(t)}_handleQueueNotify(e,t,s,i){if(this.#m)for(;this.#I.length&&Date.now()-i<20&&t.size<s;){const t=this.#I.shift();this.#f<=1&&t.updatedItems?.latestMessage?.val.isOffLineMessage||e(this._handleConversationNtf(t))}else{let o=0;for(;o<this.#I.length&&Date.now()-i<20&&t.size<s;){const t=this.#I[o];if(t.updatedItems?.latestMessage){if(!t.updatedItems.latestMessage.val.isOffLineMessage)break;this.#I.splice(o,1),e(this._handleConversationNtf(t))}else o+=1}}}_handleConversationNtf(t){const{conversation:s,updatedItems:i}=t,o=F(s);let r=this.#M.get(o);return r&&i?this._handleUpdatedItems(r,i,s):!r&&i?.latestMessage?(s.conversationType===e.PRIVATE?r=this._transPriConversation(s):s.conversationType===e.GROUP?r=this._transGroupConversation(s):s.conversationType===e.SYSTEM&&(r=this._transSystemConversation(s)),r&&this.#M.set(r.key,r),{changeType:2,conversation:r}):{changeType:0}}_handleUpdatedItems(e,t,s){let i=0;return t.isTop&&(e.isTop=t.isTop.val,i=Math.max(2,i)),t.notificationLevel&&(e.notificationLevel=t.notificationLevel.val,i=Math.max(1,i)),t.latestMessage?.val&&(this._paddingData(e,s),i=Math.max(2,i)),{changeType:i,conversation:e}}getMoreConversationList(e,t){let s=e?this.list.findIndex((t=>x(t,e))):-1;-1===s?s=0:s+=1;const i=s+(t||20),o=this.list.slice(s,i),r=this.list.length>i||!this.#m;return this.#d?.info(K.K_NOTIFY_GET_CONVERSATIONS_O,`get more conversation, conversation: ${e?.key}, count: ${t}, list: ${JSON.stringify(o.length)}`),{hasMore:r,code:c.SUCCESS,list:o,isFirstScreen:!e}}openConversation(t){if(t){const s=this.#R(t);return this.#p=s,this.#d?.info(K.K_OPEN_CONVERSATION_O,`open conversation, key: ${s.key}`),void(t.conversationType===e.GROUP&&this.#g.groupMembersCache.initGroupMembers(t.targetId))}this.#d?.info(K.K_OPEN_CONVERSATION_O,`close conversation, key: ${this.#p?.key}`),this.#p=null}async removeConversation(e){const t=this.list.findIndex((t=>t.key===e));if(t>-1){const[s]=this.list.splice(t,1);return this.#M.delete(e),void this.#d?.info(K.S_REMOVE_CONVERSATION_O,`remove conversation: ${s}`)}this.#d?.warn(K.S_REMOVE_CONVERSATION_O,`remove conversation failed: ${e} not found`)}_parseConversationList(t){const s=[];return t.forEach((t=>{const{conversationType:i,targetId:o}=t;switch(i){case e.PRIVATE:s.push(this._transPriConversation(t));break;case e.GROUP:s.push(this._transGroupConversation(t));break;case e.SYSTEM:s.push(this._transSystemConversation(t));break;default:this.#d?.warn(K.S_PARSE_CONVERSATION_E,`unknown conversation type: ${i}, targetId: ${o}`)}})),s}_paddingData(e,t){e.unreadCount=t.unreadMessageCount||0,e.isTop=!!t.isTop,e.latestMessage=t.latestMessage,e.updateTime=t.operationTime||t.latestMessage?.sentTime||0,t.notificationLevel&&(e.notificationLevel=t.notificationLevel)}_transPriConversation(e){const t=this.#g?.getUserProfile(e.targetId),s=this.#R(e);return t&&(s.name=t.name,s.nickName=t.remark||"",s.portraitUri=t.portraitUri||""),this._paddingData(s,e),s}_transSystemConversation(e){const t=this.#g?.getSystemProfile(e.targetId),s=this.#R(e);return t&&(s.name=t.name,s.portraitUri=t.portraitUri||""),this._paddingData(s,e),s}_transGroupConversation(e){const t=this.#g?.getGroupProfile(e.targetId),s=this.#R(e);return t&&(s.name=t.name,s.nickName=t.remark||"",s.portraitUri=t.portraitUri||""),this._paddingData(s,e),s}count=0;#R(e){const t=F(e);if(this.#M.has(t))return this.#M.get(t);this.count++;const s={key:t,targetId:e.targetId,conversationType:e.conversationType,channelId:e.channelId||"",name:"",nickName:"",portraitUri:"",draft:"",latestMessage:null,isTop:!1,notificationLevel:l.ALL_MESSAGE,unreadCount:0,updateTime:0,memberCount:0};return this.#M.set(t,s),s}createCachedConversation(e){const t=this.#R(e);if(-1===this.list.findIndex((e=>e.key===t.key))){const e=this.list.findIndex((e=>!e.isTop));e>-1?this.list.splice(e,0,t):this.list.unshift(t)}return t}updateCacheConversation(e,t){if(!this.#C)return;const s=this.list.findIndex((t=>t.key===e));if(s>-1)return Object.keys(t).forEach((e=>{if(e in this.list[s]){const i=e;this.list[s][i]=t[e]}})),this.#M.set(e,this.list[s]),void this.#d?.info(K.S_UPDATE_CONVERSATION_O,`update conversation: ${e}`);this.#d?.warn(K.S_UPDATE_CONVERSATION_O,`update conversation failed: ${e} not found`)}async clearUnreadCount(e){const t=this.list.find((t=>t.key===e));if(t){const e={conversationType:t.conversationType,targetId:t.targetId,channelId:t.channelId};await g(e),await E(e,(new Date).getTime())}}}class se{_kitStore;openedConversation=null;conversations=[];#v=null;#d=null;constructor(e,t){this._kitStore=e,this.#d=t,D(this),this.#y(e)}async#y(e){this.#v=new te(e.appData,this.#d),this.#A(),L((()=>this.#v?.list),(e=>{e&&(this.conversations=e?.slice())}))}#A(){const e=this.#v?.getCachedConversationList()||[];P((()=>{this.conversations=e}))}getConversations(e=null,t=10){return this.#v?.getMoreConversationList(e,t)}openConversation(e){!e&&this.openedConversation&&this._kitStore.messageStore.clearExcessMessage(this.openedConversation?.key),this.#v?.openConversation(e),P((()=>{this.openedConversation=e}))}createCachedConversation(e){return this.#v?.createCachedConversation(e)}removeConversation(e){this.#d?.info(K.K_REMOVE_CONVERSATION_O,`remove conversation: ${e}`),this.#v?.removeConversation(e),P((()=>{this.conversations=this.conversations.filter((t=>t.key!==e)),this.#d?.info(K.K_REMOVE_CONVERSATION_O,`remove conversation: ${e}, current conversations length: ${this.conversations.length}`)}))}updateCacheConversation(e,t){this.#v?.updateCacheConversation(e,t)}getTotalUnreadCount(){return(this.#v?.getCachedConversationList()||[]).reduce(((e,t)=>e+t.unreadCount),0)}async clearUnreadCount(e){await(this.#v?.clearUnreadCount(e))}clearMemoryData(){this.#v?.clearMemoryData()}destroy(){this.#v?.destroy()}}class ie{config;constructor(e){this.config={timeout:5e3,...e}}async getUserProfile(e){return this.withTimeout(this.fetchUser(e))}async getGroupProfile(e){return this.withTimeout(this.fetchGroup(e))}async getSystemProfile(e){return this.withTimeout(this.fetchSystem(e))}async getGroupMembers(e){return this.withTimeout(this.fetchGroupMembers(e))}async withTimeout(e){return Promise.race([e,new Promise(((e,t)=>setTimeout((()=>t("Request timeout")),this.config.timeout)))])}}class oe extends ie{_hooks;constructor(e){super({timeout:8e3}),this._hooks=e}async fetchUser(e){if(!this._hooks.reqUserProfiles)throw new Error("reqUserProfiles hook not implemented");return this._hooks.reqUserProfiles(e)}async fetchGroup(e){if(!this._hooks.reqGroupProfiles)throw new Error("reqGroupProfiles hook not implemented");return this._hooks.reqGroupProfiles(e)}async fetchSystem(e){if(!this._hooks.reqSystemProfiles)throw new Error("reqSystemProfiles hook not implemented");return this._hooks.reqSystemProfiles(e)}fetchGroupMembers(e){if(!this._hooks.reqGroupMembers)throw new Error("reqGroupMembers hook not implemented");return this._hooks.reqGroupMembers(e)}}class re{logger;dataSource;#U=new Q(20);#D=new Map;constructor(e,t){this.logger=e,this.dataSource=t,D(this)}async initGroupMembers(e){if(this.#U.get(e))return;if(this.#D.get(e))return;const t=this.dataSource.getGroupMembers(e);this.#D.set(e,t);try{const s=this.logger.createTraceId();this.logger.info(K.S_GET_GROUP_MEMBERS_HOOK_T,e,s);const i=await t;if(this.#D.delete(e),!i||!Array.isArray(i))return void this.logger.error(K.S_GET_GROUP_MEMBERS_HOOK_E,"result must be a Array",s);const o=i.filter(((e,t)=>!this.#G(e)||(this.logger.error(K.S_GET_GROUP_MEMBERS_HOOK_E,`result[${t}] is invalid, member: ${JSON.stringify(e)}`,s),!1))).map(this.#P);this.logger.info(K.S_GET_GROUP_MEMBERS_HOOK_R,`groupId: ${e}, memberCount: ${i.length}`,s),this.#U.set(e,o,!1,0)}catch(t){this.#D.delete(e),this.logger.error(K.S_GET_GROUP_MEMBERS_HOOK_E,e,t)}}getGroupMembers(e){return this.#U.get(e)||[]}getGroupMember(e,t){const s=this.#U.get(e),i=s?.find((e=>e.user.id===t));return i?{...i}:void 0}getGroupMemberMap(e){const t=this.#U.get(e),s=new Map;return t?.forEach((e=>{s.set(e.user.id,{...e})})),s}#G(e){return"object"!=typeof e||"string"!=typeof e.groupNickname||"object"!=typeof e.user||!e.user.id||"string"!=typeof e.user.id||"string"!=typeof e.user.nickname}#P(e){const{groupNickname:t,user:s}=e;return{user:{...s},groupNickname:t}}clearMemoryData(){this.#U.clear(),this.#D.clear()}}class ne{logger;#L;#w=G.map();#F=G.map();#V=G.map();groupMembersCache;#x={ids:[]};#$={ids:[],timer:void 0};#q={ids:[],timer:void 0};constructor(e,t={}){this.logger=e,this.#L=new oe(t),this.groupMembersCache=new re(e,this.#L),D(this)}getUserProfile(e){return this.#b({id:e,cache:this.#w,queue:this.#x,batchFetch:e=>this.#L.getUserProfile(e)})}getGroupProfile(e){return this.#b({id:e,cache:this.#F,queue:this.#$,batchFetch:e=>this.#L.getGroupProfile(e)})}getSystemProfile(e){return this.#b({id:e,cache:this.#V,queue:this.#q,batchFetch:e=>this.#L.getSystemProfile(e)})}getUserInfo(e){return this.#w.get(e)?.data}getUsersCache(){return this.#w}getGroupsCache(){return this.#F}getSystemsCache(){return this.#V}updateUserProfile(e,t){this.#w.get(e)?this.#k(this.#w,[e],[t]):this.logger.warn(K.K_USER_PROFILE_NOT_FOUND_O,`user id ${e} not found`)}updateGroupProfile(e,t){this.#F.get(e)?this.#k(this.#F,[e],[t]):this.logger.warn(K.K_GROUP_PROFILE_NOT_FOUND_O,`group id ${e} not found`)}updateSystemProfile(e,t){this.#V.get(e)?this.#k(this.#V,[e],[t]):this.logger.warn(K.K_SYSTEM_PROFILE_NOT_FOUND_O,`system id ${e} not found`)}async getProfileSync(e,t){if(t===A.PRIVATE){return(await this.#L.getUserProfile([e]))[0]}if(t===A.GROUP){return(await this.#L.getGroupProfile([e]))[0]}return(await this.#L.getSystemProfile([e]))[0]}#b(e){const t=Date.now(),s=e.cache.get(e.id);if(s)return s.expires>t||s.pending||this.#Q({id:e.id,cache:e.cache,queue:e.queue,batchFetch:e.batchFetch}),s.data;this.#Q({id:e.id,cache:e.cache,queue:e.queue,batchFetch:e.batchFetch})}#Q(e){let t=e.cache.get(e.id);t&&e.cache.set(e.id,{...t,pending:!0}),e.queue.ids=[...new Set([...e.queue.ids,e.id])],e.queue.timer&&clearTimeout(e.queue.timer),e.queue.timer=setTimeout((()=>this.#K(e.cache,e.queue,e.batchFetch)),200)}async#K(e,t,s){const i=[...t.ids];if(t.ids=[],t.timer=void 0,0!==i.length)try{const t=await s(i);P((()=>this.#k(e,i,t)))}catch(t){P((()=>this.#B(e,i)))}}#k(e,t,s){const i=Date.now();s.forEach((t=>{const{id:s}=t;s&&(e.set(s,{data:t,expires:i+6e5,pending:!1}),this.logger.info(K.S_UPDATE_CACHE_O,`update cache ${s} success, data: ${JSON.stringify(t)}`))}))}#B(e,t){t.forEach((t=>{const s=e.get(t);s&&e.set(t,{...s,pending:!1})}))}clearMemoryData(){[this.#x,this.#$,this.#q].forEach((e=>{e.timer&&clearTimeout(e.timer)})),this.#w.clear(),this.#F.clear(),this.#V.clear(),this.groupMembersCache.clearMemoryData()}}class ae{rootStore;_logger;constructor(e,t){this.rootStore=e,this._logger=t}_monitorIds=[];init(){const e=Object.getOwnPropertyNames(Object.getPrototypeOf(this));for(const t of e)t.startsWith("monitor")&&"function"==typeof this[t]&&this._monitorIds.push(this[t]())}destroy(){this._monitorIds.forEach((e=>{p(e)}))}monitorSendMessage(){return m(s,(async(e,t)=>{const{code:s,data:i}=await t;if(i?.isPersited){const t={...i,sentStatus:s===c.SUCCESS?u.SENT:u.FAILED,...e[2]};this.rootStore.messageStore?.updateCatchedMessage(t),this.rootStore.conversationStore?.updateCacheConversation(F(e[0]),{latestMessage:t})}}),(e=>{const[,,t]=e;if(t){const{messageId:s}=t,i=t?.onSendBefore;t.onSendBefore=t=>{this._logger.info(K.S_ON_SEND_BEFORE_S,`${s}, isPersited: ${t.isPersited}`),t.isPersited&&(s?this.rootStore.messageStore?.updateCatchedMessage(t):this.rootStore.messageStore?.insertMessage(t),this.rootStore.conversationStore?.updateCacheConversation(F(e[0]),{latestMessage:t,draft:""})),i?.(t)}}return e}))}monitorClearMessagesUnreadStatus(){return m(g,(async(e,t)=>{this._logger.info(K.S_CLEAR_MESSAGES_UNREAD_STATUS_T,JSON.stringify(e));const s=await t;this._logger.info(K.S_CLEAR_MESSAGES_UNREAD_STATUS_R,JSON.stringify(s));const i=e[0],o=F(i);this.rootStore.conversationStore?.updateCacheConversation(o,{unreadCount:0})}))}monitorRemoveConversation(){return m(O,(async(e,t)=>{this._logger.info(K.S_REMOVE_CONVERSATION_T,JSON.stringify(e));const s=await t;this._logger.info(K.S_REMOVE_CONVERSATION_R,JSON.stringify(s));const i=e[0],o=F(i);this.rootStore.conversationStore?.removeConversation(o)}))}monitorSetConversationNotificationLevel(){return m(T,(async(e,t)=>{this._logger.info(K.S_SET_CONVERSATION_NOTIFICATION_LEVEL_T,JSON.stringify(e));const s=await t;this._logger.info(K.S_SET_CONVERSATION_NOTIFICATION_LEVEL_R,JSON.stringify(s));const i=e[0],o=e[1],r=F(i);this.rootStore.conversationStore?.updateCacheConversation(r,{notificationLevel:o})}))}monitorSetConversationToTop(){return m(C,(async(e,t)=>{this._logger.info(K.S_SET_CONVERSATION_TO_TOP_T,JSON.stringify(e));const s=await t;this._logger.info(K.S_SET_CONVERSATION_TO_TOP_R,JSON.stringify(s));const i=e[0],o=e[1],r=F(i);this.rootStore.conversationStore?.updateCacheConversation(r,{isTop:o})}))}monitorRecallMessage(){return m(_,(async(e,t)=>{const{code:s,data:i}=await t;if(s===c.SUCCESS&&i){const[t,s]=e;this._logger.info(K.S_RECALL_MESSAGE_T,JSON.stringify(e)),this.rootStore.messageStore?.removeCatchedMessage({...t,messageUId:s.messageUId,channelId:t.channelId||""}),this._logger.info(K.S_RECALL_MESSAGE_R,JSON.stringify(i)),this.rootStore.messageStore?.insertMessage(i,!1,!0)}}))}monitorDisconnect(){return m(f,(async(e,t)=>{this.rootStore.conversationStore?.clearMemoryData(),this.rootStore.messageStore?.clearMemoryData()}))}}const he="1.0.0";class ce{_context;_logger;_option;messageStore;conversationStore;appData;currentUserId="";connectStatus=G.box(U.DISCONNECTED);constructor(e,t,s){this._context=e,this._logger=t,this._option=s,this.appData=new ne(this._logger,this._option.hooks),n(a.CONNECTED,this._onConnected),n(a.DISCONNECT,this._onDisconnected),n(a.SUSPEND,this._onSuspend),n(a.CONNECTING,this._onConnecting),new ae(this,this._logger).init(),this.messageStore=new ee(this._logger,this,this._context),this.conversationStore=new se(this,this._logger),M("imkit-store",he)}_onConnected=()=>{this.currentUserId=this._context.getCurrentId(),this.appData.getUserProfile(this.currentUserId),P((()=>{this.connectStatus.set(U.CONNECTED)}))};_onDisconnected=()=>{P((()=>{this.connectStatus.set(U.DISCONNECTED)}))};_onSuspend=()=>{P((()=>{this.connectStatus.set(U.SUSPENDED)}))};_onConnecting=()=>{P((()=>{this.connectStatus.set(U.CONNECTING)}))};destroy(){d(a.CONNECTED,this._onConnected),d(a.DISCONNECT,this._onDisconnected),d(a.SUSPEND,this._onSuspend),d(a.CONNECTING,this._onConnecting),this.clearMemoryData()}clearMemoryData(){this.conversationStore.clearMemoryData(),this.messageStore.clearMemoryData(),this.appData.clearMemoryData()}}const _e={tag:"UIKitStore",verify:()=>!0,setup(e,t,s){const i=e.createLogger("UIKitStore","IM");return s.logLevel&&i.setOutputLevel(s.logLevel),i.warn(K.K_INIT_O,`Commit: d825b5aa3c607e2050a1c1fbd7443da2e1d79dbe, Version: ${he}`),new ce(e,i,s)}},ue=e=>I(_e,e);export{j as AKitUploadRequest,ne as AppDataModule,re as GroupMembersCache,se as RCKitConversationStore,ee as RCKitMessageStore,ce as RCKitStore,ue as RCKitStoreInstaller,F as trans2ConversationKey};