@anyaipartner/im-sdk 2.0.1

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/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Comind Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,73 @@
1
+ # @comind/im-sdk
2
+
3
+ > Official IM SDK for Comind - A powerful instant messaging solution for web applications
4
+
5
+ [![npm version](https://img.shields.io/npm/v/@comind/im-sdk.svg)](https://www.npmjs.com/package/@comind/im-sdk)
6
+ [![license](https://img.shields.io/npm/l/@comind/im-sdk.svg)](https://github.com/comind/comind-im-sdk/blob/main/LICENSE)
7
+
8
+ ## ✨ Features
9
+
10
+ - 🚀 **Full TypeScript Support** - Built with TypeScript for better type safety and developer experience
11
+ - 💬 **Real-time Messaging** - WebSocket-based real-time communication with auto-reconnection
12
+ - 👥 **Group Chat** - Full support for group conversations and management
13
+ - 📁 **File Transfer** - Built-in file upload and download capabilities
14
+ - 🔔 **Event-Driven Architecture** - Easy to integrate with flexible event handling
15
+ - 💾 **Local Storage** - IndexedDB-based offline message caching
16
+ - 🔄 **Message Status Tracking** - Track message delivery and read status
17
+ - 🎯 **Simple API** - Clean and intuitive API design
18
+
19
+ ## 📦 Installation
20
+
21
+ ```bash
22
+ npm install @comind/im-sdk
23
+ ```
24
+
25
+ ## 🚀 Quick Start
26
+
27
+ ```typescript
28
+ import { createIMSDK, IMEventType, ConversationType } from '@comind/im-sdk'
29
+
30
+ // Create SDK instance
31
+ const sdk = createIMSDK({
32
+ appId: 'your-app-id',
33
+ appSecret: 'your-app-secret',
34
+ apiBaseUrl: 'https://api.example.com',
35
+ wsUrl: 'wss://ws.example.com',
36
+ })
37
+
38
+ // Listen to events
39
+ sdk.on(IMEventType.MESSAGE_RECEIVED, (message) => {
40
+ console.log('New message:', message)
41
+ })
42
+
43
+ // Login
44
+ await sdk.login({
45
+ userId: 'user123',
46
+ userName: 'John Doe',
47
+ })
48
+
49
+ // Send a message
50
+ const message = sdk.message.createTextMessage({
51
+ to: 'user456',
52
+ conversationType: ConversationType.SINGLE,
53
+ payload: { text: 'Hello!' },
54
+ })
55
+ await sdk.message.sendMessage(message)
56
+ ```
57
+
58
+ ## 📖 Documentation
59
+
60
+ For detailed documentation, please visit [GitHub Repository](https://github.com/comind/comind-im-sdk)
61
+
62
+ ## 🌐 Browser Support
63
+
64
+ | Browser | Version |
65
+ |---------|---------|
66
+ | Chrome | >= 90 |
67
+ | Firefox | >= 88 |
68
+ | Safari | >= 14 |
69
+ | Edge | >= 90 |
70
+
71
+ ## 📄 License
72
+
73
+ [MIT](LICENSE)
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Comind Web IM SDK
3
+ *
4
+ * 参考腾讯云IM SDK设计的Web端即时通讯SDK
5
+ *
6
+ * @example
7
+ * ```typescript
8
+ * import { createIMSDK, IMEventType } from '@comind/web-im-sdk';
9
+ *
10
+ * // 创建SDK实例
11
+ * const sdk = createIMSDK({
12
+ * appId: 'your-app-id',
13
+ * appSecret: 'your-app-secret',
14
+ * apiBaseUrl: 'https://api.example.com',
15
+ * wsUrl: 'wss://ws.example.com',
16
+ * logLevel: 'INFO',
17
+ * });
18
+ *
19
+ * // 监听事件
20
+ * sdk.on(IMEventType.MESSAGE_RECEIVED, (message) => {
21
+ * console.log('收到新消息:', message);
22
+ * });
23
+ *
24
+ * // 登录
25
+ * await sdk.login({
26
+ * userId: 'user123',
27
+ * userName: 'John Doe',
28
+ * });
29
+ *
30
+ * // 创建并发送消息
31
+ * const message = sdk.message.createTextMessage({
32
+ * to: 'user456',
33
+ * conversationType: ConversationType.SINGLE,
34
+ * payload: { text: 'Hello!' },
35
+ * });
36
+ * await sdk.message.sendMessage(message);
37
+ * ```
38
+ */
39
+ import { IMSDK, createIMSDK } from './IMSDK';
40
+ export { IMSDK, createIMSDK };
41
+ export type { IMSDKConfig, LoginParams, LoginResult, RegisterParams, LoginWithPasswordParams } from './types';
42
+ export { LogLevel } from './types';
43
+ export type { Message, SendMessageOptions, MessageReceipt, SendAudioMessageParams, SendVideoMessageParams, } from './types';
44
+ export { MessageType, MessageStatus, ConversationType } from './types';
45
+ export type { Conversation, ConversationListResult, GetConversationListParams, } from './types';
46
+ export type { GroupInfo, GroupMember, GroupMemberListResult, CreateGroupParams, UpdateGroupInfoParams, GetGroupMembersParams, } from './types';
47
+ export type { UserInfo, UpdateUserInfoParams } from './types';
48
+ export type { FriendInfo, FriendRequest, AddFriendParams } from './types';
49
+ export { IMEventType, SocketEventType } from './types';
50
+ export { IMError, IMErrorCode } from './types';
51
+ export type { MessageManager } from './managers';
52
+ export type { ConversationManager } from './managers';
53
+ export type { GroupManager } from './managers';
54
+ export type { UserManager } from './managers';
55
+ export type { FriendManager } from './managers';
56
+ export type { FriendApplication } from './managers';
57
+ export { Logger } from './core';
58
+ export { EventBus } from './core';
59
+ export { TraceLogService } from './services';
60
+ export type { TraceLogEntry } from './services/TraceLogService';
61
+ export { formatRelativeTime, formatDate, parseDate } from './utils';
62
+ export default IMSDK;
@@ -0,0 +1 @@
1
+ import e from"axios";import t from"socket.io-client";var s,r,a,i,n,o,c;!function(e){e[e.VERBOSE=0]="VERBOSE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.NONE=5]="NONE"}(s||(s={})),function(e){e[e.SINGLE=1]="SINGLE",e[e.GROUP=2]="GROUP"}(r||(r={})),function(e){e[e.TEXT=0]="TEXT",e[e.FILE=1]="FILE",e[e.IMAGE=2]="IMAGE",e[e.VOICE=4]="VOICE",e[e.AUDIO=5]="AUDIO",e[e.VIDEO=6]="VIDEO",e[e.AT_TEXT=8]="AT_TEXT",e[e.CUSTOM=9]="CUSTOM"}(a||(a={})),function(e){e[e.SENDING=0]="SENDING",e[e.SUCCESS=1]="SUCCESS",e[e.FAILED=2]="FAILED"}(i||(i={})),function(e){e[e.SUCCESS=0]="SUCCESS",e[e.UNKNOWN_ERROR=1e3]="UNKNOWN_ERROR",e[e.NETWORK_ERROR=1001]="NETWORK_ERROR",e[e.INVALID_PARAMETER=1002]="INVALID_PARAMETER",e[e.NOT_INITIALIZED=1003]="NOT_INITIALIZED",e[e.NOT_LOGGED_IN=1004]="NOT_LOGGED_IN",e[e.ALREADY_LOGGED_IN=1005]="ALREADY_LOGGED_IN",e[e.LOGIN_FAILED=2e3]="LOGIN_FAILED",e[e.TOKEN_EXPIRED=2001]="TOKEN_EXPIRED",e[e.TOKEN_INVALID=2002]="TOKEN_INVALID",e[e.USER_NOT_EXIST=2003]="USER_NOT_EXIST",e[e.MESSAGE_SEND_FAILED=3e3]="MESSAGE_SEND_FAILED",e[e.MESSAGE_REVOKE_TIMEOUT=3001]="MESSAGE_REVOKE_TIMEOUT",e[e.MESSAGE_NOT_FOUND=3002]="MESSAGE_NOT_FOUND",e[e.GROUP_NOT_EXIST=4e3]="GROUP_NOT_EXIST",e[e.GROUP_MEMBER_LIMIT=4001]="GROUP_MEMBER_LIMIT",e[e.NOT_GROUP_MEMBER=4002]="NOT_GROUP_MEMBER",e[e.NO_PERMISSION=4003]="NO_PERMISSION",e[e.GROUP_DISMISSED=4004]="GROUP_DISMISSED",e[e.FRIEND_NOT_EXIST=5e3]="FRIEND_NOT_EXIST",e[e.FRIEND_ALREADY_EXIST=5001]="FRIEND_ALREADY_EXIST",e[e.FILE_UPLOAD_FAILED=6e3]="FILE_UPLOAD_FAILED",e[e.FILE_DOWNLOAD_FAILED=6001]="FILE_DOWNLOAD_FAILED",e[e.FILE_SIZE_LIMIT=6002]="FILE_SIZE_LIMIT",e[e.FILE_TYPE_NOT_ALLOWED=6003]="FILE_TYPE_NOT_ALLOWED"}(n||(n={}));class g extends Error{constructor(e,t,s){super(t),this.name="IMError",this.code="string"==typeof e?n.UNKNOWN_ERROR:e,this.detail=s,Object.setPrototypeOf(this,g.prototype)}}!function(e){e.CONNECT_SUCCESS="CONNECT_SUCCESS",e.DISCONNECT="DISCONNECT",e.RECONNECTING="RECONNECTING",e.RECONNECTED="RECONNECTED",e.LOGIN_SUCCESS="LOGIN_SUCCESS",e.LOGIN_FAILED="LOGIN_FAILED",e.LOGOUT="LOGOUT",e.KICKED_OFFLINE="KICKED_OFFLINE",e.MESSAGE_RECEIVED="MESSAGE_RECEIVED",e.MESSAGE_SENT="MESSAGE_SENT",e.MESSAGE_REVOKED="MESSAGE_REVOKED",e.MESSAGE_READ="MESSAGE_READ",e.CONVERSATION_UPDATED="CONVERSATION_UPDATED",e.GROUP_NOTIFICATION="GROUP_NOTIFICATION",e.FRIEND_NOTIFICATION="FRIEND_NOTIFICATION",e.FRIEND_ADDED="FRIEND_ADDED",e.FRIEND_DELETED="FRIEND_DELETED",e.FRIEND_APPLICATION_RECEIVED="FRIEND_APPLICATION_RECEIVED",e.ERROR="ERROR"}(o||(o={})),function(e){e.CONNECT="connect",e.DISCONNECT="disconnect",e.CONNECT_ERROR="connect_error",e.RECONNECT_ATTEMPT="reconnect_attempt",e.RECONNECT="reconnect",e.RECONNECT_FAILED="reconnect_failed",e.ERROR="error",e.MESSAGE="message",e.GROUP_NOTIFICATION="group_notification",e.FRIEND_NOTIFICATION="friend_notification"}(c||(c={}));class d{constructor(){this.level=s.INFO,this.enabled=!0}static getInstance(){return d.instance||(d.instance=new d),d.instance}setLevel(e){this.level="string"==typeof e?s[e]||s.INFO:e}setEnabled(e){this.enabled=e}verbose(...e){this.log(s.VERBOSE,...e)}debug(...e){this.log(s.DEBUG,...e)}info(...e){this.log(s.INFO,...e)}warn(...e){this.log(s.WARN,...e)}error(...e){this.log(s.ERROR,...e)}log(e,...t){if(!this.enabled||e<this.level)return;(new Date).toISOString(),s[e];switch(e){case s.ERROR:case s.WARN:}}}d.instance=null;class l{constructor(e){this.config=null,e&&(this.config=e)}setConfig(e){this.config=e}getConfig(){if(!this.config)throw new Error("SDK not initialized");return this.config}getAppId(){return this.getConfig().appId}getAppSecret(){return this.getConfig().appSecret}getApiBaseUrl(){return this.getConfig().apiBaseUrl}getWsUrl(){return this.getConfig().wsUrl}getWsPath(){return this.getConfig().wsPath||"/socket.io"}}class u{constructor(){this.isLoggedInFlag=!1,this.userId=null,this.token=null}setLoginStatus(e){this.isLoggedInFlag=e}isLoggedIn(){return this.isLoggedInFlag}setUserId(e){this.userId=e;try{localStorage.setItem("im_userId",e)}catch(e){}}getUserId(){return this.userId}setToken(e){this.token=e;try{localStorage.setItem("im_token",e)}catch(e){}}getToken(){return this.token}loadToken(){try{const e=localStorage.getItem("im_token");return e&&(this.token=e),e}catch(e){return null}}loadUserId(){try{const e=localStorage.getItem("im_userId");return e&&(this.userId=e),e}catch(e){return null}}clear(){this.isLoggedInFlag=!1,this.userId=null,this.token=null;try{localStorage.removeItem("im_token"),localStorage.removeItem("im_userId")}catch(e){}}}function h(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var p={exports:{}};!function(e){var t=Object.prototype.hasOwnProperty,s="~";function r(){}function a(e,t,s){this.fn=e,this.context=t,this.once=s||!1}function i(e,t,r,i,n){if("function"!=typeof r)throw new TypeError("The listener must be a function");var o=new a(r,i||e,n),c=s?s+t:t;return e._events[c]?e._events[c].fn?e._events[c]=[e._events[c],o]:e._events[c].push(o):(e._events[c]=o,e._eventsCount++),e}function n(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function o(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(s=!1)),o.prototype.eventNames=function(){var e,r,a=[];if(0===this._eventsCount)return a;for(r in e=this._events)t.call(e,r)&&a.push(s?r.slice(1):r);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(e)):a},o.prototype.listeners=function(e){var t=s?s+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var a=0,i=r.length,n=new Array(i);a<i;a++)n[a]=r[a].fn;return n},o.prototype.listenerCount=function(e){var t=s?s+e:e,r=this._events[t];return r?r.fn?1:r.length:0},o.prototype.emit=function(e,t,r,a,i,n){var o=s?s+e:e;if(!this._events[o])return!1;var c,g,d=this._events[o],l=arguments.length;if(d.fn){switch(d.once&&this.removeListener(e,d.fn,void 0,!0),l){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,t),!0;case 3:return d.fn.call(d.context,t,r),!0;case 4:return d.fn.call(d.context,t,r,a),!0;case 5:return d.fn.call(d.context,t,r,a,i),!0;case 6:return d.fn.call(d.context,t,r,a,i,n),!0}for(g=1,c=new Array(l-1);g<l;g++)c[g-1]=arguments[g];d.fn.apply(d.context,c)}else{var u,h=d.length;for(g=0;g<h;g++)switch(d[g].once&&this.removeListener(e,d[g].fn,void 0,!0),l){case 1:d[g].fn.call(d[g].context);break;case 2:d[g].fn.call(d[g].context,t);break;case 3:d[g].fn.call(d[g].context,t,r);break;case 4:d[g].fn.call(d[g].context,t,r,a);break;default:if(!c)for(u=1,c=new Array(l-1);u<l;u++)c[u-1]=arguments[u];d[g].fn.apply(d[g].context,c)}}return!0},o.prototype.on=function(e,t,s){return i(this,e,t,s,!1)},o.prototype.once=function(e,t,s){return i(this,e,t,s,!0)},o.prototype.removeListener=function(e,t,r,a){var i=s?s+e:e;if(!this._events[i])return this;if(!t)return n(this,i),this;var o=this._events[i];if(o.fn)o.fn!==t||a&&!o.once||r&&o.context!==r||n(this,i);else{for(var c=0,g=[],d=o.length;c<d;c++)(o[c].fn!==t||a&&!o[c].once||r&&o[c].context!==r)&&g.push(o[c]);g.length?this._events[i]=1===g.length?g[0]:g:n(this,i)}return this},o.prototype.removeAllListeners=function(e){var t;return e?(t=s?s+e:e,this._events[t]&&n(this,t)):(this._events=new r,this._eventsCount=0),this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prefixed=s,o.EventEmitter=o,e.exports=o}(p);var m,I,v,f=h(p.exports);class S extends f{constructor(){super()}static getInstance(){return S.instance||(S.instance=new S),S.instance}emitEvent(e,t){this.emit(e,t)}onEvent(e,t){this.on(e,t)}offEvent(e,t){t?this.off(e,t):this.removeAllListeners(e)}onceEvent(e,t){this.once(e,t)}clearAll(){this.removeAllListeners()}}function E(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}S.instance=null,function(e){e[e.CONNECT=1]="CONNECT",e[e.CONNECT_ACK=2]="CONNECT_ACK",e[e.PING=10]="PING",e[e.PONG=11]="PONG",e[e.GROUP_NOTIFICATION=20]="GROUP_NOTIFICATION",e[e.FRIEND_NOTIFICATION=30]="FRIEND_NOTIFICATION",e[e.CHAT_MESSAGE=51]="CHAT_MESSAGE",e[e.RECEIPT_MESSAGE=52]="RECEIPT_MESSAGE",e[e.KICK_OFF=99]="KICK_OFF"}(m||(m={})),function(e){e[e.SINGLE=1]="SINGLE",e[e.GROUP=2]="GROUP"}(I||(I={})),function(e){e[e.DESC=1]="DESC",e[e.ASC=2]="ASC"}(v||(v={}));const M=104857600;var y;!function(e){e[e.UNKNOW_REQ=0]="UNKNOW_REQ",e[e.PING=1]="PING",e[e.PONG=2]="PONG",e[e.CONNECT=3]="CONNECT",e[e.CONNECT_ACK=4]="CONNECT_ACK",e[e.DISCONNECT=5]="DISCONNECT",e[e.Reserved=6]="Reserved",e[e.MESSAGE=7]="MESSAGE",e[e.MESSAGE_ACK=8]="MESSAGE_ACK"}(y||(y={}));let N=Math.floor(1e4*Math.random());function T(e){const t=function(e){const t=null!=e.ackId?6:2,s=new ArrayBuffer(t),r=new DataView(s);return r.setUint8(0,e.version),r.setUint8(1,e.type),null!=e.ackId&&r.setUint32(2,e.ackId),r}(e.header),s=function(e){if(null==e)return null;const t=new ArrayBuffer(e.byteLength),s=new DataView(t);for(let t=0;t<e.byteLength;t++)s.setUint8(t,e[t]);return s}(e.payload||null);let r=t.byteLength;null!=s&&(r+=s.byteLength);const a=new ArrayBuffer(r),i=new DataView(a);for(let e=0;e<t.byteLength;e++)i.setUint8(e,t.getUint8(e));if(null!=s)for(let e=0;e<s.byteLength;e++)i.setUint8(e+t.byteLength,s.getUint8(e));return a}function w(e){const t=[];for(;e>127;)t.push(127&e|128),e>>>=7;return t.push(127&e),t}function D(e,t){return w(e<<3|t)}function O(e){const t=function(e){const t=[];if(t.push(...D(1,0)),t.push(...w(e.cmd)),e.token.length>0){const s=(new TextEncoder).encode(e.token);t.push(...D(2,2)),t.push(...w(s.length)),t.push(...Array.from(s))}return t.push(...D(3,0)),t.push(...w(e.clientType)),new Uint8Array(t)}({cmd:3,token:e,clientType:1});return T({header:{version:2,type:y.CONNECT},payload:t})}function C(e){const t=new DataView(new Uint8Array(e).buffer),s=t.getUint8(0);let r=null;if(0!==s&&t.byteLength>1){r=function(e){if("string"==typeof e)return e;let t="";for(let s=0;s<e.length;s++){const r=e[s].toString(2),a=r.match(/^1+?(?=0)/);if(a&&8===r.length){const r=a[0].length;let i=e[s].toString(2).slice(7-r);for(let t=1;t<r;t++)i+=e[t+s].toString(2).slice(2);t+=String.fromCharCode(parseInt(i,2)),s+=r-1}else t+=String.fromCharCode(e[s])}return t}(e.slice(1))}return{status:s,errMsg:r}}function _(e){const t=Array.from(new Uint8Array(e)),s=function(e){const t=e.getUint8(0),s=e.getUint8(1);let r;return s!==y.MESSAGE&&s!==y.MESSAGE_ACK||(r=e.getUint32(2)),{version:t,type:s,ackId:r}}(new DataView(new Uint8Array(t).buffer));let r=2;s.type!==y.MESSAGE&&s.type!==y.MESSAGE_ACK||(r+=4);const a=t.slice(r);let i=null;return s.type===y.CONNECT_ACK?i=C(a):s.type===y.MESSAGE&&(i=function(e){let t=0;if(e.length>=2&&8===e[0]){let s,r=1,a=0;do{s=e[r++],t|=(127&s)<<a,a+=7}while(s>=128&&r<e.length)}return{cmd:t,bytes:e}}(a)),{header:s,payload:i}}function R(e){const t=[];if(0!==e.cmd&&(t.push(...D(1,0)),t.push(...w(e.cmd))),e.id.length>0){const s=(new TextEncoder).encode(e.id);t.push(...D(2,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(0!==e.createTimestamp&&(t.push(...D(3,0)),t.push(...function(e){const t=[];for(;e>127;)t.push(127&e|128),e=Math.floor(e/128);return t.push(127&e),t}(e.createTimestamp))),0!==e.type&&(t.push(...D(4,0)),t.push(...w(e.type))),e.data&&e.data.length>0){const s=(new TextEncoder).encode(e.data);t.push(...D(6,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(e.from.length>0){const s=(new TextEncoder).encode(e.from);t.push(...D(7,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(e.to.length>0){const s=(new TextEncoder).encode(e.to);t.push(...D(8,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(0!==e.chatType&&(t.push(...D(11,0)),t.push(...w(e.chatType))),0!==e.msgType&&(t.push(...D(12,0)),t.push(...w(e.msgType))),e.content.length>0){const s=(new TextEncoder).encode(e.content);t.push(...D(13,2)),t.push(...w(s.length)),t.push(...Array.from(s))}return new Uint8Array(t)}function A(e,t){let s,r=0,a=0;do{s=e[t++],r|=(127&s)<<a,a+=7}while(s>=128&&t<e.length);return{value:r,newOffset:t}}const U="imchat";function b(e){if(!e)return"";let t;if(e instanceof Date)t=e;else if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);if(isNaN(t.getTime()))return String(e);const s=new Date,r=s.getTime()-t.getTime();return r<0||r>31536e6?L(t,"YYYY/MM/DD"):r<6e4?"刚刚":r<36e5?`${Math.floor(r/6e4)}分钟前`:r<864e5?t.getDate()===s.getDate()&&t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear()?`今天 ${L(t,"HH:mm")}`:`昨天 ${L(t,"HH:mm")}`:r<6048e5?`${Math.floor(r/864e5)}天前`:t.getFullYear()===s.getFullYear()?L(t,"MM/DD"):L(t,"YYYY/MM/DD")}function L(e,t="YYYY-MM-DD HH:mm:ss"){if(!e)return"";let s;if(e instanceof Date)s=e;else if("string"==typeof e){const t=e.replace(/-/g,"/").replace(" ","T")+"Z";s=new Date(t),isNaN(s.getTime())&&(s=new Date(e.replace(/-/g,"/")))}else s=new Date(e);if(isNaN(s.getTime()))return String(e);const r=s.getFullYear(),a=s.getMonth()+1,i=s.getDate(),n=s.getHours(),o=s.getMinutes(),c=s.getSeconds();return t.replace("YYYY",String(r)).replace("MM",String(a).padStart(2,"0")).replace("DD",String(i).padStart(2,"0")).replace("HH",String(n).padStart(2,"0")).replace("mm",String(o).padStart(2,"0")).replace("ss",String(c).padStart(2,"0"))}function k(e){if(!e)return null;let t;if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);return isNaN(t.getTime())?null:t}class G{static createTextMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:r.text,msgType:a.TEXT,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{msgdata:"txt"}}}static createImageMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type}),msgType:a.IMAGE,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,msgdata:"img"}}}static createFileMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type}),msgType:a.FILE,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,msgdata:"file"}}}static createAudioMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type,duration:r.duration||0}),msgType:a.AUDIO,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,duration:r.duration||0,msgdata:"audio"}}}static createVideoMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type,duration:r.duration||0,width:r.width||0,height:r.height||0,thumbnailUrl:r.thumbnailUrl||""}),msgType:a.VIDEO,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,duration:r.duration||0,width:r.width||0,height:r.height||0,thumbnailUrl:r.thumbnailUrl||"",msgdata:"video"}}}static createCustomMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:r.description||"[自定义消息]",msgType:a.CUSTOM,status:i.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{data:r.data,extension:r.extension}}}static fromServerData(e){let t;return e.readRecords&&Array.isArray(e.readRecords)&&(t=e.readRecords.filter(e=>e.readFlag).map(e=>e.userId)),{msgId:e.id||e.msgId,conversationId:e.to||e.groupId,conversationType:1===e.chatType?r.SINGLE:r.GROUP,from:e.from,fromUserName:e.fromUserName,fromUserImg:e.fromUserImg,content:e.content,msgType:Number(e.msgType),status:i.SUCCESS,seqId:e.seqId||0,timestamp:e.createTimestamp||e.createTime||Date.now(),isRead:e.isRead||!1,isRevoked:e.isRevoked||1===e.isUndo||!1,readMembers:t,extra:e.data?JSON.parse(e.data):void 0}}}class F{constructor(t,s){this.token=null,this.config=t,this.logger=s,this.axiosInstance=e.create({baseURL:`${t.apiBaseUrl}/comind-im-api`,timeout:3e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),this.logger.debug("[APIService] Request:",e.method,e.url),e),e=>(this.logger.error("[APIService] Request error:",e),Promise.reject(e))),this.axiosInstance.interceptors.response.use(e=>{this.logger.debug("[APIService] Response:",e.config.url,e.status,e.data);const t=e.data;if(!0===t.success)return t.jsonData;throw new g(t.errorCode||n.UNKNOWN_ERROR,t.errorMessage||t.errorMsg||"Unknown error")},e=>{var t,s,r;throw this.logger.error("[APIService] Response error:",e),e.response?new g((null===(t=e.response.data)||void 0===t?void 0:t.errorCode)||n.UNKNOWN_ERROR,(null===(s=e.response.data)||void 0===s?void 0:s.errorMessage)||(null===(r=e.response.data)||void 0===r?void 0:r.errorMsg)||e.message):e.request?new g(n.NETWORK_ERROR,"Network error, please check your connection"):new g(n.UNKNOWN_ERROR,e.message)})}setToken(e){this.token=e}getCurrentToken(){return this.token}getConfig(){return this.config}async getToken(e){return this.axiosInstance.post("/v1/token/get",{appId:e.appId,appSecret:e.appSecret,userId:e.userId,userName:e.userName,userImg:e.userAvatar})}async registerWithPassword(e){return this.axiosInstance.post("/v1/token/registerWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password,userImg:e.userAvatar,companyName:e.companyName})}async loginWithPassword(e){return this.axiosInstance.post("/v1/token/loginWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password})}async getUserInfo(e){return this.axiosInstance.post("/v1/user/getUserInfo",e)}async updateUserInfo(e){return this.axiosInstance.post("/v1/user/updateName",e)}async changePassword(e){return this.axiosInstance.post("/v1/user/changePassword",e)}async getChatList(e){return this.axiosInstance.post("/v2/group/list",e||{})}async getOfflineMsg(e,t=10){return this.axiosInstance.post("/v1/msg/getOfflineMsg",{groupIds:e,msgNumberNeedReturned:t})}async getUnreadMsgList(){return this.axiosInstance.post("/v1/msg/unreadMsg")}async searchRoamingMsg(e){var t,s;const r={...e,detailType:null!==(t=e.detailType)&&void 0!==t?t:3,syncType:null!==(s=e.syncType)&&void 0!==s?s:"BACK"};return this.axiosInstance.post("/v1/msg/searchRoamingMsg",r)}async saveLastReadMsgSeqIdOfGroup(e){return this.axiosInstance.post("/v1/msg/saveLastReadMsgSeqIdOfGroup",{groupId:e.groupId,seqId:e.seqId})}async createGroup(e){return this.axiosInstance.post("/v1/group/create",e)}async getGroupBaseInfo(e){return this.axiosInstance.post("/v2/group/getBaseInfo",e)}async updateGroupBaseInfo(e){return this.axiosInstance.post("/v1/group/updateBaseInfo",e)}async getGroupMemberList(e){return this.axiosInstance.post("/v1/groupMember/list",e)}async addGroupMember(e){return this.axiosInstance.post("/v1/groupMember/add",e)}async removeGroupMember(e){return this.axiosInstance.post("/v1/groupMember/remove",e)}async quitGroup(e){return this.axiosInstance.post("/v1/group/quit",e)}async dismissGroup(e){return this.axiosInstance.post("/v2/group/dismiss",e)}async onTopGroup(e){return this.axiosInstance.post("/v1/group/onTop",e)}async hideGroup(e){return this.axiosInstance.post("/v1/group/hide",e)}async getFriendList(e){return this.axiosInstance.post("/v1/friend/list",e||{})}async addFriend(e){return this.axiosInstance.post("/v1/friendRequest/add",e)}async getFriendRequestList(e){return this.axiosInstance.post("/v1/friendRequest/list",e||{})}async agreeFriendRequest(e){return this.axiosInstance.post("/v1/friendRequest/agree",e)}async deleteFriend(e){return this.axiosInstance.post("/v1/friend/delete",e)}async getUserPrivacy(e){return this.axiosInstance.post("/v1/user/getUserPrivacy",e)}async updatePrivacy(e){return this.axiosInstance.post("/v1/user/updatePrivacy",e)}async getBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/list",e||{})}async addToBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/add",e)}async removeFromBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/delete",e)}}class P{constructor(e){this.db=null,this.dbName="comind-im-sdk",this.version=1,this.logger=e}async init(){return new Promise((e,t)=>{const s=indexedDB.open(this.dbName,this.version);s.onerror=()=>{this.logger.error("[StorageService] Failed to open IndexedDB:",s.error),t(s.error)},s.onsuccess=()=>{this.db=s.result,this.logger.info("[StorageService] IndexedDB initialized successfully"),e()},s.onupgradeneeded=e=>{const t=e.target.result;if(!t.objectStoreNames.contains("messages")){const e=t.createObjectStore("messages",{keyPath:"msgId"});e.createIndex("conversationId","conversationId",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),e.createIndex("conv_time",["conversationId","timestamp"],{unique:!1})}if(!t.objectStoreNames.contains("conversations")){t.createObjectStore("conversations",{keyPath:"conversationId"}).createIndex("lastMessageTime","lastMessageTime",{unique:!1})}}})}async saveMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message saved:",e.msgId),this.cleanOldMessages(e.conversationId).catch(e=>{this.logger.warn("[StorageService] Failed to clean old messages:",e)}),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async saveMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite"),a=r.objectStore("messages");let i=e.length;0!==i?(e.forEach(e=>{const t=a.get(e.msgId);t.onsuccess=()=>{const s=t.result;if(s&&(s.isRevoked&&(e.isRevoked=!0),s.readMembers||e.readMembers)){const t=s.readMembers||[],r=e.readMembers||[],a=[...new Set([...t,...r])];e.readMembers=a.length>0?a:void 0}a.put(e),i--},t.onerror=()=>{a.put(e),i--}}),r.oncomplete=()=>{this.logger.debug("[StorageService] Messages saved:",e.length),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save messages:",r.error),s(r.error)}):t()});this.logger.warn("[StorageService] Database not initialized")}async getMessages(e,t=20,s=0){return this.db?new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readonly").objectStore("messages").index("conv_time"),n=IDBKeyRange.bound([e,0],[e,Date.now()]),o=i.openCursor(n,"prev"),c=[];let g=0;o.onsuccess=e=>{const a=e.target.result;a&&g<s+t?(g>=s&&c.push(a.value),g++,a.continue()):(this.logger.debug("[StorageService] Messages loaded:",c.length),r(c.reverse()))},o.onerror=()=>{this.logger.error("[StorageService] Failed to load messages:",o.error),a(o.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async updateMessageRevoked(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.isRevoked=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message revoked status updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message revoked status:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for revoke update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for revoke update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageSeqId(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.seqId=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message seqId updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message seqId:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for seqId update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for seqId update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembers(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){const i=n.readMembers||[];if(i.includes(t))s();else{i.push(t),n.readMembers=i;const o=a.put(n);o.onsuccess=()=>{this.logger.debug("[StorageService] Message readMembers updated:",e,t),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update message readMembers:",o.error),r(o.error)}}}else this.logger.debug("[StorageService] Message not found for readMembers update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for readMembers update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembersBySeqId(e,t,s){if(this.db)return new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));let n=0;i.onsuccess=e=>{const a=e.target.result;if(a){const e=a.value;if(e.seqId&&e.seqId<=t){const t=e.readMembers||[];t.includes(s)||(t.push(s),e.readMembers=t,a.update(e),n++)}a.continue()}else n>0&&this.logger.debug("[StorageService] Updated readMembers for",n,"messages, seqId <=",t,"readUserId:",s),r()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update readMembers by seqId:",i.error),a(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteConversationMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));r.onsuccess=s=>{const r=s.target.result;r?(r.delete(),r.continue()):(this.logger.debug("[StorageService] Conversation messages deleted:",e),t())},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation messages:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async cleanOldMessages(e){if(!this.db)return;const t=await this.getMessages(e,Number.MAX_SAFE_INTEGER);if(t.length>500){const e=t.slice(500),s=this.db.transaction(["messages"],"readwrite").objectStore("messages");e.forEach(e=>{s.delete(e.msgId)}),this.logger.debug("[StorageService] Old messages cleaned:",e.length)}}async saveConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation saved:",e.conversationId),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async getConversations(){return this.db?new Promise((e,t)=>{const s=this.db.transaction(["conversations"],"readonly").objectStore("conversations").getAll();s.onsuccess=()=>{const t=s.result;this.logger.debug("[StorageService] Conversations loaded:",t.length),e(t)},s.onerror=()=>{this.logger.error("[StorageService] Failed to load conversations:",s.error),t(s.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async deleteConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}setItem(e,t){try{localStorage.setItem(`im_${e}`,t)}catch(e){this.logger.error("[StorageService] Failed to set localStorage item:",e)}}getItem(e){try{return localStorage.getItem(`im_${e}`)}catch(e){return this.logger.error("[StorageService] Failed to get localStorage item:",e),null}}removeItem(e){try{localStorage.removeItem(`im_${e}`)}catch(e){this.logger.error("[StorageService] Failed to remove localStorage item:",e)}}async clear(){if(this.db){const e=Array.from(this.db.objectStoreNames),t=this.db.transaction(e,"readwrite");e.forEach(e=>{t.objectStore(e).clear()}),await new Promise((e,s)=>{t.oncomplete=()=>{this.logger.info("[StorageService] IndexedDB cleared"),e()},t.onerror=()=>s(t.error)})}try{const e=[];for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);s&&s.startsWith("im_")&&e.push(s)}e.forEach(e=>localStorage.removeItem(e)),this.logger.info("[StorageService] localStorage cleared")}catch(e){this.logger.error("[StorageService] Failed to clear localStorage:",e)}}}class x{constructor(e,t){this.apiService=e,this.logger=t}async uploadFile(e,t){if(this.logger.info("[FileService] Uploading file:",e.name,e.size),e.size>M)throw new g(n.FILE_SIZE_LIMIT,"File size exceeds limit (100MB)");const s=new FormData;s.append("file",e);try{if(null==t?void 0:t.onProgress)return await this.uploadWithProgress(s,t.onProgress);const e=this.apiService.getCurrentToken(),r=this.apiService.getConfig(),a=await fetch(`${r.apiBaseUrl}/comind-im-api/v1/file/upload`,{method:"POST",headers:{token:e||""},body:s});if(!a.ok)throw new Error(`Upload failed: ${a.statusText}`);const i=await a.json();if(!i.success)throw new g(i.errorCode||n.FILE_UPLOAD_FAILED,i.errorMsg||"File upload failed");return this.logger.info("[FileService] File uploaded successfully"),{fileUrl:i.jsonData.filePath,fileName:i.jsonData.originFileName,fileSize:i.jsonData.originFileSize}}catch(e){throw this.logger.error("[FileService] Upload failed:",e),e}}uploadWithProgress(e,t){return new Promise((s,r)=>{const a=new XMLHttpRequest,i=this.apiService.getCurrentToken(),o=this.apiService.getConfig();a.upload.addEventListener("progress",e=>{if(e.lengthComputable){const s=Math.round(e.loaded/e.total*100);t(s)}}),a.addEventListener("load",()=>{if(200===a.status)try{const e=JSON.parse(a.responseText);e.success?s({fileUrl:e.jsonData.filePath,fileName:e.jsonData.originFileName,fileSize:e.jsonData.originFileSize}):r(new g(e.errorCode||n.FILE_UPLOAD_FAILED,e.errorMsg||"File upload failed"))}catch(e){r(new g(n.UNKNOWN_ERROR,"Parse response failed"))}else r(new g(n.FILE_UPLOAD_FAILED,`Upload failed: ${a.statusText}`))}),a.addEventListener("error",()=>{r(new g(n.NETWORK_ERROR,"Network error"))}),a.open("POST",`${o.apiBaseUrl}/comind-im-api/v1/file/upload`),a.setRequestHeader("token",i||""),a.send(e)})}async downloadFile(e,t){try{this.logger.info("[FileService] Downloading file:",e);const s=await fetch(e);if(!s.ok)throw new Error(`Download failed: ${s.statusText}`);const r=await s.blob(),a=URL.createObjectURL(r),i=document.createElement("a");i.href=a,i.download=t||this.getFileNameFromUrl(e),document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a),this.logger.info("[FileService] Download completed")}catch(e){throw this.logger.error("[FileService] Download failed:",e),new g(n.FILE_DOWNLOAD_FAILED,e.message)}}getFileNameFromUrl(e){const t=e.split("/");return t[t.length-1]||"download"}}class B{constructor(e,t){this.socket=null,this.reconnectAttempts=0,this.heartbeatTimer=null,this.isManualDisconnect=!1,this.connectionPromise=null,this.currentToken="",this.authFlag=!1,this.config=e,this.logger=t,this.eventBus=S.getInstance()}async connect(e,t){if(this.connectionPromise)return this.connectionPromise;if(this.isConnected())return this.logger.info("[SocketService] Already connected"),Promise.resolve();this.currentToken=e,this.connectionPromise=this.doConnect(e,t);try{await this.connectionPromise}finally{this.connectionPromise=null}}doConnect(e,s){return new Promise((s,r)=>{this.logger.info("[SocketService] Connecting to WebSocket..."),this.isManualDisconnect=!1;const a=this.config.wsUrl,i=this.config.wsPath||"/socket.io";this.socket=t(a,{path:i,transports:["polling","websocket"],reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3,timeout:2e4,autoConnect:!1}),this.socket.on("connect",()=>{this.logger.info("[SocketService] Socket connected"),this.reconnectAttempts=0,this.authenticate(e)}),this.socket.on(U,e=>{this.handleBinaryMessage(e,s)}),this.socket.on("connect_error",e=>{this.logger.error("[SocketService] Connect error:",e),this.eventBus.emitEvent(o.ERROR,e),r(e)}),this.socket.on("disconnect",e=>{this.logger.warn("[SocketService] Disconnected:",e),this.stopHeartbeat(),this.isManualDisconnect||this.eventBus.emitEvent(o.DISCONNECT,{reason:e})}),this.socket.on("reconnect_attempt",e=>{this.logger.info("[SocketService] Reconnecting...",e),this.reconnectAttempts=e,this.eventBus.emitEvent(o.RECONNECTING,{attempt:e})}),this.socket.on("reconnect",e=>{this.logger.info("[SocketService] Reconnected after",e,"attempts"),this.authenticate(this.currentToken),this.eventBus.emitEvent(o.RECONNECTED)}),this.socket.on("reconnect_failed",()=>{this.logger.error("[SocketService] Reconnect failed"),this.eventBus.emitEvent(o.ERROR,new Error("Reconnect failed"))}),this.socket.connect(),this.authFlag=!1,setTimeout(()=>{this.authFlag||this.isManualDisconnect||r(new Error("Authentication timeout"))},15e3)})}authenticate(e){var t;const s=O(e);this.logger.debug("[SocketService] Sending auth packet"),null===(t=this.socket)||void 0===t||t.emit(U,s)}handleBinaryMessage(e,t){try{const s=_(e);switch(this.logger.debug("[SocketService] Received packet:",s.header.type,s.payload),s.header.type){case y.CONNECT_ACK:this.handleConnectAck(s.payload,t);break;case y.PONG:this.logger.debug("[SocketService] Heartbeat received");break;case y.MESSAGE:this.handleMessagePacket(s);break;case y.DISCONNECT:this.logger.warn("[SocketService] Server requested disconnect"),this.eventBus.emitEvent(o.KICKED_OFFLINE),this.disconnect();break;default:this.logger.warn("[SocketService] Unknown packet type:",s.header.type)}}catch(e){this.logger.error("[SocketService] Failed to decode packet:",e)}}handleConnectAck(e,t){if(this.authFlag=!0,0===e.status)this.logger.info("[SocketService] Authentication successful"),this.startHeartbeat(),this.eventBus.emitEvent(o.CONNECT_SUCCESS),null==t||t();else{const t=e.errMsg||"Authentication failed";this.logger.error("[SocketService] Authentication failed:",t),this.eventBus.emitEvent(o.ERROR,new Error(t))}}handleMessagePacket(e){var t,s;if(void 0!==e.header.ackId){const r=(s=e.header.ackId,T({header:{version:2,type:y.MESSAGE_ACK,ackId:s}}));null===(t=this.socket)||void 0===t||t.emit(U,r)}this.logger.info("[SocketService] Emitting SOCKET_MESSAGE, cmd:",e.payload.cmd),this.eventBus.emitEvent("SOCKET_MESSAGE",{cmd:e.payload.cmd,data:e.payload.bytes,ackId:e.header.ackId})}disconnect(){this.logger.info("[SocketService] Disconnecting..."),this.isManualDisconnect=!0,this.socket&&(this.stopHeartbeat(),this.socket.disconnect(),this.socket=null)}isConnected(){var e;return(null===(e=this.socket)||void 0===e?void 0:e.connected)||!1}async sendMessage(e,t){if(!this.socket||!this.isConnected())throw new Error("Socket not connected");const s=function(e,t){return T({header:{version:2,type:y.MESSAGE,ackId:null!=t?t:N++},payload:e})}(e,t);this.logger.debug("[SocketService] Sending message packet"),this.socket.emit(U,s)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{var e;if(this.isConnected()){const t=T({header:{version:2,type:y.PING}});null===(e=this.socket)||void 0===e||e.emit(U,t),this.logger.debug("[SocketService] Heartbeat sent")}},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}getStatus(){return{connected:this.isConnected(),reconnectAttempts:this.reconnectAttempts}}}class q{constructor(t,s){this.logQueue=[],this.uploadTimer=null,this.userId=null,this.token=null,this.enabled=!1,this.consecutiveFailures=0,this.maxConsecutiveFailures=3,this.uploadDisabled=!1,this.maxPayloadSize=5e4,this.config=t,this.logger=s,this.enabled=!0===t.enableRemoteLog,this.batchSize=t.remoteLogBatchSize||50,this.uploadInterval=t.remoteLogInterval||3e4,this.clientId=this.generateClientId(),this.sessionId=this.generateSessionId(),this.axiosInstance=e.create({baseURL:`${t.apiBaseUrl}/comind-im-api`,timeout:1e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),e)),this.enabled&&(this.startUploadTimer(),this.setupUnloadHandler())}setToken(e){this.token=e}generateClientId(){const e="undefined"!=typeof localStorage?localStorage.getItem("im_sdk_client_id"):null;if(e)return e;const t="client_"+Date.now()+"_"+Math.random().toString(36).substring(2,11);return"undefined"!=typeof localStorage&&localStorage.setItem("im_sdk_client_id",t),t}generateSessionId(){return"session_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateLogId(){return"log_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateBatchId(){return"batch_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}setUserId(e){this.userId=e}setEnabled(e){this.enabled=e,e&&!this.uploadTimer?this.startUploadTimer():!e&&this.uploadTimer&&this.stopUploadTimer()}log(e){if(!this.enabled)return;const t={id:this.generateLogId(),level:e.level||"info",category:e.category||"system",timestamp:Date.now(),...e,context:{userId:this.userId||void 0,sessionId:this.sessionId,...e.context}};this.logQueue.push(t),this.logQueue.length>=this.batchSize&&this.flush()}info(e,t,s){this.log({level:"info",category:e,message:t,data:s})}warn(e,t,s){this.log({level:"warn",category:e,message:t,data:s})}error(e,t,s,r){this.log({level:"error",category:e,message:t,error:s,data:r,status:"error"})}performance(e,t,s,r){this.log({level:"info",category:"performance",module:e,action:t,status:"success",metrics:{duration:s,...r}})}aiCall(e,t,s,r,a){this.log({level:"error"===r?"error":"info",category:"ai_call",action:e,status:r,data:a,metrics:{tokenCount:t,duration:s}})}startUploadTimer(){this.uploadTimer||(this.uploadTimer=window.setInterval(()=>{this.flush()},this.uploadInterval))}stopUploadTimer(){this.uploadTimer&&(window.clearInterval(this.uploadTimer),this.uploadTimer=null)}setupUnloadHandler(){"undefined"!=typeof window&&(window.addEventListener("beforeunload",()=>{this.flushSync()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushSync()}))}flushSync(){}async flush(){}cleanLogEntry(e){var t,s;const r={...e};if(r.message&&r.message.length>500&&(r.message=r.message.substring(0,500)+"... [truncated]"),r.data){const e=JSON.stringify(r.data);e.length>1e3&&(r.data={_truncated:!0,_originalSize:e.length})}return(null===(t=r.error)||void 0===t?void 0:t.stack)&&r.error.stack.length>500&&(r.error={...r.error,stack:r.error.stack.substring(0,500)+"... [truncated]"}),(null===(s=r.error)||void 0===s?void 0:s.message)&&r.error.message.length>200&&(r.error={...r.error,message:r.error.message.substring(0,200)+"..."}),r}resetUploadState(){this.consecutiveFailures=0,this.uploadDisabled=!1,this.logger.info("[TraceLogService] Upload state reset")}getEnvironment(){if("undefined"!=typeof window){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e)return"development";if(e.includes("staging")||e.includes("test")||e.includes("qa"))return"staging"}return"production"}destroy(){this.flushSync(),this.stopUploadTimer(),this.logQueue=[]}}class K{constructor(e,t,s,r,a){this.apiService=e,this.socketService=t,this.storageService=s,this.fileService=r,this.currentUserId="",this.logger=a,this.eventBus=S.getInstance(),this.setupSocketListeners()}setCurrentUserId(e){this.currentUserId=e}createTextMessage(e){return G.createTextMessage(e)}createImageMessage(e){return G.createImageMessage(e)}createFileMessage(e){return G.createFileMessage(e)}createCustomMessage(e){return G.createCustomMessage(e)}createAudioMessage(e){return G.createAudioMessage(e)}createVideoMessage(e){return G.createVideoMessage(e)}async sendMessage(e){var t,s;this.logger.info("[MessageManager] Sending message:",e.msgId);const n=null===(t=e.extra)||void 0===t?void 0:t.file;try{if(e.from=this.currentUserId,e.status=i.SENDING,this.eventBus.emitEvent("MESSAGE_SENDING",e),await this.storageService.saveMessage(this.cleanMessageForStorage(e)),(e.msgType===a.IMAGE||e.msgType===a.FILE||e.msgType===a.AUDIO||e.msgType===a.VIDEO)&&n){const t=await this.fileService.uploadFile(n,{onProgress:t=>{this.eventBus.emitEvent("UPLOAD_PROGRESS",{msgId:e.msgId,progress:t})}}),s=JSON.parse(e.content);s.url=t.fileUrl,s.fileName=t.fileName,s.fileSize=t.fileSize,e.content=JSON.stringify(s),e.extra||(e.extra={}),e.extra.url=t.fileUrl,delete e.extra.file}const t=R((c=e.content,g=e.conversationId,d=e.conversationType===r.SINGLE?I.SINGLE:I.GROUP,l=e.from,u=e.msgType,h=e.extra||{},p=e.msgId,{cmd:m.CHAT_MESSAGE,type:1,id:p||E(),to:g,chatType:d,content:c,createTimestamp:Date.now(),msgType:u,from:l,data:JSON.stringify(h)}));return await this.socketService.sendMessage(t),e.status=i.SUCCESS,e.timestamp=Date.now(),await this.storageService.saveMessage(e),this.eventBus.emitEvent(o.MESSAGE_SENT,e),this.logger.info("[MessageManager] Message sent successfully:",e.msgId),this.fetchMessageSeqId(e.conversationId,e.msgId).catch(e=>{this.logger.warn("[MessageManager] Failed to fetch message seqId:",e)}),e}catch(t){throw this.logger.error("[MessageManager] Send message failed:",t),e.status=i.FAILED,null===(s=e.extra)||void 0===s||delete s.file,await this.storageService.saveMessage(this.cleanMessageForStorage(e)),this.eventBus.emitEvent("MESSAGE_SEND_FAILED",{message:e,error:t}),t}var c,g,d,l,u,h,p}async revokeMessage(e){this.logger.info("[MessageManager] Revoking message:",e.msgId);if(Date.now()-e.timestamp>12e4)throw new Error("Message revoke timeout (2 minutes)");if(e.from!==this.currentUserId)throw new Error("Can only revoke own messages");try{const t=function(e){return R({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType||2,content:"",createTimestamp:e.createTimestamp,msgType:0,from:e.from,data:JSON.stringify({msgId:e.msgId})})}(function(e,t,s,r=2){return{cmd:m.CHAT_MESSAGE,type:3,id:E(),to:t,msgId:e,from:s,chatType:r,createTimestamp:Date.now()}}(e.msgId,e.conversationId,e.from));await this.socketService.sendMessage(t);const s=this.cleanMessageForStorage(e);s.isRevoked=!0,await this.storageService.saveMessage(s),this.eventBus.emitEvent(o.MESSAGE_REVOKED,s),this.logger.info("[MessageManager] Message revoked:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Revoke message failed:",e),e}}cleanMessageForStorage(e){var t;const s=JSON.parse(JSON.stringify(e));return(null===(t=s.extra)||void 0===t?void 0:t.file)&&delete s.extra.file,s}async fetchMessageSeqId(e,t){await new Promise(e=>setTimeout(e,500));try{const s=(await this.apiService.searchRoamingMsg({groupId:e,limitSize:5,syncType:"BACK"})).find(e=>e.id===t||e.msgId===t);s&&s.seqId?(this.logger.info("[MessageManager] Found message seqId from server, msgId:",t,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(t,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t,seqId:s.seqId})):this.logger.warn("[MessageManager] Message not found on server or no seqId, msgId:",t)}catch(e){this.logger.error("[MessageManager] Failed to fetch message seqId:",e)}}async getMessageList(e,t=20,s){this.logger.info("[MessageManager] Getting message list:",e,"lastMsgSeqId:",s);try{const r=(await this.apiService.searchRoamingMsg({groupId:e,msgSeqId:null!=s?s:"",limitSize:t,syncType:"FORWARD"})).map(e=>G.fromServerData(e));r.length>0&&await this.storageService.saveMessages(r);const a=r.length>=t;return r.sort((e,t)=>e.timestamp-t.timestamp),{messages:r,hasMore:a}}catch(s){this.logger.error("[MessageManager] Get message list failed:",s);try{return{messages:await this.storageService.getMessages(e,t),hasMore:!1}}catch(e){throw s}}}async markMessageAsRead(e,t){try{await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:e,seqId:t.seqId}),t.isRead=!0,await this.storageService.saveMessage(t),this.eventBus.emitEvent(o.MESSAGE_READ,{conversationId:e,message:t})}catch(e){throw this.logger.error("[MessageManager] Mark message as read failed:",e),e}}async sendReadReceipt(e){this.logger.info("[MessageManager] Sending read receipt for message:",e.msgId,"seqId:",e.seqId);try{if(e.from===this.currentUserId)return;if(!e.seqId)return void this.logger.warn("[MessageManager] Message has no seqId, skip read receipt");const t=e.conversationType===r.GROUP,s=function(e,t,s,r,a,i){return{cmd:m.CHAT_MESSAGE,type:2,id:E(),to:e,chatType:r,msgType:a,from:i,groupId:t,seqId:s,createTimestamp:Date.now()}}(t?e.conversationId:e.from,e.conversationId,e.seqId,t?I.GROUP:I.SINGLE,e.msgType,this.currentUserId),a=function(e){return R({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType,content:"",createTimestamp:e.createTimestamp,msgType:e.msgType,from:e.from,data:JSON.stringify({groupId:e.groupId,lastReadSeqId:e.seqId})})}(s);await this.socketService.sendMessage(a),this.logger.info("[MessageManager] Read receipt sent for message:",e.msgId,"seqId:",e.seqId)}catch(e){throw this.logger.error("[MessageManager] Send read receipt failed:",e),e}}async deleteMessage(e){try{await this.storageService.deleteMessage(e.msgId),this.logger.info("[MessageManager] Message deleted:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Delete message failed:",e),e}}setupSocketListeners(){this.eventBus.onEvent("SOCKET_MESSAGE",async e=>{this.logger.debug("[MessageManager] Received socket message:",e);try{const t=e.cmd,s=e.data;if(51===t){const e=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",from:"",to:"",handle:0,seqId:0,chatType:0,msgType:0,content:""};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=A(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 9:t.handle=r;break;case 10:t.seqId=r;break;case 11:t.chatType=r;break;case 12:t.msgType=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=A(e,s);s=n;const o=e.slice(s,s+a),c=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=c;break;case 6:t.data=c;break;case 7:t.from=c;break;case 8:t.to=c;break;case 13:t.content=c}}}}return t}(s);if(this.logger.info("[MessageManager] Decoded C2C message, type:",e.type,"from:",e.from,"to:",e.to,"seqId:",e.seqId),1===e.type){const t=G.fromServerData(e);if(t.from===this.currentUserId)return this.logger.info("[MessageManager] Received own message from server, msgId:",t.msgId,"seqId:",t.seqId,"rawId:",e.id),void(t.seqId&&t.msgId?(this.logger.info("[MessageManager] Updating local message seqId, msgId:",t.msgId,"seqId:",t.seqId),await this.storageService.updateMessageSeqId(t.msgId,t.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t.msgId,seqId:t.seqId}),this.logger.info("[MessageManager] MESSAGE_SEQID_UPDATED event emitted")):this.logger.warn("[MessageManager] Missing seqId or msgId, cannot update. seqId:",t.seqId,"msgId:",t.msgId));await this.storageService.saveMessage(t),this.eventBus.emitEvent(o.MESSAGE_RECEIVED,t)}else if(2===e.type||3===e.type){let t="";try{if(e.data){t=JSON.parse(e.data).msgId||""}}catch(e){}if(t||(t=e.id||""),3===e.type){this.logger.debug("[MessageManager] Message revoked:",t);try{await this.storageService.updateMessageRevoked(t,!0)}catch(e){this.logger.error("[MessageManager] Failed to update revoked status in storage:",e)}this.eventBus.emitEvent(o.MESSAGE_REVOKED,{msgId:t,conversationId:e.to})}else{let s=e.seqId,r=e.to;if(e.data)try{const t=JSON.parse(e.data);t.lastReadSeqId&&(s=t.lastReadSeqId),t.groupId&&(r=t.groupId)}catch(e){}if(this.logger.debug("[MessageManager] Message read receipt, seqId:",s,"groupId:",r,"from:",e.from),e.from&&s&&r)try{await this.storageService.updateMessageReadMembersBySeqId(r,s,e.from)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(o.MESSAGE_READ,{msgId:t,seqId:s,conversationId:r,from:e.from})}}}else if(53===t){const e=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",broadcast:0,to:"",seqId:0};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=A(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 7:t.broadcast=r;break;case 9:t.seqId=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=A(e,s);s=n;const o=e.slice(s,s+a),c=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=c;break;case 6:t.data=c;break;case 8:t.to=c}}}}return t}(s);if(this.logger.info("[MessageManager] ===== 收到S2C通知消息 ===== cmd=53, type:",e.type,"data:",e.data),2===e.type)try{const t=JSON.parse(e.data);this.logger.info("[MessageManager] New group notification, groupId:",t.groupId),this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"NEW_GROUP",groupId:t.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse new group notification:",e)}else if(1===e.type)this.logger.warn("[MessageManager] Kicked offline notification"),this.eventBus.emitEvent(o.KICKED_OFFLINE);else if(7===e.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"MEMBER_ADDED",data:e.data});else if(8===e.type||11===e.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:8===e.type?"MEMBER_QUIT":"MEMBER_REMOVED",data:e.data});else if(9===e.type)try{const t=JSON.parse(e.data);this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"GROUP_DISMISSED",groupId:t.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse group dismiss notification:",e)}else if(18===e.type||19===e.type)this.eventBus.emitEvent(o.FRIEND_APPLICATION_RECEIVED,e);else if(23===e.type)try{const t=JSON.parse(e.data),{from:s,groupId:r,lastReadSeqId:a}=t;if(this.logger.info("[MessageManager] Received read receipt notification, from:",s,"groupId:",r,"seqId:",a),s&&r&&a)try{await this.storageService.updateMessageReadMembersBySeqId(r,a,s)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(o.MESSAGE_READ,{seqId:a,conversationId:r,from:s})}catch(e){this.logger.error("[MessageManager] Failed to parse read receipt notification:",e)}}}catch(e){this.logger.error("[MessageManager] Failed to decode message:",e)}}),this.eventBus.onEvent("SOCKET_RECEIPT",async e=>{3===e.type?(this.logger.debug("[MessageManager] Message revoked:",e.msgId),this.eventBus.emitEvent(o.MESSAGE_REVOKED,{msgId:e.msgId,conversationId:e.to})):2===e.type&&(this.logger.debug("[MessageManager] Message read receipt:",e.msgId),this.eventBus.emitEvent(o.MESSAGE_READ,{msgId:e.msgId,conversationId:e.to}))})}}class z{constructor(e,t,s){this.apiService=e,this.storageService=t,this.conversationMap=new Map,this.currentUserId="",this.logger=s,this.eventBus=S.getInstance(),this.setupMessageListeners()}setCurrentUserId(e){this.currentUserId=e}async getConversationList(e){this.logger.info("[ConversationManager] Getting conversation list");try{const{pageNo:t=1,pageSize:s=100}=e||{},a=await this.apiService.getChatList({pageNo:t,pageSize:s});let i=[];try{const e=await this.apiService.getUnreadMsgList();i=Array.isArray(e)?e:[],this.logger.debug("[ConversationManager] Unread messages:",i.length)}catch(e){this.logger.warn("[ConversationManager] Get unread msg list failed:",e)}const n=new Map;for(const e of i)if(51===e.cmd&&e.from!==this.currentUserId&&3!==e.type&&1!==e.isUndo){const t=e.to,s=n.get(t)||0;n.set(t,s+1)}const o=a.result.map(e=>e.groupId);let c=new Map;try{if(o.length>0){const e=await this.apiService.getOfflineMsg(o,1),t=(null==e?void 0:e.groupList)||[];for(const e of t)e.msgDetail&&e.msgDetail.length>0&&c.set(e.groupId,e.msgDetail[0])}}catch(e){this.logger.warn("[ConversationManager] Get offline msg failed:",e)}const g=a.result.map(e=>{const t=c.get(e.groupId)||e.lastMsg,s=t?this.parseLastMessage(t):void 0,a=e.createTime?new Date(e.createTime).getTime():0,i=e.lastMsgTime||(null==s?void 0:s.timestamp)||a||Date.now(),o={conversationId:e.groupId,conversationType:"SINGLE_CHAT"===e.groupType?r.SINGLE:r.GROUP,displayName:e.displayName||e.name||"",avatarUrl:e.groupImg||"",lastMessage:s,lastMessageTime:i,unreadCount:n.get(e.groupId)||0,isPinned:e.onTop||!1,isHidden:e.hidden||!1,pinnedTime:e.pinnedTime};return this.conversationMap.set(o.conversationId,o),o});g.sort((e,t)=>e.isPinned&&!t.isPinned?-1:!e.isPinned&&t.isPinned?1:(t.lastMessageTime||0)-(e.lastMessageTime||0));for(const e of g)await this.storageService.saveConversation(e);return this.eventBus.emitEvent("CONVERSATION_LIST_UPDATED",g),{total:a.total||g.length,conversations:g}}catch(e){this.logger.error("[ConversationManager] Get conversation list failed:",e);const t=await this.storageService.getConversations();return{total:t.length,conversations:t}}}async getConversation(e){return this.logger.info("[ConversationManager] Getting conversation:",e),this.conversationMap.has(e)?this.conversationMap.get(e):(await this.getConversationList(),this.conversationMap.get(e)||null)}async deleteConversation(e){this.logger.info("[ConversationManager] Deleting conversation:",e);try{await this.apiService.hideGroup({groupId:e}),await this.storageService.deleteConversation(e),this.conversationMap.delete(e),this.eventBus.emitEvent("CONVERSATION_DELETED",{conversationId:e}),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Delete conversation failed:",e),e}}async pinConversation(e,t){this.logger.info("[ConversationManager] Pin conversation:",e,t);try{await this.apiService.onTopGroup({groupId:e,onTop:t});const s=this.conversationMap.get(e);s&&(s.isPinned=t,s.pinnedTime=t?Date.now():void 0,await this.storageService.saveConversation(s),this.eventBus.emitEvent(o.CONVERSATION_UPDATED,s)),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Pin conversation failed:",e),e}}getTotalUnreadCount(){let e=0;return this.conversationMap.forEach(t=>{e+=t.unreadCount}),e}async clearUnreadCount(e,t){var s;this.logger.info("[ConversationManager] Clearing unread count:",e,"seqId:",t);try{const r=this.conversationMap.get(e);let a=t;if(a&&0!==a&&""!==a||(a=null===(s=null==r?void 0:r.lastMessage)||void 0===s?void 0:s.seqId),!a||0===a)return this.logger.warn("[ConversationManager] No valid seqId found, skip clearing unread count"),void(r&&(r.unreadCount=0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(o.CONVERSATION_UPDATED,r)));await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:e,seqId:a}),r&&(r.unreadCount=0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(o.CONVERSATION_UPDATED,r))}catch(e){throw this.logger.error("[ConversationManager] Clear unread count failed:",e),e}}async updateConversationLastMessage(e){this.logger.debug("[ConversationManager] Updating conversation last message:",e.msgId);try{let t=this.conversationMap.get(e.conversationId);if(t){t.lastMessage=e,t.lastMessageTime=e.timestamp;this.currentUserId&&e.from===this.currentUserId||e.isRead||t.unreadCount++}else{const s=this.currentUserId&&e.from===this.currentUserId;let a=e.fromUserName||e.conversationId,i=e.fromUserImg||"";if(e.conversationType===r.GROUP)try{const t=await this.apiService.getGroupBaseInfo({groupId:e.conversationId});a=t.name||t.displayName||e.conversationId,i=t.groupImg||"",this.logger.debug("[ConversationManager] Got group info for new conversation:",a)}catch(e){this.logger.warn("[ConversationManager] Failed to get group info:",e)}t={conversationId:e.conversationId,conversationType:e.conversationType,displayName:a,avatarUrl:i,lastMessage:e,lastMessageTime:e.timestamp,unreadCount:s?0:1,isPinned:!1,isHidden:!1},this.conversationMap.set(t.conversationId,t)}await this.storageService.saveConversation(t),this.eventBus.emitEvent(o.CONVERSATION_UPDATED,t)}catch(e){this.logger.error("[ConversationManager] Update conversation last message failed:",e)}}parseLastMessage(e){if(e)return{msgId:e.id||e.msgId||"",conversationId:e.to||e.groupId||"",conversationType:1===e.chatType?r.SINGLE:r.GROUP,from:e.from||"",fromUserName:e.fromUserName,fromUserImg:e.fromUserImg,content:e.content||"",msgType:e.msgType||0,status:1,seqId:e.seqId||0,timestamp:e.createTimestamp||e.createTime||0,isRead:!1}}setupMessageListeners(){this.eventBus.onEvent(o.MESSAGE_RECEIVED,async e=>{await this.updateConversationLastMessage(e)}),this.eventBus.onEvent(o.MESSAGE_SENT,async e=>{await this.updateConversationLastMessage(e)})}}class V{constructor(e,t){this.apiService=e,this.logger=t,this.eventBus=S.getInstance(),this.setupGroupListeners()}async createGroup(e){this.logger.info("[GroupManager] Creating group");try{const t=await this.apiService.createGroup({groupType:e.groupType,userIdList:e.userIdList,name:e.groupName,groupImg:e.groupAvatar}),s=await this.getGroupInfo(t.groupId);return this.eventBus.emitEvent("GROUP_CREATED",s),s}catch(e){throw this.logger.error("[GroupManager] Create group failed:",e),e}}async getGroupInfo(e){this.logger.info("[GroupManager] Getting group info:",e);try{const t=await this.apiService.getGroupBaseInfo({groupId:e});return{groupId:t.groupId,groupType:t.groupType,groupName:t.name||t.displayName,groupAvatar:t.groupImg,notice:t.notice,ownerId:t.owner,memberCount:t.memberCurrent,maxMemberCount:t.memberLimit,createTime:t.createTime}}catch(e){throw this.logger.error("[GroupManager] Get group info failed:",e),e}}async updateGroupInfo(e){this.logger.info("[GroupManager] Updating group info:",e.groupId);try{await this.apiService.updateGroupBaseInfo({groupId:e.groupId,name:e.groupName,groupImg:e.groupAvatar,notice:e.notice}),this.eventBus.emitEvent("GROUP_INFO_UPDATED",{groupId:e.groupId})}catch(e){throw this.logger.error("[GroupManager] Update group info failed:",e),e}}async getGroupMemberList(e){this.logger.info("[GroupManager] Getting group member list:",e.groupId);try{const[t,s]=await Promise.all([this.apiService.getGroupBaseInfo({groupId:e.groupId}),this.apiService.getGroupMemberList({groupId:e.groupId,pageNo:e.pageNo,pageSize:e.pageSize})]),r=t.owner,a=null==r?void 0:r.toLowerCase();return{total:s.total,members:s.result.map(e=>{var t;return{userId:e.userId,userName:e.userName,userAvatar:e.userImg,groupNickname:e.groupNickName,role:(null===(t=e.userId)||void 0===t?void 0:t.toLowerCase())===a?0:1===e.isGroupManager?1:2,joinTime:e.joinTime}})}}catch(e){throw this.logger.error("[GroupManager] Get group member list failed:",e),e}}async addGroupMembers(e,t){this.logger.info("[GroupManager] Adding group members:",e,t);try{await this.apiService.addGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_JOINED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Add group members failed:",e),e}}async removeGroupMembers(e,t){this.logger.info("[GroupManager] Removing group members:",e,t);try{await this.apiService.removeGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_REMOVED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Remove group members failed:",e),e}}async quitGroup(e){this.logger.info("[GroupManager] Quitting group:",e);try{await this.apiService.quitGroup({groupId:e}),this.eventBus.emitEvent("MEMBER_QUIT",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Quit group failed:",e),e}}async dismissGroup(e){this.logger.info("[GroupManager] Dismissing group:",e);try{await this.apiService.dismissGroup({groupId:e}),this.eventBus.emitEvent("GROUP_DISMISSED",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Dismiss group failed:",e),e}}setupGroupListeners(){this.eventBus.onEvent("SOCKET_GROUP_NOTIFICATION",e=>{this.logger.debug("[GroupManager] Group notification:",e),this.eventBus.emitEvent(o.GROUP_NOTIFICATION,e)})}}class j{constructor(e,t){this.apiService=e,this.logger=t}async getCurrentUserInfo(){return this.getUserInfo()}async getUserInfo(e){this.logger.info("[UserManager] Getting user info:",e);try{const t=await this.apiService.getUserInfo({userId:e});return{userId:t.userId,userName:t.userName,userImg:t.userImg,companyName:t.companyName,imRole:t.imRole}}catch(e){throw this.logger.error("[UserManager] Get user info failed:",e),e}}async updateUserInfo(e){this.logger.info("[UserManager] Updating user info:",e.userId);try{await this.apiService.updateUserInfo(e)}catch(e){throw this.logger.error("[UserManager] Update user info failed:",e),e}}async getBlacklist(e=1,t=100){this.logger.info("[UserManager] Getting blacklist");try{return(await this.apiService.getBlacklist({pageNo:e,pageSize:t})).result.map(e=>({userId:e.userId,userName:e.userName,userImg:e.userImg}))}catch(e){throw this.logger.error("[UserManager] Get blacklist failed:",e),e}}async addToBlacklist(e){this.logger.info("[UserManager] Adding to blacklist:",e);try{await this.apiService.addToBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Add to blacklist failed:",e),e}}async removeFromBlacklist(e){this.logger.info("[UserManager] Removing from blacklist:",e);try{await this.apiService.removeFromBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Remove from blacklist failed:",e),e}}async getUserPrivacy(e){this.logger.info("[UserManager] Getting user privacy:",e);try{const t=await this.apiService.getUserPrivacy({userId:e});return{isSetAuth:t.isSetAuth||0,isChatStranger:t.isChatStranger||0}}catch(e){throw this.logger.error("[UserManager] Get user privacy failed:",e),e}}async updatePrivacy(e,t){this.logger.info("[UserManager] Updating user privacy:",e,t);try{await this.apiService.updatePrivacy({userId:e,...t})}catch(e){throw this.logger.error("[UserManager] Update user privacy failed:",e),e}}async changePassword(e,t){this.logger.info("[UserManager] Changing password");try{await this.apiService.changePassword({oldPassword:e,newPassword:t}),this.logger.info("[UserManager] Password changed successfully")}catch(e){throw this.logger.error("[UserManager] Change password failed:",e),e}}}class W{constructor(e,t){this.apiService=e,this.currentUserId="",this.logger=t,this.eventBus=S.getInstance(),this.setupFriendListeners()}setCurrentUserId(e){this.currentUserId=e}async getFriendList(){this.logger.info("[FriendManager] Getting friend list");try{const e=await this.apiService.getFriendList({userId:this.currentUserId}),t=[],s=(null==e?void 0:e.jsonData)||e||[];if(Array.isArray(s))for(const e of s)if(e.friendList&&Array.isArray(e.friendList))for(const s of e.friendList)t.push({userId:s.friendUserId||s.userId,userName:s.friendUserName||s.userName,userImg:s.friendUserImg||s.userImg});return t}catch(e){throw this.logger.error("[FriendManager] Get friend list failed:",e),e}}async getFriendApplicationList(){this.logger.info("[FriendManager] Getting friend application list");try{const e=await this.apiService.getFriendRequestList({userId:this.currentUserId}),t=Array.isArray(e)?e:(null==e?void 0:e.jsonData)||(null==e?void 0:e.result)||[];this.logger.debug("[FriendManager] Friend request list raw data:",t),this.logger.debug("[FriendManager] Current user ID:",this.currentUserId);const s=this.currentUserId.toLowerCase(),r=t.filter(e=>{var t;return(null===(t=e.friendUserId)||void 0===t?void 0:t.toLowerCase())===s});return this.logger.debug("[FriendManager] Incoming requests after filter:",r),r.map(e=>({requestId:e.requestId,userId:e.requestUserId,userName:e.friendUserName||e.requestUserId,userAvatar:e.friendUserImg,applyMessage:e.requestReason,createTime:e.requestTime,status:e.requestStatus}))}catch(e){throw this.logger.error("[FriendManager] Get friend application list failed:",e),e}}async addFriend(e,t,s){this.logger.info("[FriendManager] Adding friend:",e);try{const r=await this.apiService.addFriend({friendUserId:e,requestUserId:this.currentUserId,requestReason:t,requestRemark:s});return this.eventBus.emitEvent("FRIEND_APPLICATION_SENT",{friendUserId:e,requestReason:t}),r}catch(e){throw this.logger.error("[FriendManager] Add friend failed:",e),e}}async acceptFriendApplication(e){this.logger.info("[FriendManager] Accepting friend application:",e);try{const t=await this.apiService.agreeFriendRequest({requestId:e});return this.eventBus.emitEvent(o.FRIEND_ADDED,{requestId:e}),t}catch(e){throw this.logger.error("[FriendManager] Accept friend application failed:",e),e}}async deleteFriend(e){this.logger.info("[FriendManager] Deleting friend:",e);try{await this.apiService.deleteFriend({userId:this.currentUserId,friendUserId:e}),this.eventBus.emitEvent(o.FRIEND_DELETED,{friendUserId:e})}catch(e){throw this.logger.error("[FriendManager] Delete friend failed:",e),e}}setupFriendListeners(){this.eventBus.onEvent("SOCKET_FRIEND_NOTIFICATION",e=>{switch(this.logger.debug("[FriendManager] Friend notification:",e),e.type){case"friend_request":this.eventBus.emitEvent(o.FRIEND_APPLICATION_RECEIVED,e);break;case"friend_added":this.eventBus.emitEvent(o.FRIEND_ADDED,e);break;case"friend_deleted":this.eventBus.emitEvent(o.FRIEND_DELETED,e);break;default:this.logger.warn("[FriendManager] Unknown friend notification type:",e.type)}})}}class H{constructor(e){if(this.logger=d.getInstance(),this.eventBus=S.getInstance(),this.configManager=new l(e),this.stateManager=new u,void 0!==e.logLevel){const t="string"==typeof e.logLevel?s[e.logLevel]:e.logLevel;this.logger.setLevel(t)}!1===e.enableLog&&this.logger.setEnabled(!1),this.apiService=new F(e,this.logger),this.socketService=new B(e,this.logger),this.storageService=new P(this.logger),this.fileService=new x(this.apiService,this.logger),this.traceLogService=new q(e,this.logger),this.message=new K(this.apiService,this.socketService,this.storageService,this.fileService,this.logger),this.conversation=new z(this.apiService,this.storageService,this.logger),this.group=new V(this.apiService,this.logger),this.user=new j(this.apiService,this.logger),this.friend=new W(this.apiService,this.logger),this.logger.info("[IMSDK] SDK initialized")}static create(e){return H.instance||(H.instance=new H(e)),H.instance}static getInstance(){return H.instance}async login(e){this.logger.info("[IMSDK] Logging in:",e.userId);try{let t=e.token,s=0;if(!t){const r=await this.apiService.getToken({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userId:e.userId,userName:e.userName,userAvatar:e.userAvatar});t=r.token,s=r.expireIn}return this.apiService.setToken(t),this.stateManager.setToken(t),this.stateManager.setUserId(e.userId),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(t),this.traceLogService.setUserId(e.userId),this.message.setCurrentUserId(e.userId),this.conversation.setCurrentUserId(e.userId),this.friend.setCurrentUserId(e.userId),await this.storageService.init(),await this.socketService.connect(t,e.userId),this.eventBus.emitEvent(o.LOGIN_SUCCESS,{userId:e.userId,token:t,expireTime:s}),this.logger.info("[IMSDK] Login successful"),{userId:e.userId,token:t,expireTime:s}}catch(e){throw this.logger.error("[IMSDK] Login failed:",e),this.eventBus.emitEvent(o.LOGIN_FAILED,e),e}}async register(e){this.logger.info("[IMSDK] Registering user:",e.userName);try{const t=await this.apiService.registerWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:e.userName,password:e.password,userAvatar:e.userAvatar,companyName:e.companyName}),s=t.token,r=t.expireIn;return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.message.setCurrentUserId(e.userName),this.conversation.setCurrentUserId(e.userName),this.friend.setCurrentUserId(e.userName),await this.storageService.init(),await this.socketService.connect(s,e.userName),this.eventBus.emitEvent(o.LOGIN_SUCCESS,{userId:e.userName,token:s,expireTime:r}),this.logger.info("[IMSDK] Registration and login successful"),{userId:e.userName,token:s,expireTime:r}}catch(e){throw this.logger.error("[IMSDK] Registration failed:",e),this.eventBus.emitEvent(o.LOGIN_FAILED,e),e}}async loginWithPassword(e){this.logger.info("[IMSDK] Logging in with password:",e.userName);try{const t=await this.apiService.loginWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:e.userName,password:e.password}),s=t.token,r=t.expireIn;return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setUserId(e.userName),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.traceLogService.setUserId(e.userName),this.message.setCurrentUserId(e.userName),this.conversation.setCurrentUserId(e.userName),this.friend.setCurrentUserId(e.userName),await this.storageService.init(),await this.socketService.connect(s,e.userName),this.eventBus.emitEvent(o.LOGIN_SUCCESS,{userId:e.userName,token:s,expireTime:r}),this.logger.info("[IMSDK] Login with password successful"),{userId:e.userName,token:s,expireTime:r}}catch(e){throw this.logger.error("[IMSDK] Login with password failed:",e),this.eventBus.emitEvent(o.LOGIN_FAILED,e),e}}async logout(){this.logger.info("[IMSDK] Logging out");try{this.socketService.disconnect(),this.stateManager.clear(),this.apiService.setToken(null),this.traceLogService.setToken(null),this.traceLogService.setUserId(null),this.eventBus.emitEvent(o.LOGOUT),this.logger.info("[IMSDK] Logout successful")}catch(e){throw this.logger.error("[IMSDK] Logout failed:",e),e}}destroy(){this.logger.info("[IMSDK] Destroying SDK instance"),this.isLoggedIn()&&this.logout().catch(()=>{}),this.eventBus.removeAllListeners(),this.traceLogService.destroy(),H.instance=null,this.logger.info("[IMSDK] SDK instance destroyed")}isLoggedIn(){return this.stateManager.isLoggedIn()}getCurrentUserId(){return this.stateManager.getUserId()}getConnectionStatus(){return this.socketService.getStatus()}on(e,t){this.eventBus.onEvent(e,t)}off(e,t){this.eventBus.offEvent(e,t)}once(e,t){this.eventBus.once(e,t)}setLogLevel(e){this.logger.setLevel(e)}setLogEnabled(e){this.logger.setEnabled(e)}static getVersion(){return"1.0.0"}getTraceLogService(){return this.traceLogService}async uploadFile(e,t){return this.fileService.uploadFile(e,{onProgress:t})}}function Y(e){return H.create(e)}H.instance=null;export{r as ConversationType,S as EventBus,g as IMError,n as IMErrorCode,o as IMEventType,H as IMSDK,s as LogLevel,d as Logger,i as MessageStatus,a as MessageType,c as SocketEventType,q as TraceLogService,Y as createIMSDK,H as default,L as formatDate,b as formatRelativeTime,k as parseDate};
package/dist/index.js ADDED
@@ -0,0 +1 @@
1
+ "use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t,s,r,a,o,i,n=require("axios"),g=require("socket.io-client");exports.LogLevel=void 0,(e=exports.LogLevel||(exports.LogLevel={}))[e.VERBOSE=0]="VERBOSE",e[e.DEBUG=1]="DEBUG",e[e.INFO=2]="INFO",e[e.WARN=3]="WARN",e[e.ERROR=4]="ERROR",e[e.NONE=5]="NONE",exports.ConversationType=void 0,(t=exports.ConversationType||(exports.ConversationType={}))[t.SINGLE=1]="SINGLE",t[t.GROUP=2]="GROUP",exports.MessageType=void 0,(s=exports.MessageType||(exports.MessageType={}))[s.TEXT=0]="TEXT",s[s.FILE=1]="FILE",s[s.IMAGE=2]="IMAGE",s[s.VOICE=4]="VOICE",s[s.AUDIO=5]="AUDIO",s[s.VIDEO=6]="VIDEO",s[s.AT_TEXT=8]="AT_TEXT",s[s.CUSTOM=9]="CUSTOM",exports.MessageStatus=void 0,(r=exports.MessageStatus||(exports.MessageStatus={}))[r.SENDING=0]="SENDING",r[r.SUCCESS=1]="SUCCESS",r[r.FAILED=2]="FAILED",exports.IMErrorCode=void 0,(a=exports.IMErrorCode||(exports.IMErrorCode={}))[a.SUCCESS=0]="SUCCESS",a[a.UNKNOWN_ERROR=1e3]="UNKNOWN_ERROR",a[a.NETWORK_ERROR=1001]="NETWORK_ERROR",a[a.INVALID_PARAMETER=1002]="INVALID_PARAMETER",a[a.NOT_INITIALIZED=1003]="NOT_INITIALIZED",a[a.NOT_LOGGED_IN=1004]="NOT_LOGGED_IN",a[a.ALREADY_LOGGED_IN=1005]="ALREADY_LOGGED_IN",a[a.LOGIN_FAILED=2e3]="LOGIN_FAILED",a[a.TOKEN_EXPIRED=2001]="TOKEN_EXPIRED",a[a.TOKEN_INVALID=2002]="TOKEN_INVALID",a[a.USER_NOT_EXIST=2003]="USER_NOT_EXIST",a[a.MESSAGE_SEND_FAILED=3e3]="MESSAGE_SEND_FAILED",a[a.MESSAGE_REVOKE_TIMEOUT=3001]="MESSAGE_REVOKE_TIMEOUT",a[a.MESSAGE_NOT_FOUND=3002]="MESSAGE_NOT_FOUND",a[a.GROUP_NOT_EXIST=4e3]="GROUP_NOT_EXIST",a[a.GROUP_MEMBER_LIMIT=4001]="GROUP_MEMBER_LIMIT",a[a.NOT_GROUP_MEMBER=4002]="NOT_GROUP_MEMBER",a[a.NO_PERMISSION=4003]="NO_PERMISSION",a[a.GROUP_DISMISSED=4004]="GROUP_DISMISSED",a[a.FRIEND_NOT_EXIST=5e3]="FRIEND_NOT_EXIST",a[a.FRIEND_ALREADY_EXIST=5001]="FRIEND_ALREADY_EXIST",a[a.FILE_UPLOAD_FAILED=6e3]="FILE_UPLOAD_FAILED",a[a.FILE_DOWNLOAD_FAILED=6001]="FILE_DOWNLOAD_FAILED",a[a.FILE_SIZE_LIMIT=6002]="FILE_SIZE_LIMIT",a[a.FILE_TYPE_NOT_ALLOWED=6003]="FILE_TYPE_NOT_ALLOWED";class c extends Error{constructor(e,t,s){super(t),this.name="IMError",this.code="string"==typeof e?exports.IMErrorCode.UNKNOWN_ERROR:e,this.detail=s,Object.setPrototypeOf(this,c.prototype)}}exports.IMEventType=void 0,(o=exports.IMEventType||(exports.IMEventType={})).CONNECT_SUCCESS="CONNECT_SUCCESS",o.DISCONNECT="DISCONNECT",o.RECONNECTING="RECONNECTING",o.RECONNECTED="RECONNECTED",o.LOGIN_SUCCESS="LOGIN_SUCCESS",o.LOGIN_FAILED="LOGIN_FAILED",o.LOGOUT="LOGOUT",o.KICKED_OFFLINE="KICKED_OFFLINE",o.MESSAGE_RECEIVED="MESSAGE_RECEIVED",o.MESSAGE_SENT="MESSAGE_SENT",o.MESSAGE_REVOKED="MESSAGE_REVOKED",o.MESSAGE_READ="MESSAGE_READ",o.CONVERSATION_UPDATED="CONVERSATION_UPDATED",o.GROUP_NOTIFICATION="GROUP_NOTIFICATION",o.FRIEND_NOTIFICATION="FRIEND_NOTIFICATION",o.FRIEND_ADDED="FRIEND_ADDED",o.FRIEND_DELETED="FRIEND_DELETED",o.FRIEND_APPLICATION_RECEIVED="FRIEND_APPLICATION_RECEIVED",o.ERROR="ERROR",exports.SocketEventType=void 0,(i=exports.SocketEventType||(exports.SocketEventType={})).CONNECT="connect",i.DISCONNECT="disconnect",i.CONNECT_ERROR="connect_error",i.RECONNECT_ATTEMPT="reconnect_attempt",i.RECONNECT="reconnect",i.RECONNECT_FAILED="reconnect_failed",i.ERROR="error",i.MESSAGE="message",i.GROUP_NOTIFICATION="group_notification",i.FRIEND_NOTIFICATION="friend_notification";class d{constructor(){this.level=exports.LogLevel.INFO,this.enabled=!0}static getInstance(){return d.instance||(d.instance=new d),d.instance}setLevel(e){this.level="string"==typeof e?exports.LogLevel[e]||exports.LogLevel.INFO:e}setEnabled(e){this.enabled=e}verbose(...e){this.log(exports.LogLevel.VERBOSE,...e)}debug(...e){this.log(exports.LogLevel.DEBUG,...e)}info(...e){this.log(exports.LogLevel.INFO,...e)}warn(...e){this.log(exports.LogLevel.WARN,...e)}error(...e){this.log(exports.LogLevel.ERROR,...e)}log(e,...t){if(!this.enabled||e<this.level)return;(new Date).toISOString(),exports.LogLevel[e];switch(e){case exports.LogLevel.ERROR:case exports.LogLevel.WARN:}}}d.instance=null;class l{constructor(e){this.config=null,e&&(this.config=e)}setConfig(e){this.config=e}getConfig(){if(!this.config)throw new Error("SDK not initialized");return this.config}getAppId(){return this.getConfig().appId}getAppSecret(){return this.getConfig().appSecret}getApiBaseUrl(){return this.getConfig().apiBaseUrl}getWsUrl(){return this.getConfig().wsUrl}getWsPath(){return this.getConfig().wsPath||"/socket.io"}}class u{constructor(){this.isLoggedInFlag=!1,this.userId=null,this.token=null}setLoginStatus(e){this.isLoggedInFlag=e}isLoggedIn(){return this.isLoggedInFlag}setUserId(e){this.userId=e;try{localStorage.setItem("im_userId",e)}catch(e){}}getUserId(){return this.userId}setToken(e){this.token=e;try{localStorage.setItem("im_token",e)}catch(e){}}getToken(){return this.token}loadToken(){try{const e=localStorage.getItem("im_token");return e&&(this.token=e),e}catch(e){return null}}loadUserId(){try{const e=localStorage.getItem("im_userId");return e&&(this.userId=e),e}catch(e){return null}}clear(){this.isLoggedInFlag=!1,this.userId=null,this.token=null;try{localStorage.removeItem("im_token"),localStorage.removeItem("im_userId")}catch(e){}}}function h(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var p={exports:{}};!function(e){var t=Object.prototype.hasOwnProperty,s="~";function r(){}function a(e,t,s){this.fn=e,this.context=t,this.once=s||!1}function o(e,t,r,o,i){if("function"!=typeof r)throw new TypeError("The listener must be a function");var n=new a(r,o||e,i),g=s?s+t:t;return e._events[g]?e._events[g].fn?e._events[g]=[e._events[g],n]:e._events[g].push(n):(e._events[g]=n,e._eventsCount++),e}function i(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function n(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(s=!1)),n.prototype.eventNames=function(){var e,r,a=[];if(0===this._eventsCount)return a;for(r in e=this._events)t.call(e,r)&&a.push(s?r.slice(1):r);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(e)):a},n.prototype.listeners=function(e){var t=s?s+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var a=0,o=r.length,i=new Array(o);a<o;a++)i[a]=r[a].fn;return i},n.prototype.listenerCount=function(e){var t=s?s+e:e,r=this._events[t];return r?r.fn?1:r.length:0},n.prototype.emit=function(e,t,r,a,o,i){var n=s?s+e:e;if(!this._events[n])return!1;var g,c,d=this._events[n],l=arguments.length;if(d.fn){switch(d.once&&this.removeListener(e,d.fn,void 0,!0),l){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,t),!0;case 3:return d.fn.call(d.context,t,r),!0;case 4:return d.fn.call(d.context,t,r,a),!0;case 5:return d.fn.call(d.context,t,r,a,o),!0;case 6:return d.fn.call(d.context,t,r,a,o,i),!0}for(c=1,g=new Array(l-1);c<l;c++)g[c-1]=arguments[c];d.fn.apply(d.context,g)}else{var u,h=d.length;for(c=0;c<h;c++)switch(d[c].once&&this.removeListener(e,d[c].fn,void 0,!0),l){case 1:d[c].fn.call(d[c].context);break;case 2:d[c].fn.call(d[c].context,t);break;case 3:d[c].fn.call(d[c].context,t,r);break;case 4:d[c].fn.call(d[c].context,t,r,a);break;default:if(!g)for(u=1,g=new Array(l-1);u<l;u++)g[u-1]=arguments[u];d[c].fn.apply(d[c].context,g)}}return!0},n.prototype.on=function(e,t,s){return o(this,e,t,s,!1)},n.prototype.once=function(e,t,s){return o(this,e,t,s,!0)},n.prototype.removeListener=function(e,t,r,a){var o=s?s+e:e;if(!this._events[o])return this;if(!t)return i(this,o),this;var n=this._events[o];if(n.fn)n.fn!==t||a&&!n.once||r&&n.context!==r||i(this,o);else{for(var g=0,c=[],d=n.length;g<d;g++)(n[g].fn!==t||a&&!n[g].once||r&&n[g].context!==r)&&c.push(n[g]);c.length?this._events[o]=1===c.length?c[0]:c:i(this,o)}return this},n.prototype.removeAllListeners=function(e){var t;return e?(t=s?s+e:e,this._events[t]&&i(this,t)):(this._events=new r,this._eventsCount=0),this},n.prototype.off=n.prototype.removeListener,n.prototype.addListener=n.prototype.on,n.prefixed=s,n.EventEmitter=n,e.exports=n}(p);var I,v,m,S=h(p.exports);class f extends S{constructor(){super()}static getInstance(){return f.instance||(f.instance=new f),f.instance}emitEvent(e,t){this.emit(e,t)}onEvent(e,t){this.on(e,t)}offEvent(e,t){t?this.off(e,t):this.removeAllListeners(e)}onceEvent(e,t){this.once(e,t)}clearAll(){this.removeAllListeners()}}function E(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}f.instance=null,function(e){e[e.CONNECT=1]="CONNECT",e[e.CONNECT_ACK=2]="CONNECT_ACK",e[e.PING=10]="PING",e[e.PONG=11]="PONG",e[e.GROUP_NOTIFICATION=20]="GROUP_NOTIFICATION",e[e.FRIEND_NOTIFICATION=30]="FRIEND_NOTIFICATION",e[e.CHAT_MESSAGE=51]="CHAT_MESSAGE",e[e.RECEIPT_MESSAGE=52]="RECEIPT_MESSAGE",e[e.KICK_OFF=99]="KICK_OFF"}(I||(I={})),function(e){e[e.SINGLE=1]="SINGLE",e[e.GROUP=2]="GROUP"}(v||(v={})),function(e){e[e.DESC=1]="DESC",e[e.ASC=2]="ASC"}(m||(m={}));const M=104857600;var y;!function(e){e[e.UNKNOW_REQ=0]="UNKNOW_REQ",e[e.PING=1]="PING",e[e.PONG=2]="PONG",e[e.CONNECT=3]="CONNECT",e[e.CONNECT_ACK=4]="CONNECT_ACK",e[e.DISCONNECT=5]="DISCONNECT",e[e.Reserved=6]="Reserved",e[e.MESSAGE=7]="MESSAGE",e[e.MESSAGE_ACK=8]="MESSAGE_ACK"}(y||(y={}));let T=Math.floor(1e4*Math.random());function N(e){const t=function(e){const t=null!=e.ackId?6:2,s=new ArrayBuffer(t),r=new DataView(s);return r.setUint8(0,e.version),r.setUint8(1,e.type),null!=e.ackId&&r.setUint32(2,e.ackId),r}(e.header),s=function(e){if(null==e)return null;const t=new ArrayBuffer(e.byteLength),s=new DataView(t);for(let t=0;t<e.byteLength;t++)s.setUint8(t,e[t]);return s}(e.payload||null);let r=t.byteLength;null!=s&&(r+=s.byteLength);const a=new ArrayBuffer(r),o=new DataView(a);for(let e=0;e<t.byteLength;e++)o.setUint8(e,t.getUint8(e));if(null!=s)for(let e=0;e<s.byteLength;e++)o.setUint8(e+t.byteLength,s.getUint8(e));return a}function w(e){const t=[];for(;e>127;)t.push(127&e|128),e>>>=7;return t.push(127&e),t}function C(e,t){return w(e<<3|t)}function D(e){const t=function(e){const t=[];if(t.push(...C(1,0)),t.push(...w(e.cmd)),e.token.length>0){const s=(new TextEncoder).encode(e.token);t.push(...C(2,2)),t.push(...w(s.length)),t.push(...Array.from(s))}return t.push(...C(3,0)),t.push(...w(e.clientType)),new Uint8Array(t)}({cmd:3,token:e,clientType:1});return N({header:{version:2,type:y.CONNECT},payload:t})}function O(e){const t=new DataView(new Uint8Array(e).buffer),s=t.getUint8(0);let r=null;if(0!==s&&t.byteLength>1){r=function(e){if("string"==typeof e)return e;let t="";for(let s=0;s<e.length;s++){const r=e[s].toString(2),a=r.match(/^1+?(?=0)/);if(a&&8===r.length){const r=a[0].length;let o=e[s].toString(2).slice(7-r);for(let t=1;t<r;t++)o+=e[t+s].toString(2).slice(2);t+=String.fromCharCode(parseInt(o,2)),s+=r-1}else t+=String.fromCharCode(e[s])}return t}(e.slice(1))}return{status:s,errMsg:r}}function _(e){const t=Array.from(new Uint8Array(e)),s=function(e){const t=e.getUint8(0),s=e.getUint8(1);let r;return s!==y.MESSAGE&&s!==y.MESSAGE_ACK||(r=e.getUint32(2)),{version:t,type:s,ackId:r}}(new DataView(new Uint8Array(t).buffer));let r=2;s.type!==y.MESSAGE&&s.type!==y.MESSAGE_ACK||(r+=4);const a=t.slice(r);let o=null;return s.type===y.CONNECT_ACK?o=O(a):s.type===y.MESSAGE&&(o=function(e){let t=0;if(e.length>=2&&8===e[0]){let s,r=1,a=0;do{s=e[r++],t|=(127&s)<<a,a+=7}while(s>=128&&r<e.length)}return{cmd:t,bytes:e}}(a)),{header:s,payload:o}}function R(e){const t=[];if(0!==e.cmd&&(t.push(...C(1,0)),t.push(...w(e.cmd))),e.id.length>0){const s=(new TextEncoder).encode(e.id);t.push(...C(2,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(0!==e.createTimestamp&&(t.push(...C(3,0)),t.push(...function(e){const t=[];for(;e>127;)t.push(127&e|128),e=Math.floor(e/128);return t.push(127&e),t}(e.createTimestamp))),0!==e.type&&(t.push(...C(4,0)),t.push(...w(e.type))),e.data&&e.data.length>0){const s=(new TextEncoder).encode(e.data);t.push(...C(6,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(e.from.length>0){const s=(new TextEncoder).encode(e.from);t.push(...C(7,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(e.to.length>0){const s=(new TextEncoder).encode(e.to);t.push(...C(8,2)),t.push(...w(s.length)),t.push(...Array.from(s))}if(0!==e.chatType&&(t.push(...C(11,0)),t.push(...w(e.chatType))),0!==e.msgType&&(t.push(...C(12,0)),t.push(...w(e.msgType))),e.content.length>0){const s=(new TextEncoder).encode(e.content);t.push(...C(13,2)),t.push(...w(s.length)),t.push(...Array.from(s))}return new Uint8Array(t)}function A(e,t){let s,r=0,a=0;do{s=e[t++],r|=(127&s)<<a,a+=7}while(s>=128&&t<e.length);return{value:r,newOffset:t}}const U="imchat";function b(e,t="YYYY-MM-DD HH:mm:ss"){if(!e)return"";let s;if(e instanceof Date)s=e;else if("string"==typeof e){const t=e.replace(/-/g,"/").replace(" ","T")+"Z";s=new Date(t),isNaN(s.getTime())&&(s=new Date(e.replace(/-/g,"/")))}else s=new Date(e);if(isNaN(s.getTime()))return String(e);const r=s.getFullYear(),a=s.getMonth()+1,o=s.getDate(),i=s.getHours(),n=s.getMinutes(),g=s.getSeconds();return t.replace("YYYY",String(r)).replace("MM",String(a).padStart(2,"0")).replace("DD",String(o).padStart(2,"0")).replace("HH",String(i).padStart(2,"0")).replace("mm",String(n).padStart(2,"0")).replace("ss",String(g).padStart(2,"0"))}class x{static createTextMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:r.text,msgType:exports.MessageType.TEXT,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{msgdata:"txt"}}}static createImageMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type}),msgType:exports.MessageType.IMAGE,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,msgdata:"img"}}}static createFileMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type}),msgType:exports.MessageType.FILE,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,msgdata:"file"}}}static createAudioMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type,duration:r.duration||0}),msgType:exports.MessageType.AUDIO,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,duration:r.duration||0,msgdata:"audio"}}}static createVideoMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:JSON.stringify({fileName:r.file.name,fileSize:r.file.size,fileType:r.file.type,duration:r.duration||0,width:r.width||0,height:r.height||0,thumbnailUrl:r.thumbnailUrl||""}),msgType:exports.MessageType.VIDEO,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:r.file,duration:r.duration||0,width:r.width||0,height:r.height||0,thumbnailUrl:r.thumbnailUrl||"",msgdata:"video"}}}static createCustomMessage(e){const{to:t,conversationType:s,payload:r}=e;return{msgId:E(),conversationId:t,conversationType:s,from:"",content:r.description||"[自定义消息]",msgType:exports.MessageType.CUSTOM,status:exports.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{data:r.data,extension:r.extension}}}static fromServerData(e){let t;return e.readRecords&&Array.isArray(e.readRecords)&&(t=e.readRecords.filter(e=>e.readFlag).map(e=>e.userId)),{msgId:e.id||e.msgId,conversationId:e.to||e.groupId,conversationType:1===e.chatType?exports.ConversationType.SINGLE:exports.ConversationType.GROUP,from:e.from,fromUserName:e.fromUserName,fromUserImg:e.fromUserImg,content:e.content,msgType:Number(e.msgType),status:exports.MessageStatus.SUCCESS,seqId:e.seqId||0,timestamp:e.createTimestamp||e.createTime||Date.now(),isRead:e.isRead||!1,isRevoked:e.isRevoked||1===e.isUndo||!1,readMembers:t,extra:e.data?JSON.parse(e.data):void 0}}}class L{constructor(e,t){this.token=null,this.config=e,this.logger=t,this.axiosInstance=n.create({baseURL:`${e.apiBaseUrl}/comind-im-api`,timeout:3e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),this.logger.debug("[APIService] Request:",e.method,e.url),e),e=>(this.logger.error("[APIService] Request error:",e),Promise.reject(e))),this.axiosInstance.interceptors.response.use(e=>{this.logger.debug("[APIService] Response:",e.config.url,e.status,e.data);const t=e.data;if(!0===t.success)return t.jsonData;throw new c(t.errorCode||exports.IMErrorCode.UNKNOWN_ERROR,t.errorMessage||t.errorMsg||"Unknown error")},e=>{var t,s,r;throw this.logger.error("[APIService] Response error:",e),e.response?new c((null===(t=e.response.data)||void 0===t?void 0:t.errorCode)||exports.IMErrorCode.UNKNOWN_ERROR,(null===(s=e.response.data)||void 0===s?void 0:s.errorMessage)||(null===(r=e.response.data)||void 0===r?void 0:r.errorMsg)||e.message):e.request?new c(exports.IMErrorCode.NETWORK_ERROR,"Network error, please check your connection"):new c(exports.IMErrorCode.UNKNOWN_ERROR,e.message)})}setToken(e){this.token=e}getCurrentToken(){return this.token}getConfig(){return this.config}async getToken(e){return this.axiosInstance.post("/v1/token/get",{appId:e.appId,appSecret:e.appSecret,userId:e.userId,userName:e.userName,userImg:e.userAvatar})}async registerWithPassword(e){return this.axiosInstance.post("/v1/token/registerWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password,userImg:e.userAvatar,companyName:e.companyName})}async loginWithPassword(e){return this.axiosInstance.post("/v1/token/loginWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password})}async getUserInfo(e){return this.axiosInstance.post("/v1/user/getUserInfo",e)}async updateUserInfo(e){return this.axiosInstance.post("/v1/user/updateName",e)}async changePassword(e){return this.axiosInstance.post("/v1/user/changePassword",e)}async getChatList(e){return this.axiosInstance.post("/v2/group/list",e||{})}async getOfflineMsg(e,t=10){return this.axiosInstance.post("/v1/msg/getOfflineMsg",{groupIds:e,msgNumberNeedReturned:t})}async getUnreadMsgList(){return this.axiosInstance.post("/v1/msg/unreadMsg")}async searchRoamingMsg(e){var t,s;const r={...e,detailType:null!==(t=e.detailType)&&void 0!==t?t:3,syncType:null!==(s=e.syncType)&&void 0!==s?s:"BACK"};return this.axiosInstance.post("/v1/msg/searchRoamingMsg",r)}async saveLastReadMsgSeqIdOfGroup(e){return this.axiosInstance.post("/v1/msg/saveLastReadMsgSeqIdOfGroup",{groupId:e.groupId,seqId:e.seqId})}async createGroup(e){return this.axiosInstance.post("/v1/group/create",e)}async getGroupBaseInfo(e){return this.axiosInstance.post("/v2/group/getBaseInfo",e)}async updateGroupBaseInfo(e){return this.axiosInstance.post("/v1/group/updateBaseInfo",e)}async getGroupMemberList(e){return this.axiosInstance.post("/v1/groupMember/list",e)}async addGroupMember(e){return this.axiosInstance.post("/v1/groupMember/add",e)}async removeGroupMember(e){return this.axiosInstance.post("/v1/groupMember/remove",e)}async quitGroup(e){return this.axiosInstance.post("/v1/group/quit",e)}async dismissGroup(e){return this.axiosInstance.post("/v2/group/dismiss",e)}async onTopGroup(e){return this.axiosInstance.post("/v1/group/onTop",e)}async hideGroup(e){return this.axiosInstance.post("/v1/group/hide",e)}async getFriendList(e){return this.axiosInstance.post("/v1/friend/list",e||{})}async addFriend(e){return this.axiosInstance.post("/v1/friendRequest/add",e)}async getFriendRequestList(e){return this.axiosInstance.post("/v1/friendRequest/list",e||{})}async agreeFriendRequest(e){return this.axiosInstance.post("/v1/friendRequest/agree",e)}async deleteFriend(e){return this.axiosInstance.post("/v1/friend/delete",e)}async getUserPrivacy(e){return this.axiosInstance.post("/v1/user/getUserPrivacy",e)}async updatePrivacy(e){return this.axiosInstance.post("/v1/user/updatePrivacy",e)}async getBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/list",e||{})}async addToBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/add",e)}async removeFromBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/delete",e)}}class k{constructor(e){this.db=null,this.dbName="comind-im-sdk",this.version=1,this.logger=e}async init(){return new Promise((e,t)=>{const s=indexedDB.open(this.dbName,this.version);s.onerror=()=>{this.logger.error("[StorageService] Failed to open IndexedDB:",s.error),t(s.error)},s.onsuccess=()=>{this.db=s.result,this.logger.info("[StorageService] IndexedDB initialized successfully"),e()},s.onupgradeneeded=e=>{const t=e.target.result;if(!t.objectStoreNames.contains("messages")){const e=t.createObjectStore("messages",{keyPath:"msgId"});e.createIndex("conversationId","conversationId",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),e.createIndex("conv_time",["conversationId","timestamp"],{unique:!1})}if(!t.objectStoreNames.contains("conversations")){t.createObjectStore("conversations",{keyPath:"conversationId"}).createIndex("lastMessageTime","lastMessageTime",{unique:!1})}}})}async saveMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message saved:",e.msgId),this.cleanOldMessages(e.conversationId).catch(e=>{this.logger.warn("[StorageService] Failed to clean old messages:",e)}),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async saveMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite"),a=r.objectStore("messages");let o=e.length;0!==o?(e.forEach(e=>{const t=a.get(e.msgId);t.onsuccess=()=>{const s=t.result;if(s&&(s.isRevoked&&(e.isRevoked=!0),s.readMembers||e.readMembers)){const t=s.readMembers||[],r=e.readMembers||[],a=[...new Set([...t,...r])];e.readMembers=a.length>0?a:void 0}a.put(e),o--},t.onerror=()=>{a.put(e),o--}}),r.oncomplete=()=>{this.logger.debug("[StorageService] Messages saved:",e.length),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save messages:",r.error),s(r.error)}):t()});this.logger.warn("[StorageService] Database not initialized")}async getMessages(e,t=20,s=0){return this.db?new Promise((r,a)=>{const o=this.db.transaction(["messages"],"readonly").objectStore("messages").index("conv_time"),i=IDBKeyRange.bound([e,0],[e,Date.now()]),n=o.openCursor(i,"prev"),g=[];let c=0;n.onsuccess=e=>{const a=e.target.result;a&&c<s+t?(c>=s&&g.push(a.value),c++,a.continue()):(this.logger.debug("[StorageService] Messages loaded:",g.length),r(g.reverse()))},n.onerror=()=>{this.logger.error("[StorageService] Failed to load messages:",n.error),a(n.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async updateMessageRevoked(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),o=a.get(e);o.onsuccess=()=>{const i=o.result;if(i){i.isRevoked=t;const o=a.put(i);o.onsuccess=()=>{this.logger.debug("[StorageService] Message revoked status updated:",e,t),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update message revoked status:",o.error),r(o.error)}}else this.logger.debug("[StorageService] Message not found for revoke update:",e),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to get message for revoke update:",o.error),r(o.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageSeqId(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),o=a.get(e);o.onsuccess=()=>{const i=o.result;if(i){i.seqId=t;const o=a.put(i);o.onsuccess=()=>{this.logger.debug("[StorageService] Message seqId updated:",e,t),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update message seqId:",o.error),r(o.error)}}else this.logger.debug("[StorageService] Message not found for seqId update:",e),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to get message for seqId update:",o.error),r(o.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembers(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),o=a.get(e);o.onsuccess=()=>{const i=o.result;if(i){const o=i.readMembers||[];if(o.includes(t))s();else{o.push(t),i.readMembers=o;const n=a.put(i);n.onsuccess=()=>{this.logger.debug("[StorageService] Message readMembers updated:",e,t),s()},n.onerror=()=>{this.logger.error("[StorageService] Failed to update message readMembers:",n.error),r(n.error)}}}else this.logger.debug("[StorageService] Message not found for readMembers update:",e),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to get message for readMembers update:",o.error),r(o.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembersBySeqId(e,t,s){if(this.db)return new Promise((r,a)=>{const o=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));let i=0;o.onsuccess=e=>{const a=e.target.result;if(a){const e=a.value;if(e.seqId&&e.seqId<=t){const t=e.readMembers||[];t.includes(s)||(t.push(s),e.readMembers=t,a.update(e),i++)}a.continue()}else i>0&&this.logger.debug("[StorageService] Updated readMembers for",i,"messages, seqId <=",t,"readUserId:",s),r()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update readMembers by seqId:",o.error),a(o.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteConversationMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));r.onsuccess=s=>{const r=s.target.result;r?(r.delete(),r.continue()):(this.logger.debug("[StorageService] Conversation messages deleted:",e),t())},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation messages:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async cleanOldMessages(e){if(!this.db)return;const t=await this.getMessages(e,Number.MAX_SAFE_INTEGER);if(t.length>500){const e=t.slice(500),s=this.db.transaction(["messages"],"readwrite").objectStore("messages");e.forEach(e=>{s.delete(e.msgId)}),this.logger.debug("[StorageService] Old messages cleaned:",e.length)}}async saveConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation saved:",e.conversationId),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async getConversations(){return this.db?new Promise((e,t)=>{const s=this.db.transaction(["conversations"],"readonly").objectStore("conversations").getAll();s.onsuccess=()=>{const t=s.result;this.logger.debug("[StorageService] Conversations loaded:",t.length),e(t)},s.onerror=()=>{this.logger.error("[StorageService] Failed to load conversations:",s.error),t(s.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async deleteConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}setItem(e,t){try{localStorage.setItem(`im_${e}`,t)}catch(e){this.logger.error("[StorageService] Failed to set localStorage item:",e)}}getItem(e){try{return localStorage.getItem(`im_${e}`)}catch(e){return this.logger.error("[StorageService] Failed to get localStorage item:",e),null}}removeItem(e){try{localStorage.removeItem(`im_${e}`)}catch(e){this.logger.error("[StorageService] Failed to remove localStorage item:",e)}}async clear(){if(this.db){const e=Array.from(this.db.objectStoreNames),t=this.db.transaction(e,"readwrite");e.forEach(e=>{t.objectStore(e).clear()}),await new Promise((e,s)=>{t.oncomplete=()=>{this.logger.info("[StorageService] IndexedDB cleared"),e()},t.onerror=()=>s(t.error)})}try{const e=[];for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);s&&s.startsWith("im_")&&e.push(s)}e.forEach(e=>localStorage.removeItem(e)),this.logger.info("[StorageService] localStorage cleared")}catch(e){this.logger.error("[StorageService] Failed to clear localStorage:",e)}}}class G{constructor(e,t){this.apiService=e,this.logger=t}async uploadFile(e,t){if(this.logger.info("[FileService] Uploading file:",e.name,e.size),e.size>M)throw new c(exports.IMErrorCode.FILE_SIZE_LIMIT,"File size exceeds limit (100MB)");const s=new FormData;s.append("file",e);try{if(null==t?void 0:t.onProgress)return await this.uploadWithProgress(s,t.onProgress);const e=this.apiService.getCurrentToken(),r=this.apiService.getConfig(),a=await fetch(`${r.apiBaseUrl}/comind-im-api/v1/file/upload`,{method:"POST",headers:{token:e||""},body:s});if(!a.ok)throw new Error(`Upload failed: ${a.statusText}`);const o=await a.json();if(!o.success)throw new c(o.errorCode||exports.IMErrorCode.FILE_UPLOAD_FAILED,o.errorMsg||"File upload failed");return this.logger.info("[FileService] File uploaded successfully"),{fileUrl:o.jsonData.filePath,fileName:o.jsonData.originFileName,fileSize:o.jsonData.originFileSize}}catch(e){throw this.logger.error("[FileService] Upload failed:",e),e}}uploadWithProgress(e,t){return new Promise((s,r)=>{const a=new XMLHttpRequest,o=this.apiService.getCurrentToken(),i=this.apiService.getConfig();a.upload.addEventListener("progress",e=>{if(e.lengthComputable){const s=Math.round(e.loaded/e.total*100);t(s)}}),a.addEventListener("load",()=>{if(200===a.status)try{const e=JSON.parse(a.responseText);e.success?s({fileUrl:e.jsonData.filePath,fileName:e.jsonData.originFileName,fileSize:e.jsonData.originFileSize}):r(new c(e.errorCode||exports.IMErrorCode.FILE_UPLOAD_FAILED,e.errorMsg||"File upload failed"))}catch(e){r(new c(exports.IMErrorCode.UNKNOWN_ERROR,"Parse response failed"))}else r(new c(exports.IMErrorCode.FILE_UPLOAD_FAILED,`Upload failed: ${a.statusText}`))}),a.addEventListener("error",()=>{r(new c(exports.IMErrorCode.NETWORK_ERROR,"Network error"))}),a.open("POST",`${i.apiBaseUrl}/comind-im-api/v1/file/upload`),a.setRequestHeader("token",o||""),a.send(e)})}async downloadFile(e,t){try{this.logger.info("[FileService] Downloading file:",e);const s=await fetch(e);if(!s.ok)throw new Error(`Download failed: ${s.statusText}`);const r=await s.blob(),a=URL.createObjectURL(r),o=document.createElement("a");o.href=a,o.download=t||this.getFileNameFromUrl(e),document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(a),this.logger.info("[FileService] Download completed")}catch(e){throw this.logger.error("[FileService] Download failed:",e),new c(exports.IMErrorCode.FILE_DOWNLOAD_FAILED,e.message)}}getFileNameFromUrl(e){const t=e.split("/");return t[t.length-1]||"download"}}class F{constructor(e,t){this.socket=null,this.reconnectAttempts=0,this.heartbeatTimer=null,this.isManualDisconnect=!1,this.connectionPromise=null,this.currentToken="",this.authFlag=!1,this.config=e,this.logger=t,this.eventBus=f.getInstance()}async connect(e,t){if(this.connectionPromise)return this.connectionPromise;if(this.isConnected())return this.logger.info("[SocketService] Already connected"),Promise.resolve();this.currentToken=e,this.connectionPromise=this.doConnect(e,t);try{await this.connectionPromise}finally{this.connectionPromise=null}}doConnect(e,t){return new Promise((t,s)=>{this.logger.info("[SocketService] Connecting to WebSocket..."),this.isManualDisconnect=!1;const r=this.config.wsUrl,a=this.config.wsPath||"/socket.io";this.socket=g(r,{path:a,transports:["polling","websocket"],reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3,timeout:2e4,autoConnect:!1}),this.socket.on("connect",()=>{this.logger.info("[SocketService] Socket connected"),this.reconnectAttempts=0,this.authenticate(e)}),this.socket.on(U,e=>{this.handleBinaryMessage(e,t)}),this.socket.on("connect_error",e=>{this.logger.error("[SocketService] Connect error:",e),this.eventBus.emitEvent(exports.IMEventType.ERROR,e),s(e)}),this.socket.on("disconnect",e=>{this.logger.warn("[SocketService] Disconnected:",e),this.stopHeartbeat(),this.isManualDisconnect||this.eventBus.emitEvent(exports.IMEventType.DISCONNECT,{reason:e})}),this.socket.on("reconnect_attempt",e=>{this.logger.info("[SocketService] Reconnecting...",e),this.reconnectAttempts=e,this.eventBus.emitEvent(exports.IMEventType.RECONNECTING,{attempt:e})}),this.socket.on("reconnect",e=>{this.logger.info("[SocketService] Reconnected after",e,"attempts"),this.authenticate(this.currentToken),this.eventBus.emitEvent(exports.IMEventType.RECONNECTED)}),this.socket.on("reconnect_failed",()=>{this.logger.error("[SocketService] Reconnect failed"),this.eventBus.emitEvent(exports.IMEventType.ERROR,new Error("Reconnect failed"))}),this.socket.connect(),this.authFlag=!1,setTimeout(()=>{this.authFlag||this.isManualDisconnect||s(new Error("Authentication timeout"))},15e3)})}authenticate(e){var t;const s=D(e);this.logger.debug("[SocketService] Sending auth packet"),null===(t=this.socket)||void 0===t||t.emit(U,s)}handleBinaryMessage(e,t){try{const s=_(e);switch(this.logger.debug("[SocketService] Received packet:",s.header.type,s.payload),s.header.type){case y.CONNECT_ACK:this.handleConnectAck(s.payload,t);break;case y.PONG:this.logger.debug("[SocketService] Heartbeat received");break;case y.MESSAGE:this.handleMessagePacket(s);break;case y.DISCONNECT:this.logger.warn("[SocketService] Server requested disconnect"),this.eventBus.emitEvent(exports.IMEventType.KICKED_OFFLINE),this.disconnect();break;default:this.logger.warn("[SocketService] Unknown packet type:",s.header.type)}}catch(e){this.logger.error("[SocketService] Failed to decode packet:",e)}}handleConnectAck(e,t){if(this.authFlag=!0,0===e.status)this.logger.info("[SocketService] Authentication successful"),this.startHeartbeat(),this.eventBus.emitEvent(exports.IMEventType.CONNECT_SUCCESS),null==t||t();else{const t=e.errMsg||"Authentication failed";this.logger.error("[SocketService] Authentication failed:",t),this.eventBus.emitEvent(exports.IMEventType.ERROR,new Error(t))}}handleMessagePacket(e){var t,s;if(void 0!==e.header.ackId){const r=(s=e.header.ackId,N({header:{version:2,type:y.MESSAGE_ACK,ackId:s}}));null===(t=this.socket)||void 0===t||t.emit(U,r)}this.logger.info("[SocketService] Emitting SOCKET_MESSAGE, cmd:",e.payload.cmd),this.eventBus.emitEvent("SOCKET_MESSAGE",{cmd:e.payload.cmd,data:e.payload.bytes,ackId:e.header.ackId})}disconnect(){this.logger.info("[SocketService] Disconnecting..."),this.isManualDisconnect=!0,this.socket&&(this.stopHeartbeat(),this.socket.disconnect(),this.socket=null)}isConnected(){var e;return(null===(e=this.socket)||void 0===e?void 0:e.connected)||!1}async sendMessage(e,t){if(!this.socket||!this.isConnected())throw new Error("Socket not connected");const s=function(e,t){return N({header:{version:2,type:y.MESSAGE,ackId:null!=t?t:T++},payload:e})}(e,t);this.logger.debug("[SocketService] Sending message packet"),this.socket.emit(U,s)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{var e;if(this.isConnected()){const t=N({header:{version:2,type:y.PING}});null===(e=this.socket)||void 0===e||e.emit(U,t),this.logger.debug("[SocketService] Heartbeat sent")}},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}getStatus(){return{connected:this.isConnected(),reconnectAttempts:this.reconnectAttempts}}}class P{constructor(e,t){this.logQueue=[],this.uploadTimer=null,this.userId=null,this.token=null,this.enabled=!1,this.consecutiveFailures=0,this.maxConsecutiveFailures=3,this.uploadDisabled=!1,this.maxPayloadSize=5e4,this.config=e,this.logger=t,this.enabled=!0===e.enableRemoteLog,this.batchSize=e.remoteLogBatchSize||50,this.uploadInterval=e.remoteLogInterval||3e4,this.clientId=this.generateClientId(),this.sessionId=this.generateSessionId(),this.axiosInstance=n.create({baseURL:`${e.apiBaseUrl}/comind-im-api`,timeout:1e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),e)),this.enabled&&(this.startUploadTimer(),this.setupUnloadHandler())}setToken(e){this.token=e}generateClientId(){const e="undefined"!=typeof localStorage?localStorage.getItem("im_sdk_client_id"):null;if(e)return e;const t="client_"+Date.now()+"_"+Math.random().toString(36).substring(2,11);return"undefined"!=typeof localStorage&&localStorage.setItem("im_sdk_client_id",t),t}generateSessionId(){return"session_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateLogId(){return"log_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateBatchId(){return"batch_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}setUserId(e){this.userId=e}setEnabled(e){this.enabled=e,e&&!this.uploadTimer?this.startUploadTimer():!e&&this.uploadTimer&&this.stopUploadTimer()}log(e){if(!this.enabled)return;const t={id:this.generateLogId(),level:e.level||"info",category:e.category||"system",timestamp:Date.now(),...e,context:{userId:this.userId||void 0,sessionId:this.sessionId,...e.context}};this.logQueue.push(t),this.logQueue.length>=this.batchSize&&this.flush()}info(e,t,s){this.log({level:"info",category:e,message:t,data:s})}warn(e,t,s){this.log({level:"warn",category:e,message:t,data:s})}error(e,t,s,r){this.log({level:"error",category:e,message:t,error:s,data:r,status:"error"})}performance(e,t,s,r){this.log({level:"info",category:"performance",module:e,action:t,status:"success",metrics:{duration:s,...r}})}aiCall(e,t,s,r,a){this.log({level:"error"===r?"error":"info",category:"ai_call",action:e,status:r,data:a,metrics:{tokenCount:t,duration:s}})}startUploadTimer(){this.uploadTimer||(this.uploadTimer=window.setInterval(()=>{this.flush()},this.uploadInterval))}stopUploadTimer(){this.uploadTimer&&(window.clearInterval(this.uploadTimer),this.uploadTimer=null)}setupUnloadHandler(){"undefined"!=typeof window&&(window.addEventListener("beforeunload",()=>{this.flushSync()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushSync()}))}flushSync(){}async flush(){}cleanLogEntry(e){var t,s;const r={...e};if(r.message&&r.message.length>500&&(r.message=r.message.substring(0,500)+"... [truncated]"),r.data){const e=JSON.stringify(r.data);e.length>1e3&&(r.data={_truncated:!0,_originalSize:e.length})}return(null===(t=r.error)||void 0===t?void 0:t.stack)&&r.error.stack.length>500&&(r.error={...r.error,stack:r.error.stack.substring(0,500)+"... [truncated]"}),(null===(s=r.error)||void 0===s?void 0:s.message)&&r.error.message.length>200&&(r.error={...r.error,message:r.error.message.substring(0,200)+"..."}),r}resetUploadState(){this.consecutiveFailures=0,this.uploadDisabled=!1,this.logger.info("[TraceLogService] Upload state reset")}getEnvironment(){if("undefined"!=typeof window){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e)return"development";if(e.includes("staging")||e.includes("test")||e.includes("qa"))return"staging"}return"production"}destroy(){this.flushSync(),this.stopUploadTimer(),this.logQueue=[]}}class B{constructor(e,t,s,r,a){this.apiService=e,this.socketService=t,this.storageService=s,this.fileService=r,this.currentUserId="",this.logger=a,this.eventBus=f.getInstance(),this.setupSocketListeners()}setCurrentUserId(e){this.currentUserId=e}createTextMessage(e){return x.createTextMessage(e)}createImageMessage(e){return x.createImageMessage(e)}createFileMessage(e){return x.createFileMessage(e)}createCustomMessage(e){return x.createCustomMessage(e)}createAudioMessage(e){return x.createAudioMessage(e)}createVideoMessage(e){return x.createVideoMessage(e)}async sendMessage(e){var t,s;this.logger.info("[MessageManager] Sending message:",e.msgId);const r=null===(t=e.extra)||void 0===t?void 0:t.file;try{if(e.from=this.currentUserId,e.status=exports.MessageStatus.SENDING,this.eventBus.emitEvent("MESSAGE_SENDING",e),await this.storageService.saveMessage(this.cleanMessageForStorage(e)),(e.msgType===exports.MessageType.IMAGE||e.msgType===exports.MessageType.FILE||e.msgType===exports.MessageType.AUDIO||e.msgType===exports.MessageType.VIDEO)&&r){const t=await this.fileService.uploadFile(r,{onProgress:t=>{this.eventBus.emitEvent("UPLOAD_PROGRESS",{msgId:e.msgId,progress:t})}}),s=JSON.parse(e.content);s.url=t.fileUrl,s.fileName=t.fileName,s.fileSize=t.fileSize,e.content=JSON.stringify(s),e.extra||(e.extra={}),e.extra.url=t.fileUrl,delete e.extra.file}const t=R((a=e.content,o=e.conversationId,i=e.conversationType===exports.ConversationType.SINGLE?v.SINGLE:v.GROUP,n=e.from,g=e.msgType,c=e.extra||{},d=e.msgId,{cmd:I.CHAT_MESSAGE,type:1,id:d||E(),to:o,chatType:i,content:a,createTimestamp:Date.now(),msgType:g,from:n,data:JSON.stringify(c)}));return await this.socketService.sendMessage(t),e.status=exports.MessageStatus.SUCCESS,e.timestamp=Date.now(),await this.storageService.saveMessage(e),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_SENT,e),this.logger.info("[MessageManager] Message sent successfully:",e.msgId),this.fetchMessageSeqId(e.conversationId,e.msgId).catch(e=>{this.logger.warn("[MessageManager] Failed to fetch message seqId:",e)}),e}catch(t){throw this.logger.error("[MessageManager] Send message failed:",t),e.status=exports.MessageStatus.FAILED,null===(s=e.extra)||void 0===s||delete s.file,await this.storageService.saveMessage(this.cleanMessageForStorage(e)),this.eventBus.emitEvent("MESSAGE_SEND_FAILED",{message:e,error:t}),t}var a,o,i,n,g,c,d}async revokeMessage(e){this.logger.info("[MessageManager] Revoking message:",e.msgId);if(Date.now()-e.timestamp>12e4)throw new Error("Message revoke timeout (2 minutes)");if(e.from!==this.currentUserId)throw new Error("Can only revoke own messages");try{const t=function(e){return R({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType||2,content:"",createTimestamp:e.createTimestamp,msgType:0,from:e.from,data:JSON.stringify({msgId:e.msgId})})}(function(e,t,s,r=2){return{cmd:I.CHAT_MESSAGE,type:3,id:E(),to:t,msgId:e,from:s,chatType:r,createTimestamp:Date.now()}}(e.msgId,e.conversationId,e.from));await this.socketService.sendMessage(t);const s=this.cleanMessageForStorage(e);s.isRevoked=!0,await this.storageService.saveMessage(s),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_REVOKED,s),this.logger.info("[MessageManager] Message revoked:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Revoke message failed:",e),e}}cleanMessageForStorage(e){var t;const s=JSON.parse(JSON.stringify(e));return(null===(t=s.extra)||void 0===t?void 0:t.file)&&delete s.extra.file,s}async fetchMessageSeqId(e,t){await new Promise(e=>setTimeout(e,500));try{const s=(await this.apiService.searchRoamingMsg({groupId:e,limitSize:5,syncType:"BACK"})).find(e=>e.id===t||e.msgId===t);s&&s.seqId?(this.logger.info("[MessageManager] Found message seqId from server, msgId:",t,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(t,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t,seqId:s.seqId})):this.logger.warn("[MessageManager] Message not found on server or no seqId, msgId:",t)}catch(e){this.logger.error("[MessageManager] Failed to fetch message seqId:",e)}}async getMessageList(e,t=20,s){this.logger.info("[MessageManager] Getting message list:",e,"lastMsgSeqId:",s);try{const r=(await this.apiService.searchRoamingMsg({groupId:e,msgSeqId:null!=s?s:"",limitSize:t,syncType:"FORWARD"})).map(e=>x.fromServerData(e));r.length>0&&await this.storageService.saveMessages(r);const a=r.length>=t;return r.sort((e,t)=>e.timestamp-t.timestamp),{messages:r,hasMore:a}}catch(s){this.logger.error("[MessageManager] Get message list failed:",s);try{return{messages:await this.storageService.getMessages(e,t),hasMore:!1}}catch(e){throw s}}}async markMessageAsRead(e,t){try{await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:e,seqId:t.seqId}),t.isRead=!0,await this.storageService.saveMessage(t),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_READ,{conversationId:e,message:t})}catch(e){throw this.logger.error("[MessageManager] Mark message as read failed:",e),e}}async sendReadReceipt(e){this.logger.info("[MessageManager] Sending read receipt for message:",e.msgId,"seqId:",e.seqId);try{if(e.from===this.currentUserId)return;if(!e.seqId)return void this.logger.warn("[MessageManager] Message has no seqId, skip read receipt");const t=e.conversationType===exports.ConversationType.GROUP,s=function(e,t,s,r,a,o){return{cmd:I.CHAT_MESSAGE,type:2,id:E(),to:e,chatType:r,msgType:a,from:o,groupId:t,seqId:s,createTimestamp:Date.now()}}(t?e.conversationId:e.from,e.conversationId,e.seqId,t?v.GROUP:v.SINGLE,e.msgType,this.currentUserId),r=function(e){return R({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType,content:"",createTimestamp:e.createTimestamp,msgType:e.msgType,from:e.from,data:JSON.stringify({groupId:e.groupId,lastReadSeqId:e.seqId})})}(s);await this.socketService.sendMessage(r),this.logger.info("[MessageManager] Read receipt sent for message:",e.msgId,"seqId:",e.seqId)}catch(e){throw this.logger.error("[MessageManager] Send read receipt failed:",e),e}}async deleteMessage(e){try{await this.storageService.deleteMessage(e.msgId),this.logger.info("[MessageManager] Message deleted:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Delete message failed:",e),e}}setupSocketListeners(){this.eventBus.onEvent("SOCKET_MESSAGE",async e=>{this.logger.debug("[MessageManager] Received socket message:",e);try{const t=e.cmd,s=e.data;if(51===t){const e=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",from:"",to:"",handle:0,seqId:0,chatType:0,msgType:0,content:""};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],o=a>>3,i=7&a;if(s++,0===i){const{value:r,newOffset:a}=A(e,s);switch(s=a,o){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 9:t.handle=r;break;case 10:t.seqId=r;break;case 11:t.chatType=r;break;case 12:t.msgType=r}}else{if(2!==i)break;{const{value:a,newOffset:i}=A(e,s);s=i;const n=e.slice(s,s+a),g=r.decode(new Uint8Array(n));switch(s+=a,o){case 2:t.id=g;break;case 6:t.data=g;break;case 7:t.from=g;break;case 8:t.to=g;break;case 13:t.content=g}}}}return t}(s);if(this.logger.info("[MessageManager] Decoded C2C message, type:",e.type,"from:",e.from,"to:",e.to,"seqId:",e.seqId),1===e.type){const t=x.fromServerData(e);if(t.from===this.currentUserId)return this.logger.info("[MessageManager] Received own message from server, msgId:",t.msgId,"seqId:",t.seqId,"rawId:",e.id),void(t.seqId&&t.msgId?(this.logger.info("[MessageManager] Updating local message seqId, msgId:",t.msgId,"seqId:",t.seqId),await this.storageService.updateMessageSeqId(t.msgId,t.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t.msgId,seqId:t.seqId}),this.logger.info("[MessageManager] MESSAGE_SEQID_UPDATED event emitted")):this.logger.warn("[MessageManager] Missing seqId or msgId, cannot update. seqId:",t.seqId,"msgId:",t.msgId));await this.storageService.saveMessage(t),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_RECEIVED,t)}else if(2===e.type||3===e.type){let t="";try{if(e.data){t=JSON.parse(e.data).msgId||""}}catch(e){}if(t||(t=e.id||""),3===e.type){this.logger.debug("[MessageManager] Message revoked:",t);try{await this.storageService.updateMessageRevoked(t,!0)}catch(e){this.logger.error("[MessageManager] Failed to update revoked status in storage:",e)}this.eventBus.emitEvent(exports.IMEventType.MESSAGE_REVOKED,{msgId:t,conversationId:e.to})}else{let s=e.seqId,r=e.to;if(e.data)try{const t=JSON.parse(e.data);t.lastReadSeqId&&(s=t.lastReadSeqId),t.groupId&&(r=t.groupId)}catch(e){}if(this.logger.debug("[MessageManager] Message read receipt, seqId:",s,"groupId:",r,"from:",e.from),e.from&&s&&r)try{await this.storageService.updateMessageReadMembersBySeqId(r,s,e.from)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(exports.IMEventType.MESSAGE_READ,{msgId:t,seqId:s,conversationId:r,from:e.from})}}}else if(53===t){const e=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",broadcast:0,to:"",seqId:0};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],o=a>>3,i=7&a;if(s++,0===i){const{value:r,newOffset:a}=A(e,s);switch(s=a,o){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 7:t.broadcast=r;break;case 9:t.seqId=r}}else{if(2!==i)break;{const{value:a,newOffset:i}=A(e,s);s=i;const n=e.slice(s,s+a),g=r.decode(new Uint8Array(n));switch(s+=a,o){case 2:t.id=g;break;case 6:t.data=g;break;case 8:t.to=g}}}}return t}(s);if(this.logger.info("[MessageManager] ===== 收到S2C通知消息 ===== cmd=53, type:",e.type,"data:",e.data),2===e.type)try{const t=JSON.parse(e.data);this.logger.info("[MessageManager] New group notification, groupId:",t.groupId),this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"NEW_GROUP",groupId:t.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse new group notification:",e)}else if(1===e.type)this.logger.warn("[MessageManager] Kicked offline notification"),this.eventBus.emitEvent(exports.IMEventType.KICKED_OFFLINE);else if(7===e.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"MEMBER_ADDED",data:e.data});else if(8===e.type||11===e.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:8===e.type?"MEMBER_QUIT":"MEMBER_REMOVED",data:e.data});else if(9===e.type)try{const t=JSON.parse(e.data);this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"GROUP_DISMISSED",groupId:t.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse group dismiss notification:",e)}else if(18===e.type||19===e.type)this.eventBus.emitEvent(exports.IMEventType.FRIEND_APPLICATION_RECEIVED,e);else if(23===e.type)try{const t=JSON.parse(e.data),{from:s,groupId:r,lastReadSeqId:a}=t;if(this.logger.info("[MessageManager] Received read receipt notification, from:",s,"groupId:",r,"seqId:",a),s&&r&&a)try{await this.storageService.updateMessageReadMembersBySeqId(r,a,s)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(exports.IMEventType.MESSAGE_READ,{seqId:a,conversationId:r,from:s})}catch(e){this.logger.error("[MessageManager] Failed to parse read receipt notification:",e)}}}catch(e){this.logger.error("[MessageManager] Failed to decode message:",e)}}),this.eventBus.onEvent("SOCKET_RECEIPT",async e=>{3===e.type?(this.logger.debug("[MessageManager] Message revoked:",e.msgId),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_REVOKED,{msgId:e.msgId,conversationId:e.to})):2===e.type&&(this.logger.debug("[MessageManager] Message read receipt:",e.msgId),this.eventBus.emitEvent(exports.IMEventType.MESSAGE_READ,{msgId:e.msgId,conversationId:e.to}))})}}class q{constructor(e,t,s){this.apiService=e,this.storageService=t,this.conversationMap=new Map,this.currentUserId="",this.logger=s,this.eventBus=f.getInstance(),this.setupMessageListeners()}setCurrentUserId(e){this.currentUserId=e}async getConversationList(e){this.logger.info("[ConversationManager] Getting conversation list");try{const{pageNo:t=1,pageSize:s=100}=e||{},r=await this.apiService.getChatList({pageNo:t,pageSize:s});let a=[];try{const e=await this.apiService.getUnreadMsgList();a=Array.isArray(e)?e:[],this.logger.debug("[ConversationManager] Unread messages:",a.length)}catch(e){this.logger.warn("[ConversationManager] Get unread msg list failed:",e)}const o=new Map;for(const e of a)if(51===e.cmd&&e.from!==this.currentUserId&&3!==e.type&&1!==e.isUndo){const t=e.to,s=o.get(t)||0;o.set(t,s+1)}const i=r.result.map(e=>e.groupId);let n=new Map;try{if(i.length>0){const e=await this.apiService.getOfflineMsg(i,1),t=(null==e?void 0:e.groupList)||[];for(const e of t)e.msgDetail&&e.msgDetail.length>0&&n.set(e.groupId,e.msgDetail[0])}}catch(e){this.logger.warn("[ConversationManager] Get offline msg failed:",e)}const g=r.result.map(e=>{const t=n.get(e.groupId)||e.lastMsg,s=t?this.parseLastMessage(t):void 0,r=e.createTime?new Date(e.createTime).getTime():0,a=e.lastMsgTime||(null==s?void 0:s.timestamp)||r||Date.now(),i={conversationId:e.groupId,conversationType:"SINGLE_CHAT"===e.groupType?exports.ConversationType.SINGLE:exports.ConversationType.GROUP,displayName:e.displayName||e.name||"",avatarUrl:e.groupImg||"",lastMessage:s,lastMessageTime:a,unreadCount:o.get(e.groupId)||0,isPinned:e.onTop||!1,isHidden:e.hidden||!1,pinnedTime:e.pinnedTime};return this.conversationMap.set(i.conversationId,i),i});g.sort((e,t)=>e.isPinned&&!t.isPinned?-1:!e.isPinned&&t.isPinned?1:(t.lastMessageTime||0)-(e.lastMessageTime||0));for(const e of g)await this.storageService.saveConversation(e);return this.eventBus.emitEvent("CONVERSATION_LIST_UPDATED",g),{total:r.total||g.length,conversations:g}}catch(e){this.logger.error("[ConversationManager] Get conversation list failed:",e);const t=await this.storageService.getConversations();return{total:t.length,conversations:t}}}async getConversation(e){return this.logger.info("[ConversationManager] Getting conversation:",e),this.conversationMap.has(e)?this.conversationMap.get(e):(await this.getConversationList(),this.conversationMap.get(e)||null)}async deleteConversation(e){this.logger.info("[ConversationManager] Deleting conversation:",e);try{await this.apiService.hideGroup({groupId:e}),await this.storageService.deleteConversation(e),this.conversationMap.delete(e),this.eventBus.emitEvent("CONVERSATION_DELETED",{conversationId:e}),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Delete conversation failed:",e),e}}async pinConversation(e,t){this.logger.info("[ConversationManager] Pin conversation:",e,t);try{await this.apiService.onTopGroup({groupId:e,onTop:t});const s=this.conversationMap.get(e);s&&(s.isPinned=t,s.pinnedTime=t?Date.now():void 0,await this.storageService.saveConversation(s),this.eventBus.emitEvent(exports.IMEventType.CONVERSATION_UPDATED,s)),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Pin conversation failed:",e),e}}getTotalUnreadCount(){let e=0;return this.conversationMap.forEach(t=>{e+=t.unreadCount}),e}async clearUnreadCount(e,t){var s;this.logger.info("[ConversationManager] Clearing unread count:",e,"seqId:",t);try{const r=this.conversationMap.get(e);let a=t;if(a&&0!==a&&""!==a||(a=null===(s=null==r?void 0:r.lastMessage)||void 0===s?void 0:s.seqId),!a||0===a)return this.logger.warn("[ConversationManager] No valid seqId found, skip clearing unread count"),void(r&&(r.unreadCount=0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(exports.IMEventType.CONVERSATION_UPDATED,r)));await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:e,seqId:a}),r&&(r.unreadCount=0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(exports.IMEventType.CONVERSATION_UPDATED,r))}catch(e){throw this.logger.error("[ConversationManager] Clear unread count failed:",e),e}}async updateConversationLastMessage(e){this.logger.debug("[ConversationManager] Updating conversation last message:",e.msgId);try{let t=this.conversationMap.get(e.conversationId);if(t){t.lastMessage=e,t.lastMessageTime=e.timestamp;this.currentUserId&&e.from===this.currentUserId||e.isRead||t.unreadCount++}else{const s=this.currentUserId&&e.from===this.currentUserId;let r=e.fromUserName||e.conversationId,a=e.fromUserImg||"";if(e.conversationType===exports.ConversationType.GROUP)try{const t=await this.apiService.getGroupBaseInfo({groupId:e.conversationId});r=t.name||t.displayName||e.conversationId,a=t.groupImg||"",this.logger.debug("[ConversationManager] Got group info for new conversation:",r)}catch(e){this.logger.warn("[ConversationManager] Failed to get group info:",e)}t={conversationId:e.conversationId,conversationType:e.conversationType,displayName:r,avatarUrl:a,lastMessage:e,lastMessageTime:e.timestamp,unreadCount:s?0:1,isPinned:!1,isHidden:!1},this.conversationMap.set(t.conversationId,t)}await this.storageService.saveConversation(t),this.eventBus.emitEvent(exports.IMEventType.CONVERSATION_UPDATED,t)}catch(e){this.logger.error("[ConversationManager] Update conversation last message failed:",e)}}parseLastMessage(e){if(e)return{msgId:e.id||e.msgId||"",conversationId:e.to||e.groupId||"",conversationType:1===e.chatType?exports.ConversationType.SINGLE:exports.ConversationType.GROUP,from:e.from||"",fromUserName:e.fromUserName,fromUserImg:e.fromUserImg,content:e.content||"",msgType:e.msgType||0,status:1,seqId:e.seqId||0,timestamp:e.createTimestamp||e.createTime||0,isRead:!1}}setupMessageListeners(){this.eventBus.onEvent(exports.IMEventType.MESSAGE_RECEIVED,async e=>{await this.updateConversationLastMessage(e)}),this.eventBus.onEvent(exports.IMEventType.MESSAGE_SENT,async e=>{await this.updateConversationLastMessage(e)})}}class K{constructor(e,t){this.apiService=e,this.logger=t,this.eventBus=f.getInstance(),this.setupGroupListeners()}async createGroup(e){this.logger.info("[GroupManager] Creating group");try{const t=await this.apiService.createGroup({groupType:e.groupType,userIdList:e.userIdList,name:e.groupName,groupImg:e.groupAvatar}),s=await this.getGroupInfo(t.groupId);return this.eventBus.emitEvent("GROUP_CREATED",s),s}catch(e){throw this.logger.error("[GroupManager] Create group failed:",e),e}}async getGroupInfo(e){this.logger.info("[GroupManager] Getting group info:",e);try{const t=await this.apiService.getGroupBaseInfo({groupId:e});return{groupId:t.groupId,groupType:t.groupType,groupName:t.name||t.displayName,groupAvatar:t.groupImg,notice:t.notice,ownerId:t.owner,memberCount:t.memberCurrent,maxMemberCount:t.memberLimit,createTime:t.createTime}}catch(e){throw this.logger.error("[GroupManager] Get group info failed:",e),e}}async updateGroupInfo(e){this.logger.info("[GroupManager] Updating group info:",e.groupId);try{await this.apiService.updateGroupBaseInfo({groupId:e.groupId,name:e.groupName,groupImg:e.groupAvatar,notice:e.notice}),this.eventBus.emitEvent("GROUP_INFO_UPDATED",{groupId:e.groupId})}catch(e){throw this.logger.error("[GroupManager] Update group info failed:",e),e}}async getGroupMemberList(e){this.logger.info("[GroupManager] Getting group member list:",e.groupId);try{const[t,s]=await Promise.all([this.apiService.getGroupBaseInfo({groupId:e.groupId}),this.apiService.getGroupMemberList({groupId:e.groupId,pageNo:e.pageNo,pageSize:e.pageSize})]),r=t.owner,a=null==r?void 0:r.toLowerCase();return{total:s.total,members:s.result.map(e=>{var t;return{userId:e.userId,userName:e.userName,userAvatar:e.userImg,groupNickname:e.groupNickName,role:(null===(t=e.userId)||void 0===t?void 0:t.toLowerCase())===a?0:1===e.isGroupManager?1:2,joinTime:e.joinTime}})}}catch(e){throw this.logger.error("[GroupManager] Get group member list failed:",e),e}}async addGroupMembers(e,t){this.logger.info("[GroupManager] Adding group members:",e,t);try{await this.apiService.addGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_JOINED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Add group members failed:",e),e}}async removeGroupMembers(e,t){this.logger.info("[GroupManager] Removing group members:",e,t);try{await this.apiService.removeGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_REMOVED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Remove group members failed:",e),e}}async quitGroup(e){this.logger.info("[GroupManager] Quitting group:",e);try{await this.apiService.quitGroup({groupId:e}),this.eventBus.emitEvent("MEMBER_QUIT",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Quit group failed:",e),e}}async dismissGroup(e){this.logger.info("[GroupManager] Dismissing group:",e);try{await this.apiService.dismissGroup({groupId:e}),this.eventBus.emitEvent("GROUP_DISMISSED",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Dismiss group failed:",e),e}}setupGroupListeners(){this.eventBus.onEvent("SOCKET_GROUP_NOTIFICATION",e=>{this.logger.debug("[GroupManager] Group notification:",e),this.eventBus.emitEvent(exports.IMEventType.GROUP_NOTIFICATION,e)})}}class z{constructor(e,t){this.apiService=e,this.logger=t}async getCurrentUserInfo(){return this.getUserInfo()}async getUserInfo(e){this.logger.info("[UserManager] Getting user info:",e);try{const t=await this.apiService.getUserInfo({userId:e});return{userId:t.userId,userName:t.userName,userImg:t.userImg,companyName:t.companyName,imRole:t.imRole}}catch(e){throw this.logger.error("[UserManager] Get user info failed:",e),e}}async updateUserInfo(e){this.logger.info("[UserManager] Updating user info:",e.userId);try{await this.apiService.updateUserInfo(e)}catch(e){throw this.logger.error("[UserManager] Update user info failed:",e),e}}async getBlacklist(e=1,t=100){this.logger.info("[UserManager] Getting blacklist");try{return(await this.apiService.getBlacklist({pageNo:e,pageSize:t})).result.map(e=>({userId:e.userId,userName:e.userName,userImg:e.userImg}))}catch(e){throw this.logger.error("[UserManager] Get blacklist failed:",e),e}}async addToBlacklist(e){this.logger.info("[UserManager] Adding to blacklist:",e);try{await this.apiService.addToBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Add to blacklist failed:",e),e}}async removeFromBlacklist(e){this.logger.info("[UserManager] Removing from blacklist:",e);try{await this.apiService.removeFromBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Remove from blacklist failed:",e),e}}async getUserPrivacy(e){this.logger.info("[UserManager] Getting user privacy:",e);try{const t=await this.apiService.getUserPrivacy({userId:e});return{isSetAuth:t.isSetAuth||0,isChatStranger:t.isChatStranger||0}}catch(e){throw this.logger.error("[UserManager] Get user privacy failed:",e),e}}async updatePrivacy(e,t){this.logger.info("[UserManager] Updating user privacy:",e,t);try{await this.apiService.updatePrivacy({userId:e,...t})}catch(e){throw this.logger.error("[UserManager] Update user privacy failed:",e),e}}async changePassword(e,t){this.logger.info("[UserManager] Changing password");try{await this.apiService.changePassword({oldPassword:e,newPassword:t}),this.logger.info("[UserManager] Password changed successfully")}catch(e){throw this.logger.error("[UserManager] Change password failed:",e),e}}}class V{constructor(e,t){this.apiService=e,this.currentUserId="",this.logger=t,this.eventBus=f.getInstance(),this.setupFriendListeners()}setCurrentUserId(e){this.currentUserId=e}async getFriendList(){this.logger.info("[FriendManager] Getting friend list");try{const e=await this.apiService.getFriendList({userId:this.currentUserId}),t=[],s=(null==e?void 0:e.jsonData)||e||[];if(Array.isArray(s))for(const e of s)if(e.friendList&&Array.isArray(e.friendList))for(const s of e.friendList)t.push({userId:s.friendUserId||s.userId,userName:s.friendUserName||s.userName,userImg:s.friendUserImg||s.userImg});return t}catch(e){throw this.logger.error("[FriendManager] Get friend list failed:",e),e}}async getFriendApplicationList(){this.logger.info("[FriendManager] Getting friend application list");try{const e=await this.apiService.getFriendRequestList({userId:this.currentUserId}),t=Array.isArray(e)?e:(null==e?void 0:e.jsonData)||(null==e?void 0:e.result)||[];this.logger.debug("[FriendManager] Friend request list raw data:",t),this.logger.debug("[FriendManager] Current user ID:",this.currentUserId);const s=this.currentUserId.toLowerCase(),r=t.filter(e=>{var t;return(null===(t=e.friendUserId)||void 0===t?void 0:t.toLowerCase())===s});return this.logger.debug("[FriendManager] Incoming requests after filter:",r),r.map(e=>({requestId:e.requestId,userId:e.requestUserId,userName:e.friendUserName||e.requestUserId,userAvatar:e.friendUserImg,applyMessage:e.requestReason,createTime:e.requestTime,status:e.requestStatus}))}catch(e){throw this.logger.error("[FriendManager] Get friend application list failed:",e),e}}async addFriend(e,t,s){this.logger.info("[FriendManager] Adding friend:",e);try{const r=await this.apiService.addFriend({friendUserId:e,requestUserId:this.currentUserId,requestReason:t,requestRemark:s});return this.eventBus.emitEvent("FRIEND_APPLICATION_SENT",{friendUserId:e,requestReason:t}),r}catch(e){throw this.logger.error("[FriendManager] Add friend failed:",e),e}}async acceptFriendApplication(e){this.logger.info("[FriendManager] Accepting friend application:",e);try{const t=await this.apiService.agreeFriendRequest({requestId:e});return this.eventBus.emitEvent(exports.IMEventType.FRIEND_ADDED,{requestId:e}),t}catch(e){throw this.logger.error("[FriendManager] Accept friend application failed:",e),e}}async deleteFriend(e){this.logger.info("[FriendManager] Deleting friend:",e);try{await this.apiService.deleteFriend({userId:this.currentUserId,friendUserId:e}),this.eventBus.emitEvent(exports.IMEventType.FRIEND_DELETED,{friendUserId:e})}catch(e){throw this.logger.error("[FriendManager] Delete friend failed:",e),e}}setupFriendListeners(){this.eventBus.onEvent("SOCKET_FRIEND_NOTIFICATION",e=>{switch(this.logger.debug("[FriendManager] Friend notification:",e),e.type){case"friend_request":this.eventBus.emitEvent(exports.IMEventType.FRIEND_APPLICATION_RECEIVED,e);break;case"friend_added":this.eventBus.emitEvent(exports.IMEventType.FRIEND_ADDED,e);break;case"friend_deleted":this.eventBus.emitEvent(exports.IMEventType.FRIEND_DELETED,e);break;default:this.logger.warn("[FriendManager] Unknown friend notification type:",e.type)}})}}class j{constructor(e){if(this.logger=d.getInstance(),this.eventBus=f.getInstance(),this.configManager=new l(e),this.stateManager=new u,void 0!==e.logLevel){const t="string"==typeof e.logLevel?exports.LogLevel[e.logLevel]:e.logLevel;this.logger.setLevel(t)}!1===e.enableLog&&this.logger.setEnabled(!1),this.apiService=new L(e,this.logger),this.socketService=new F(e,this.logger),this.storageService=new k(this.logger),this.fileService=new G(this.apiService,this.logger),this.traceLogService=new P(e,this.logger),this.message=new B(this.apiService,this.socketService,this.storageService,this.fileService,this.logger),this.conversation=new q(this.apiService,this.storageService,this.logger),this.group=new K(this.apiService,this.logger),this.user=new z(this.apiService,this.logger),this.friend=new V(this.apiService,this.logger),this.logger.info("[IMSDK] SDK initialized")}static create(e){return j.instance||(j.instance=new j(e)),j.instance}static getInstance(){return j.instance}async login(e){this.logger.info("[IMSDK] Logging in:",e.userId);try{let t=e.token,s=0;if(!t){const r=await this.apiService.getToken({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userId:e.userId,userName:e.userName,userAvatar:e.userAvatar});t=r.token,s=r.expireIn}return this.apiService.setToken(t),this.stateManager.setToken(t),this.stateManager.setUserId(e.userId),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(t),this.traceLogService.setUserId(e.userId),this.message.setCurrentUserId(e.userId),this.conversation.setCurrentUserId(e.userId),this.friend.setCurrentUserId(e.userId),await this.storageService.init(),await this.socketService.connect(t,e.userId),this.eventBus.emitEvent(exports.IMEventType.LOGIN_SUCCESS,{userId:e.userId,token:t,expireTime:s}),this.logger.info("[IMSDK] Login successful"),{userId:e.userId,token:t,expireTime:s}}catch(e){throw this.logger.error("[IMSDK] Login failed:",e),this.eventBus.emitEvent(exports.IMEventType.LOGIN_FAILED,e),e}}async register(e){this.logger.info("[IMSDK] Registering user:",e.userName);try{const t=await this.apiService.registerWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:e.userName,password:e.password,userAvatar:e.userAvatar,companyName:e.companyName}),s=t.token,r=t.expireIn;return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.message.setCurrentUserId(e.userName),this.conversation.setCurrentUserId(e.userName),this.friend.setCurrentUserId(e.userName),await this.storageService.init(),await this.socketService.connect(s,e.userName),this.eventBus.emitEvent(exports.IMEventType.LOGIN_SUCCESS,{userId:e.userName,token:s,expireTime:r}),this.logger.info("[IMSDK] Registration and login successful"),{userId:e.userName,token:s,expireTime:r}}catch(e){throw this.logger.error("[IMSDK] Registration failed:",e),this.eventBus.emitEvent(exports.IMEventType.LOGIN_FAILED,e),e}}async loginWithPassword(e){this.logger.info("[IMSDK] Logging in with password:",e.userName);try{const t=await this.apiService.loginWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:e.userName,password:e.password}),s=t.token,r=t.expireIn;return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setUserId(e.userName),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.traceLogService.setUserId(e.userName),this.message.setCurrentUserId(e.userName),this.conversation.setCurrentUserId(e.userName),this.friend.setCurrentUserId(e.userName),await this.storageService.init(),await this.socketService.connect(s,e.userName),this.eventBus.emitEvent(exports.IMEventType.LOGIN_SUCCESS,{userId:e.userName,token:s,expireTime:r}),this.logger.info("[IMSDK] Login with password successful"),{userId:e.userName,token:s,expireTime:r}}catch(e){throw this.logger.error("[IMSDK] Login with password failed:",e),this.eventBus.emitEvent(exports.IMEventType.LOGIN_FAILED,e),e}}async logout(){this.logger.info("[IMSDK] Logging out");try{this.socketService.disconnect(),this.stateManager.clear(),this.apiService.setToken(null),this.traceLogService.setToken(null),this.traceLogService.setUserId(null),this.eventBus.emitEvent(exports.IMEventType.LOGOUT),this.logger.info("[IMSDK] Logout successful")}catch(e){throw this.logger.error("[IMSDK] Logout failed:",e),e}}destroy(){this.logger.info("[IMSDK] Destroying SDK instance"),this.isLoggedIn()&&this.logout().catch(()=>{}),this.eventBus.removeAllListeners(),this.traceLogService.destroy(),j.instance=null,this.logger.info("[IMSDK] SDK instance destroyed")}isLoggedIn(){return this.stateManager.isLoggedIn()}getCurrentUserId(){return this.stateManager.getUserId()}getConnectionStatus(){return this.socketService.getStatus()}on(e,t){this.eventBus.onEvent(e,t)}off(e,t){this.eventBus.offEvent(e,t)}once(e,t){this.eventBus.once(e,t)}setLogLevel(e){this.logger.setLevel(e)}setLogEnabled(e){this.logger.setEnabled(e)}static getVersion(){return"1.0.0"}getTraceLogService(){return this.traceLogService}async uploadFile(e,t){return this.fileService.uploadFile(e,{onProgress:t})}}j.instance=null,exports.EventBus=f,exports.IMError=c,exports.IMSDK=j,exports.Logger=d,exports.TraceLogService=P,exports.createIMSDK=function(e){return j.create(e)},exports.default=j,exports.formatDate=b,exports.formatRelativeTime=function(e){if(!e)return"";let t;if(e instanceof Date)t=e;else if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);if(isNaN(t.getTime()))return String(e);const s=new Date,r=s.getTime()-t.getTime();return r<0||r>31536e6?b(t,"YYYY/MM/DD"):r<6e4?"刚刚":r<36e5?`${Math.floor(r/6e4)}分钟前`:r<864e5?t.getDate()===s.getDate()&&t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear()?`今天 ${b(t,"HH:mm")}`:`昨天 ${b(t,"HH:mm")}`:r<6048e5?`${Math.floor(r/864e5)}天前`:t.getFullYear()===s.getFullYear()?b(t,"MM/DD"):b(t,"YYYY/MM/DD")},exports.parseDate=function(e){if(!e)return null;let t;if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);return isNaN(t.getTime())?null:t};
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("axios"),require("socket.io-client")):"function"==typeof define&&define.amd?define(["exports","axios","socket.io-client"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ComindIMSDK={},e.axios,e.io)}(this,function(e,t,s){"use strict";var r,a,i,n,o,g,c;e.LogLevel=void 0,(r=e.LogLevel||(e.LogLevel={}))[r.VERBOSE=0]="VERBOSE",r[r.DEBUG=1]="DEBUG",r[r.INFO=2]="INFO",r[r.WARN=3]="WARN",r[r.ERROR=4]="ERROR",r[r.NONE=5]="NONE",e.ConversationType=void 0,(a=e.ConversationType||(e.ConversationType={}))[a.SINGLE=1]="SINGLE",a[a.GROUP=2]="GROUP",e.MessageType=void 0,(i=e.MessageType||(e.MessageType={}))[i.TEXT=0]="TEXT",i[i.FILE=1]="FILE",i[i.IMAGE=2]="IMAGE",i[i.VOICE=4]="VOICE",i[i.AUDIO=5]="AUDIO",i[i.VIDEO=6]="VIDEO",i[i.AT_TEXT=8]="AT_TEXT",i[i.CUSTOM=9]="CUSTOM",e.MessageStatus=void 0,(n=e.MessageStatus||(e.MessageStatus={}))[n.SENDING=0]="SENDING",n[n.SUCCESS=1]="SUCCESS",n[n.FAILED=2]="FAILED",e.IMErrorCode=void 0,(o=e.IMErrorCode||(e.IMErrorCode={}))[o.SUCCESS=0]="SUCCESS",o[o.UNKNOWN_ERROR=1e3]="UNKNOWN_ERROR",o[o.NETWORK_ERROR=1001]="NETWORK_ERROR",o[o.INVALID_PARAMETER=1002]="INVALID_PARAMETER",o[o.NOT_INITIALIZED=1003]="NOT_INITIALIZED",o[o.NOT_LOGGED_IN=1004]="NOT_LOGGED_IN",o[o.ALREADY_LOGGED_IN=1005]="ALREADY_LOGGED_IN",o[o.LOGIN_FAILED=2e3]="LOGIN_FAILED",o[o.TOKEN_EXPIRED=2001]="TOKEN_EXPIRED",o[o.TOKEN_INVALID=2002]="TOKEN_INVALID",o[o.USER_NOT_EXIST=2003]="USER_NOT_EXIST",o[o.MESSAGE_SEND_FAILED=3e3]="MESSAGE_SEND_FAILED",o[o.MESSAGE_REVOKE_TIMEOUT=3001]="MESSAGE_REVOKE_TIMEOUT",o[o.MESSAGE_NOT_FOUND=3002]="MESSAGE_NOT_FOUND",o[o.GROUP_NOT_EXIST=4e3]="GROUP_NOT_EXIST",o[o.GROUP_MEMBER_LIMIT=4001]="GROUP_MEMBER_LIMIT",o[o.NOT_GROUP_MEMBER=4002]="NOT_GROUP_MEMBER",o[o.NO_PERMISSION=4003]="NO_PERMISSION",o[o.GROUP_DISMISSED=4004]="GROUP_DISMISSED",o[o.FRIEND_NOT_EXIST=5e3]="FRIEND_NOT_EXIST",o[o.FRIEND_ALREADY_EXIST=5001]="FRIEND_ALREADY_EXIST",o[o.FILE_UPLOAD_FAILED=6e3]="FILE_UPLOAD_FAILED",o[o.FILE_DOWNLOAD_FAILED=6001]="FILE_DOWNLOAD_FAILED",o[o.FILE_SIZE_LIMIT=6002]="FILE_SIZE_LIMIT",o[o.FILE_TYPE_NOT_ALLOWED=6003]="FILE_TYPE_NOT_ALLOWED";class d extends Error{constructor(t,s,r){super(s),this.name="IMError",this.code="string"==typeof t?e.IMErrorCode.UNKNOWN_ERROR:t,this.detail=r,Object.setPrototypeOf(this,d.prototype)}}e.IMEventType=void 0,(g=e.IMEventType||(e.IMEventType={})).CONNECT_SUCCESS="CONNECT_SUCCESS",g.DISCONNECT="DISCONNECT",g.RECONNECTING="RECONNECTING",g.RECONNECTED="RECONNECTED",g.LOGIN_SUCCESS="LOGIN_SUCCESS",g.LOGIN_FAILED="LOGIN_FAILED",g.LOGOUT="LOGOUT",g.KICKED_OFFLINE="KICKED_OFFLINE",g.MESSAGE_RECEIVED="MESSAGE_RECEIVED",g.MESSAGE_SENT="MESSAGE_SENT",g.MESSAGE_REVOKED="MESSAGE_REVOKED",g.MESSAGE_READ="MESSAGE_READ",g.CONVERSATION_UPDATED="CONVERSATION_UPDATED",g.GROUP_NOTIFICATION="GROUP_NOTIFICATION",g.FRIEND_NOTIFICATION="FRIEND_NOTIFICATION",g.FRIEND_ADDED="FRIEND_ADDED",g.FRIEND_DELETED="FRIEND_DELETED",g.FRIEND_APPLICATION_RECEIVED="FRIEND_APPLICATION_RECEIVED",g.ERROR="ERROR",e.SocketEventType=void 0,(c=e.SocketEventType||(e.SocketEventType={})).CONNECT="connect",c.DISCONNECT="disconnect",c.CONNECT_ERROR="connect_error",c.RECONNECT_ATTEMPT="reconnect_attempt",c.RECONNECT="reconnect",c.RECONNECT_FAILED="reconnect_failed",c.ERROR="error",c.MESSAGE="message",c.GROUP_NOTIFICATION="group_notification",c.FRIEND_NOTIFICATION="friend_notification";class l{constructor(){this.level=e.LogLevel.INFO,this.enabled=!0}static getInstance(){return l.instance||(l.instance=new l),l.instance}setLevel(t){this.level="string"==typeof t?e.LogLevel[t]||e.LogLevel.INFO:t}setEnabled(e){this.enabled=e}verbose(...t){this.log(e.LogLevel.VERBOSE,...t)}debug(...t){this.log(e.LogLevel.DEBUG,...t)}info(...t){this.log(e.LogLevel.INFO,...t)}warn(...t){this.log(e.LogLevel.WARN,...t)}error(...t){this.log(e.LogLevel.ERROR,...t)}log(t,...s){if(!this.enabled||t<this.level)return;(new Date).toISOString(),e.LogLevel[t];switch(t){case e.LogLevel.ERROR:case e.LogLevel.WARN:}}}l.instance=null;class u{constructor(e){this.config=null,e&&(this.config=e)}setConfig(e){this.config=e}getConfig(){if(!this.config)throw new Error("SDK not initialized");return this.config}getAppId(){return this.getConfig().appId}getAppSecret(){return this.getConfig().appSecret}getApiBaseUrl(){return this.getConfig().apiBaseUrl}getWsUrl(){return this.getConfig().wsUrl}getWsPath(){return this.getConfig().wsPath||"/socket.io"}}class h{constructor(){this.isLoggedInFlag=!1,this.userId=null,this.token=null}setLoginStatus(e){this.isLoggedInFlag=e}isLoggedIn(){return this.isLoggedInFlag}setUserId(e){this.userId=e;try{localStorage.setItem("im_userId",e)}catch(e){}}getUserId(){return this.userId}setToken(e){this.token=e;try{localStorage.setItem("im_token",e)}catch(e){}}getToken(){return this.token}loadToken(){try{const e=localStorage.getItem("im_token");return e&&(this.token=e),e}catch(e){return null}}loadUserId(){try{const e=localStorage.getItem("im_userId");return e&&(this.userId=e),e}catch(e){return null}}clear(){this.isLoggedInFlag=!1,this.userId=null,this.token=null;try{localStorage.removeItem("im_token"),localStorage.removeItem("im_userId")}catch(e){}}}function p(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var I={exports:{}};!function(e){var t=Object.prototype.hasOwnProperty,s="~";function r(){}function a(e,t,s){this.fn=e,this.context=t,this.once=s||!1}function i(e,t,r,i,n){if("function"!=typeof r)throw new TypeError("The listener must be a function");var o=new a(r,i||e,n),g=s?s+t:t;return e._events[g]?e._events[g].fn?e._events[g]=[e._events[g],o]:e._events[g].push(o):(e._events[g]=o,e._eventsCount++),e}function n(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function o(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(s=!1)),o.prototype.eventNames=function(){var e,r,a=[];if(0===this._eventsCount)return a;for(r in e=this._events)t.call(e,r)&&a.push(s?r.slice(1):r);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(e)):a},o.prototype.listeners=function(e){var t=s?s+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var a=0,i=r.length,n=new Array(i);a<i;a++)n[a]=r[a].fn;return n},o.prototype.listenerCount=function(e){var t=s?s+e:e,r=this._events[t];return r?r.fn?1:r.length:0},o.prototype.emit=function(e,t,r,a,i,n){var o=s?s+e:e;if(!this._events[o])return!1;var g,c,d=this._events[o],l=arguments.length;if(d.fn){switch(d.once&&this.removeListener(e,d.fn,void 0,!0),l){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,t),!0;case 3:return d.fn.call(d.context,t,r),!0;case 4:return d.fn.call(d.context,t,r,a),!0;case 5:return d.fn.call(d.context,t,r,a,i),!0;case 6:return d.fn.call(d.context,t,r,a,i,n),!0}for(c=1,g=new Array(l-1);c<l;c++)g[c-1]=arguments[c];d.fn.apply(d.context,g)}else{var u,h=d.length;for(c=0;c<h;c++)switch(d[c].once&&this.removeListener(e,d[c].fn,void 0,!0),l){case 1:d[c].fn.call(d[c].context);break;case 2:d[c].fn.call(d[c].context,t);break;case 3:d[c].fn.call(d[c].context,t,r);break;case 4:d[c].fn.call(d[c].context,t,r,a);break;default:if(!g)for(u=1,g=new Array(l-1);u<l;u++)g[u-1]=arguments[u];d[c].fn.apply(d[c].context,g)}}return!0},o.prototype.on=function(e,t,s){return i(this,e,t,s,!1)},o.prototype.once=function(e,t,s){return i(this,e,t,s,!0)},o.prototype.removeListener=function(e,t,r,a){var i=s?s+e:e;if(!this._events[i])return this;if(!t)return n(this,i),this;var o=this._events[i];if(o.fn)o.fn!==t||a&&!o.once||r&&o.context!==r||n(this,i);else{for(var g=0,c=[],d=o.length;g<d;g++)(o[g].fn!==t||a&&!o[g].once||r&&o[g].context!==r)&&c.push(o[g]);c.length?this._events[i]=1===c.length?c[0]:c:n(this,i)}return this},o.prototype.removeAllListeners=function(e){var t;return e?(t=s?s+e:e,this._events[t]&&n(this,t)):(this._events=new r,this._eventsCount=0),this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prefixed=s,o.EventEmitter=o,e.exports=o}(I);var v,m,S,f=p(I.exports);class E extends f{constructor(){super()}static getInstance(){return E.instance||(E.instance=new E),E.instance}emitEvent(e,t){this.emit(e,t)}onEvent(e,t){this.on(e,t)}offEvent(e,t){t?this.off(e,t):this.removeAllListeners(e)}onceEvent(e,t){this.once(e,t)}clearAll(){this.removeAllListeners()}}function M(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}E.instance=null,function(e){e[e.CONNECT=1]="CONNECT",e[e.CONNECT_ACK=2]="CONNECT_ACK",e[e.PING=10]="PING",e[e.PONG=11]="PONG",e[e.GROUP_NOTIFICATION=20]="GROUP_NOTIFICATION",e[e.FRIEND_NOTIFICATION=30]="FRIEND_NOTIFICATION",e[e.CHAT_MESSAGE=51]="CHAT_MESSAGE",e[e.RECEIPT_MESSAGE=52]="RECEIPT_MESSAGE",e[e.KICK_OFF=99]="KICK_OFF"}(v||(v={})),function(e){e[e.SINGLE=1]="SINGLE",e[e.GROUP=2]="GROUP"}(m||(m={})),function(e){e[e.DESC=1]="DESC",e[e.ASC=2]="ASC"}(S||(S={}));const y=104857600;var T;!function(e){e[e.UNKNOW_REQ=0]="UNKNOW_REQ",e[e.PING=1]="PING",e[e.PONG=2]="PONG",e[e.CONNECT=3]="CONNECT",e[e.CONNECT_ACK=4]="CONNECT_ACK",e[e.DISCONNECT=5]="DISCONNECT",e[e.Reserved=6]="Reserved",e[e.MESSAGE=7]="MESSAGE",e[e.MESSAGE_ACK=8]="MESSAGE_ACK"}(T||(T={}));let N=Math.floor(1e4*Math.random());function w(e){const t=function(e){const t=null!=e.ackId?6:2,s=new ArrayBuffer(t),r=new DataView(s);return r.setUint8(0,e.version),r.setUint8(1,e.type),null!=e.ackId&&r.setUint32(2,e.ackId),r}(e.header),s=function(e){if(null==e)return null;const t=new ArrayBuffer(e.byteLength),s=new DataView(t);for(let t=0;t<e.byteLength;t++)s.setUint8(t,e[t]);return s}(e.payload||null);let r=t.byteLength;null!=s&&(r+=s.byteLength);const a=new ArrayBuffer(r),i=new DataView(a);for(let e=0;e<t.byteLength;e++)i.setUint8(e,t.getUint8(e));if(null!=s)for(let e=0;e<s.byteLength;e++)i.setUint8(e+t.byteLength,s.getUint8(e));return a}function C(e){const t=[];for(;e>127;)t.push(127&e|128),e>>>=7;return t.push(127&e),t}function D(e,t){return C(e<<3|t)}function O(e){const t=function(e){const t=[];if(t.push(...D(1,0)),t.push(...C(e.cmd)),e.token.length>0){const s=(new TextEncoder).encode(e.token);t.push(...D(2,2)),t.push(...C(s.length)),t.push(...Array.from(s))}return t.push(...D(3,0)),t.push(...C(e.clientType)),new Uint8Array(t)}({cmd:3,token:e,clientType:1});return w({header:{version:2,type:T.CONNECT},payload:t})}function _(e){const t=new DataView(new Uint8Array(e).buffer),s=t.getUint8(0);let r=null;if(0!==s&&t.byteLength>1){r=function(e){if("string"==typeof e)return e;let t="";for(let s=0;s<e.length;s++){const r=e[s].toString(2),a=r.match(/^1+?(?=0)/);if(a&&8===r.length){const r=a[0].length;let i=e[s].toString(2).slice(7-r);for(let t=1;t<r;t++)i+=e[t+s].toString(2).slice(2);t+=String.fromCharCode(parseInt(i,2)),s+=r-1}else t+=String.fromCharCode(e[s])}return t}(e.slice(1))}return{status:s,errMsg:r}}function R(e){const t=Array.from(new Uint8Array(e)),s=function(e){const t=e.getUint8(0),s=e.getUint8(1);let r;return s!==T.MESSAGE&&s!==T.MESSAGE_ACK||(r=e.getUint32(2)),{version:t,type:s,ackId:r}}(new DataView(new Uint8Array(t).buffer));let r=2;s.type!==T.MESSAGE&&s.type!==T.MESSAGE_ACK||(r+=4);const a=t.slice(r);let i=null;return s.type===T.CONNECT_ACK?i=_(a):s.type===T.MESSAGE&&(i=function(e){let t=0;if(e.length>=2&&8===e[0]){let s,r=1,a=0;do{s=e[r++],t|=(127&s)<<a,a+=7}while(s>=128&&r<e.length)}return{cmd:t,bytes:e}}(a)),{header:s,payload:i}}function A(e){const t=[];if(0!==e.cmd&&(t.push(...D(1,0)),t.push(...C(e.cmd))),e.id.length>0){const s=(new TextEncoder).encode(e.id);t.push(...D(2,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(0!==e.createTimestamp&&(t.push(...D(3,0)),t.push(...function(e){const t=[];for(;e>127;)t.push(127&e|128),e=Math.floor(e/128);return t.push(127&e),t}(e.createTimestamp))),0!==e.type&&(t.push(...D(4,0)),t.push(...C(e.type))),e.data&&e.data.length>0){const s=(new TextEncoder).encode(e.data);t.push(...D(6,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(e.from.length>0){const s=(new TextEncoder).encode(e.from);t.push(...D(7,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(e.to.length>0){const s=(new TextEncoder).encode(e.to);t.push(...D(8,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(0!==e.chatType&&(t.push(...D(11,0)),t.push(...C(e.chatType))),0!==e.msgType&&(t.push(...D(12,0)),t.push(...C(e.msgType))),e.content.length>0){const s=(new TextEncoder).encode(e.content);t.push(...D(13,2)),t.push(...C(s.length)),t.push(...Array.from(s))}return new Uint8Array(t)}function b(e,t){let s,r=0,a=0;do{s=e[t++],r|=(127&s)<<a,a+=7}while(s>=128&&t<e.length);return{value:r,newOffset:t}}const U="imchat";function L(e,t="YYYY-MM-DD HH:mm:ss"){if(!e)return"";let s;if(e instanceof Date)s=e;else if("string"==typeof e){const t=e.replace(/-/g,"/").replace(" ","T")+"Z";s=new Date(t),isNaN(s.getTime())&&(s=new Date(e.replace(/-/g,"/")))}else s=new Date(e);if(isNaN(s.getTime()))return String(e);const r=s.getFullYear(),a=s.getMonth()+1,i=s.getDate(),n=s.getHours(),o=s.getMinutes(),g=s.getSeconds();return t.replace("YYYY",String(r)).replace("MM",String(a).padStart(2,"0")).replace("DD",String(i).padStart(2,"0")).replace("HH",String(n).padStart(2,"0")).replace("mm",String(o).padStart(2,"0")).replace("ss",String(g).padStart(2,"0"))}class k{static createTextMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:a.text,msgType:e.MessageType.TEXT,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{msgdata:"txt"}}}static createImageMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type}),msgType:e.MessageType.IMAGE,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,msgdata:"img"}}}static createFileMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type}),msgType:e.MessageType.FILE,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,msgdata:"file"}}}static createAudioMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type,duration:a.duration||0}),msgType:e.MessageType.AUDIO,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,duration:a.duration||0,msgdata:"audio"}}}static createVideoMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type,duration:a.duration||0,width:a.width||0,height:a.height||0,thumbnailUrl:a.thumbnailUrl||""}),msgType:e.MessageType.VIDEO,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,duration:a.duration||0,width:a.width||0,height:a.height||0,thumbnailUrl:a.thumbnailUrl||"",msgdata:"video"}}}static createCustomMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:a.description||"[自定义消息]",msgType:e.MessageType.CUSTOM,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{data:a.data,extension:a.extension}}}static fromServerData(t){let s;return t.readRecords&&Array.isArray(t.readRecords)&&(s=t.readRecords.filter(e=>e.readFlag).map(e=>e.userId)),{msgId:t.id||t.msgId,conversationId:t.to||t.groupId,conversationType:1===t.chatType?e.ConversationType.SINGLE:e.ConversationType.GROUP,from:t.from,fromUserName:t.fromUserName,fromUserImg:t.fromUserImg,content:t.content,msgType:Number(t.msgType),status:e.MessageStatus.SUCCESS,seqId:t.seqId||0,timestamp:t.createTimestamp||t.createTime||Date.now(),isRead:t.isRead||!1,isRevoked:t.isRevoked||1===t.isUndo||!1,readMembers:s,extra:t.data?JSON.parse(t.data):void 0}}}class G{constructor(s,r){this.token=null,this.config=s,this.logger=r,this.axiosInstance=t.create({baseURL:`${s.apiBaseUrl}/comind-im-api`,timeout:3e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),this.logger.debug("[APIService] Request:",e.method,e.url),e),e=>(this.logger.error("[APIService] Request error:",e),Promise.reject(e))),this.axiosInstance.interceptors.response.use(t=>{this.logger.debug("[APIService] Response:",t.config.url,t.status,t.data);const s=t.data;if(!0===s.success)return s.jsonData;throw new d(s.errorCode||e.IMErrorCode.UNKNOWN_ERROR,s.errorMessage||s.errorMsg||"Unknown error")},t=>{var s,r,a;throw this.logger.error("[APIService] Response error:",t),t.response?new d((null===(s=t.response.data)||void 0===s?void 0:s.errorCode)||e.IMErrorCode.UNKNOWN_ERROR,(null===(r=t.response.data)||void 0===r?void 0:r.errorMessage)||(null===(a=t.response.data)||void 0===a?void 0:a.errorMsg)||t.message):t.request?new d(e.IMErrorCode.NETWORK_ERROR,"Network error, please check your connection"):new d(e.IMErrorCode.UNKNOWN_ERROR,t.message)})}setToken(e){this.token=e}getCurrentToken(){return this.token}getConfig(){return this.config}async getToken(e){return this.axiosInstance.post("/v1/token/get",{appId:e.appId,appSecret:e.appSecret,userId:e.userId,userName:e.userName,userImg:e.userAvatar})}async registerWithPassword(e){return this.axiosInstance.post("/v1/token/registerWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password,userImg:e.userAvatar,companyName:e.companyName})}async loginWithPassword(e){return this.axiosInstance.post("/v1/token/loginWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password})}async getUserInfo(e){return this.axiosInstance.post("/v1/user/getUserInfo",e)}async updateUserInfo(e){return this.axiosInstance.post("/v1/user/updateName",e)}async changePassword(e){return this.axiosInstance.post("/v1/user/changePassword",e)}async getChatList(e){return this.axiosInstance.post("/v2/group/list",e||{})}async getOfflineMsg(e,t=10){return this.axiosInstance.post("/v1/msg/getOfflineMsg",{groupIds:e,msgNumberNeedReturned:t})}async getUnreadMsgList(){return this.axiosInstance.post("/v1/msg/unreadMsg")}async searchRoamingMsg(e){var t,s;const r={...e,detailType:null!==(t=e.detailType)&&void 0!==t?t:3,syncType:null!==(s=e.syncType)&&void 0!==s?s:"BACK"};return this.axiosInstance.post("/v1/msg/searchRoamingMsg",r)}async saveLastReadMsgSeqIdOfGroup(e){return this.axiosInstance.post("/v1/msg/saveLastReadMsgSeqIdOfGroup",{groupId:e.groupId,seqId:e.seqId})}async createGroup(e){return this.axiosInstance.post("/v1/group/create",e)}async getGroupBaseInfo(e){return this.axiosInstance.post("/v2/group/getBaseInfo",e)}async updateGroupBaseInfo(e){return this.axiosInstance.post("/v1/group/updateBaseInfo",e)}async getGroupMemberList(e){return this.axiosInstance.post("/v1/groupMember/list",e)}async addGroupMember(e){return this.axiosInstance.post("/v1/groupMember/add",e)}async removeGroupMember(e){return this.axiosInstance.post("/v1/groupMember/remove",e)}async quitGroup(e){return this.axiosInstance.post("/v1/group/quit",e)}async dismissGroup(e){return this.axiosInstance.post("/v2/group/dismiss",e)}async onTopGroup(e){return this.axiosInstance.post("/v1/group/onTop",e)}async hideGroup(e){return this.axiosInstance.post("/v1/group/hide",e)}async getFriendList(e){return this.axiosInstance.post("/v1/friend/list",e||{})}async addFriend(e){return this.axiosInstance.post("/v1/friendRequest/add",e)}async getFriendRequestList(e){return this.axiosInstance.post("/v1/friendRequest/list",e||{})}async agreeFriendRequest(e){return this.axiosInstance.post("/v1/friendRequest/agree",e)}async deleteFriend(e){return this.axiosInstance.post("/v1/friend/delete",e)}async getUserPrivacy(e){return this.axiosInstance.post("/v1/user/getUserPrivacy",e)}async updatePrivacy(e){return this.axiosInstance.post("/v1/user/updatePrivacy",e)}async getBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/list",e||{})}async addToBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/add",e)}async removeFromBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/delete",e)}}class F{constructor(e){this.db=null,this.dbName="comind-im-sdk",this.version=1,this.logger=e}async init(){return new Promise((e,t)=>{const s=indexedDB.open(this.dbName,this.version);s.onerror=()=>{this.logger.error("[StorageService] Failed to open IndexedDB:",s.error),t(s.error)},s.onsuccess=()=>{this.db=s.result,this.logger.info("[StorageService] IndexedDB initialized successfully"),e()},s.onupgradeneeded=e=>{const t=e.target.result;if(!t.objectStoreNames.contains("messages")){const e=t.createObjectStore("messages",{keyPath:"msgId"});e.createIndex("conversationId","conversationId",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),e.createIndex("conv_time",["conversationId","timestamp"],{unique:!1})}if(!t.objectStoreNames.contains("conversations")){t.createObjectStore("conversations",{keyPath:"conversationId"}).createIndex("lastMessageTime","lastMessageTime",{unique:!1})}}})}async saveMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message saved:",e.msgId),this.cleanOldMessages(e.conversationId).catch(e=>{this.logger.warn("[StorageService] Failed to clean old messages:",e)}),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async saveMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite"),a=r.objectStore("messages");let i=e.length;0!==i?(e.forEach(e=>{const t=a.get(e.msgId);t.onsuccess=()=>{const s=t.result;if(s&&(s.isRevoked&&(e.isRevoked=!0),s.readMembers||e.readMembers)){const t=s.readMembers||[],r=e.readMembers||[],a=[...new Set([...t,...r])];e.readMembers=a.length>0?a:void 0}a.put(e),i--},t.onerror=()=>{a.put(e),i--}}),r.oncomplete=()=>{this.logger.debug("[StorageService] Messages saved:",e.length),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save messages:",r.error),s(r.error)}):t()});this.logger.warn("[StorageService] Database not initialized")}async getMessages(e,t=20,s=0){return this.db?new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readonly").objectStore("messages").index("conv_time"),n=IDBKeyRange.bound([e,0],[e,Date.now()]),o=i.openCursor(n,"prev"),g=[];let c=0;o.onsuccess=e=>{const a=e.target.result;a&&c<s+t?(c>=s&&g.push(a.value),c++,a.continue()):(this.logger.debug("[StorageService] Messages loaded:",g.length),r(g.reverse()))},o.onerror=()=>{this.logger.error("[StorageService] Failed to load messages:",o.error),a(o.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async updateMessageRevoked(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.isRevoked=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message revoked status updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message revoked status:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for revoke update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for revoke update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageSeqId(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.seqId=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message seqId updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message seqId:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for seqId update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for seqId update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembers(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){const i=n.readMembers||[];if(i.includes(t))s();else{i.push(t),n.readMembers=i;const o=a.put(n);o.onsuccess=()=>{this.logger.debug("[StorageService] Message readMembers updated:",e,t),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update message readMembers:",o.error),r(o.error)}}}else this.logger.debug("[StorageService] Message not found for readMembers update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for readMembers update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembersBySeqId(e,t,s){if(this.db)return new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));let n=0;i.onsuccess=e=>{const a=e.target.result;if(a){const e=a.value;if(e.seqId&&e.seqId<=t){const t=e.readMembers||[];t.includes(s)||(t.push(s),e.readMembers=t,a.update(e),n++)}a.continue()}else n>0&&this.logger.debug("[StorageService] Updated readMembers for",n,"messages, seqId <=",t,"readUserId:",s),r()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update readMembers by seqId:",i.error),a(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteConversationMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));r.onsuccess=s=>{const r=s.target.result;r?(r.delete(),r.continue()):(this.logger.debug("[StorageService] Conversation messages deleted:",e),t())},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation messages:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async cleanOldMessages(e){if(!this.db)return;const t=await this.getMessages(e,Number.MAX_SAFE_INTEGER);if(t.length>500){const e=t.slice(500),s=this.db.transaction(["messages"],"readwrite").objectStore("messages");e.forEach(e=>{s.delete(e.msgId)}),this.logger.debug("[StorageService] Old messages cleaned:",e.length)}}async saveConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation saved:",e.conversationId),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async getConversations(){return this.db?new Promise((e,t)=>{const s=this.db.transaction(["conversations"],"readonly").objectStore("conversations").getAll();s.onsuccess=()=>{const t=s.result;this.logger.debug("[StorageService] Conversations loaded:",t.length),e(t)},s.onerror=()=>{this.logger.error("[StorageService] Failed to load conversations:",s.error),t(s.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async deleteConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}setItem(e,t){try{localStorage.setItem(`im_${e}`,t)}catch(e){this.logger.error("[StorageService] Failed to set localStorage item:",e)}}getItem(e){try{return localStorage.getItem(`im_${e}`)}catch(e){return this.logger.error("[StorageService] Failed to get localStorage item:",e),null}}removeItem(e){try{localStorage.removeItem(`im_${e}`)}catch(e){this.logger.error("[StorageService] Failed to remove localStorage item:",e)}}async clear(){if(this.db){const e=Array.from(this.db.objectStoreNames),t=this.db.transaction(e,"readwrite");e.forEach(e=>{t.objectStore(e).clear()}),await new Promise((e,s)=>{t.oncomplete=()=>{this.logger.info("[StorageService] IndexedDB cleared"),e()},t.onerror=()=>s(t.error)})}try{const e=[];for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);s&&s.startsWith("im_")&&e.push(s)}e.forEach(e=>localStorage.removeItem(e)),this.logger.info("[StorageService] localStorage cleared")}catch(e){this.logger.error("[StorageService] Failed to clear localStorage:",e)}}}class P{constructor(e,t){this.apiService=e,this.logger=t}async uploadFile(t,s){if(this.logger.info("[FileService] Uploading file:",t.name,t.size),t.size>y)throw new d(e.IMErrorCode.FILE_SIZE_LIMIT,"File size exceeds limit (100MB)");const r=new FormData;r.append("file",t);try{if(null==s?void 0:s.onProgress)return await this.uploadWithProgress(r,s.onProgress);const t=this.apiService.getCurrentToken(),a=this.apiService.getConfig(),i=await fetch(`${a.apiBaseUrl}/comind-im-api/v1/file/upload`,{method:"POST",headers:{token:t||""},body:r});if(!i.ok)throw new Error(`Upload failed: ${i.statusText}`);const n=await i.json();if(!n.success)throw new d(n.errorCode||e.IMErrorCode.FILE_UPLOAD_FAILED,n.errorMsg||"File upload failed");return this.logger.info("[FileService] File uploaded successfully"),{fileUrl:n.jsonData.filePath,fileName:n.jsonData.originFileName,fileSize:n.jsonData.originFileSize}}catch(e){throw this.logger.error("[FileService] Upload failed:",e),e}}uploadWithProgress(t,s){return new Promise((r,a)=>{const i=new XMLHttpRequest,n=this.apiService.getCurrentToken(),o=this.apiService.getConfig();i.upload.addEventListener("progress",e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t)}}),i.addEventListener("load",()=>{if(200===i.status)try{const t=JSON.parse(i.responseText);t.success?r({fileUrl:t.jsonData.filePath,fileName:t.jsonData.originFileName,fileSize:t.jsonData.originFileSize}):a(new d(t.errorCode||e.IMErrorCode.FILE_UPLOAD_FAILED,t.errorMsg||"File upload failed"))}catch(t){a(new d(e.IMErrorCode.UNKNOWN_ERROR,"Parse response failed"))}else a(new d(e.IMErrorCode.FILE_UPLOAD_FAILED,`Upload failed: ${i.statusText}`))}),i.addEventListener("error",()=>{a(new d(e.IMErrorCode.NETWORK_ERROR,"Network error"))}),i.open("POST",`${o.apiBaseUrl}/comind-im-api/v1/file/upload`),i.setRequestHeader("token",n||""),i.send(t)})}async downloadFile(t,s){try{this.logger.info("[FileService] Downloading file:",t);const e=await fetch(t);if(!e.ok)throw new Error(`Download failed: ${e.statusText}`);const r=await e.blob(),a=URL.createObjectURL(r),i=document.createElement("a");i.href=a,i.download=s||this.getFileNameFromUrl(t),document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a),this.logger.info("[FileService] Download completed")}catch(t){throw this.logger.error("[FileService] Download failed:",t),new d(e.IMErrorCode.FILE_DOWNLOAD_FAILED,t.message)}}getFileNameFromUrl(e){const t=e.split("/");return t[t.length-1]||"download"}}class x{constructor(e,t){this.socket=null,this.reconnectAttempts=0,this.heartbeatTimer=null,this.isManualDisconnect=!1,this.connectionPromise=null,this.currentToken="",this.authFlag=!1,this.config=e,this.logger=t,this.eventBus=E.getInstance()}async connect(e,t){if(this.connectionPromise)return this.connectionPromise;if(this.isConnected())return this.logger.info("[SocketService] Already connected"),Promise.resolve();this.currentToken=e,this.connectionPromise=this.doConnect(e,t);try{await this.connectionPromise}finally{this.connectionPromise=null}}doConnect(t,r){return new Promise((r,a)=>{this.logger.info("[SocketService] Connecting to WebSocket..."),this.isManualDisconnect=!1;const i=this.config.wsUrl,n=this.config.wsPath||"/socket.io";this.socket=s(i,{path:n,transports:["polling","websocket"],reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3,timeout:2e4,autoConnect:!1}),this.socket.on("connect",()=>{this.logger.info("[SocketService] Socket connected"),this.reconnectAttempts=0,this.authenticate(t)}),this.socket.on(U,e=>{this.handleBinaryMessage(e,r)}),this.socket.on("connect_error",t=>{this.logger.error("[SocketService] Connect error:",t),this.eventBus.emitEvent(e.IMEventType.ERROR,t),a(t)}),this.socket.on("disconnect",t=>{this.logger.warn("[SocketService] Disconnected:",t),this.stopHeartbeat(),this.isManualDisconnect||this.eventBus.emitEvent(e.IMEventType.DISCONNECT,{reason:t})}),this.socket.on("reconnect_attempt",t=>{this.logger.info("[SocketService] Reconnecting...",t),this.reconnectAttempts=t,this.eventBus.emitEvent(e.IMEventType.RECONNECTING,{attempt:t})}),this.socket.on("reconnect",t=>{this.logger.info("[SocketService] Reconnected after",t,"attempts"),this.authenticate(this.currentToken),this.eventBus.emitEvent(e.IMEventType.RECONNECTED)}),this.socket.on("reconnect_failed",()=>{this.logger.error("[SocketService] Reconnect failed"),this.eventBus.emitEvent(e.IMEventType.ERROR,new Error("Reconnect failed"))}),this.socket.connect(),this.authFlag=!1,setTimeout(()=>{this.authFlag||this.isManualDisconnect||a(new Error("Authentication timeout"))},15e3)})}authenticate(e){var t;const s=O(e);this.logger.debug("[SocketService] Sending auth packet"),null===(t=this.socket)||void 0===t||t.emit(U,s)}handleBinaryMessage(t,s){try{const r=R(t);switch(this.logger.debug("[SocketService] Received packet:",r.header.type,r.payload),r.header.type){case T.CONNECT_ACK:this.handleConnectAck(r.payload,s);break;case T.PONG:this.logger.debug("[SocketService] Heartbeat received");break;case T.MESSAGE:this.handleMessagePacket(r);break;case T.DISCONNECT:this.logger.warn("[SocketService] Server requested disconnect"),this.eventBus.emitEvent(e.IMEventType.KICKED_OFFLINE),this.disconnect();break;default:this.logger.warn("[SocketService] Unknown packet type:",r.header.type)}}catch(e){this.logger.error("[SocketService] Failed to decode packet:",e)}}handleConnectAck(t,s){if(this.authFlag=!0,0===t.status)this.logger.info("[SocketService] Authentication successful"),this.startHeartbeat(),this.eventBus.emitEvent(e.IMEventType.CONNECT_SUCCESS),null==s||s();else{const s=t.errMsg||"Authentication failed";this.logger.error("[SocketService] Authentication failed:",s),this.eventBus.emitEvent(e.IMEventType.ERROR,new Error(s))}}handleMessagePacket(e){var t,s;if(void 0!==e.header.ackId){const r=(s=e.header.ackId,w({header:{version:2,type:T.MESSAGE_ACK,ackId:s}}));null===(t=this.socket)||void 0===t||t.emit(U,r)}this.logger.info("[SocketService] Emitting SOCKET_MESSAGE, cmd:",e.payload.cmd),this.eventBus.emitEvent("SOCKET_MESSAGE",{cmd:e.payload.cmd,data:e.payload.bytes,ackId:e.header.ackId})}disconnect(){this.logger.info("[SocketService] Disconnecting..."),this.isManualDisconnect=!0,this.socket&&(this.stopHeartbeat(),this.socket.disconnect(),this.socket=null)}isConnected(){var e;return(null===(e=this.socket)||void 0===e?void 0:e.connected)||!1}async sendMessage(e,t){if(!this.socket||!this.isConnected())throw new Error("Socket not connected");const s=function(e,t){return w({header:{version:2,type:T.MESSAGE,ackId:null!=t?t:N++},payload:e})}(e,t);this.logger.debug("[SocketService] Sending message packet"),this.socket.emit(U,s)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{var e;if(this.isConnected()){const t=w({header:{version:2,type:T.PING}});null===(e=this.socket)||void 0===e||e.emit(U,t),this.logger.debug("[SocketService] Heartbeat sent")}},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}getStatus(){return{connected:this.isConnected(),reconnectAttempts:this.reconnectAttempts}}}class B{constructor(e,s){this.logQueue=[],this.uploadTimer=null,this.userId=null,this.token=null,this.enabled=!1,this.consecutiveFailures=0,this.maxConsecutiveFailures=3,this.uploadDisabled=!1,this.maxPayloadSize=5e4,this.config=e,this.logger=s,this.enabled=!0===e.enableRemoteLog,this.batchSize=e.remoteLogBatchSize||50,this.uploadInterval=e.remoteLogInterval||3e4,this.clientId=this.generateClientId(),this.sessionId=this.generateSessionId(),this.axiosInstance=t.create({baseURL:`${e.apiBaseUrl}/comind-im-api`,timeout:1e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),e)),this.enabled&&(this.startUploadTimer(),this.setupUnloadHandler())}setToken(e){this.token=e}generateClientId(){const e="undefined"!=typeof localStorage?localStorage.getItem("im_sdk_client_id"):null;if(e)return e;const t="client_"+Date.now()+"_"+Math.random().toString(36).substring(2,11);return"undefined"!=typeof localStorage&&localStorage.setItem("im_sdk_client_id",t),t}generateSessionId(){return"session_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateLogId(){return"log_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateBatchId(){return"batch_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}setUserId(e){this.userId=e}setEnabled(e){this.enabled=e,e&&!this.uploadTimer?this.startUploadTimer():!e&&this.uploadTimer&&this.stopUploadTimer()}log(e){if(!this.enabled)return;const t={id:this.generateLogId(),level:e.level||"info",category:e.category||"system",timestamp:Date.now(),...e,context:{userId:this.userId||void 0,sessionId:this.sessionId,...e.context}};this.logQueue.push(t),this.logQueue.length>=this.batchSize&&this.flush()}info(e,t,s){this.log({level:"info",category:e,message:t,data:s})}warn(e,t,s){this.log({level:"warn",category:e,message:t,data:s})}error(e,t,s,r){this.log({level:"error",category:e,message:t,error:s,data:r,status:"error"})}performance(e,t,s,r){this.log({level:"info",category:"performance",module:e,action:t,status:"success",metrics:{duration:s,...r}})}aiCall(e,t,s,r,a){this.log({level:"error"===r?"error":"info",category:"ai_call",action:e,status:r,data:a,metrics:{tokenCount:t,duration:s}})}startUploadTimer(){this.uploadTimer||(this.uploadTimer=window.setInterval(()=>{this.flush()},this.uploadInterval))}stopUploadTimer(){this.uploadTimer&&(window.clearInterval(this.uploadTimer),this.uploadTimer=null)}setupUnloadHandler(){"undefined"!=typeof window&&(window.addEventListener("beforeunload",()=>{this.flushSync()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushSync()}))}flushSync(){}async flush(){}cleanLogEntry(e){var t,s;const r={...e};if(r.message&&r.message.length>500&&(r.message=r.message.substring(0,500)+"... [truncated]"),r.data){const e=JSON.stringify(r.data);e.length>1e3&&(r.data={_truncated:!0,_originalSize:e.length})}return(null===(t=r.error)||void 0===t?void 0:t.stack)&&r.error.stack.length>500&&(r.error={...r.error,stack:r.error.stack.substring(0,500)+"... [truncated]"}),(null===(s=r.error)||void 0===s?void 0:s.message)&&r.error.message.length>200&&(r.error={...r.error,message:r.error.message.substring(0,200)+"..."}),r}resetUploadState(){this.consecutiveFailures=0,this.uploadDisabled=!1,this.logger.info("[TraceLogService] Upload state reset")}getEnvironment(){if("undefined"!=typeof window){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e)return"development";if(e.includes("staging")||e.includes("test")||e.includes("qa"))return"staging"}return"production"}destroy(){this.flushSync(),this.stopUploadTimer(),this.logQueue=[]}}class q{constructor(e,t,s,r,a){this.apiService=e,this.socketService=t,this.storageService=s,this.fileService=r,this.currentUserId="",this.logger=a,this.eventBus=E.getInstance(),this.setupSocketListeners()}setCurrentUserId(e){this.currentUserId=e}createTextMessage(e){return k.createTextMessage(e)}createImageMessage(e){return k.createImageMessage(e)}createFileMessage(e){return k.createFileMessage(e)}createCustomMessage(e){return k.createCustomMessage(e)}createAudioMessage(e){return k.createAudioMessage(e)}createVideoMessage(e){return k.createVideoMessage(e)}async sendMessage(t){var s,r;this.logger.info("[MessageManager] Sending message:",t.msgId);const a=null===(s=t.extra)||void 0===s?void 0:s.file;try{if(t.from=this.currentUserId,t.status=e.MessageStatus.SENDING,this.eventBus.emitEvent("MESSAGE_SENDING",t),await this.storageService.saveMessage(this.cleanMessageForStorage(t)),(t.msgType===e.MessageType.IMAGE||t.msgType===e.MessageType.FILE||t.msgType===e.MessageType.AUDIO||t.msgType===e.MessageType.VIDEO)&&a){const e=await this.fileService.uploadFile(a,{onProgress:e=>{this.eventBus.emitEvent("UPLOAD_PROGRESS",{msgId:t.msgId,progress:e})}}),s=JSON.parse(t.content);s.url=e.fileUrl,s.fileName=e.fileName,s.fileSize=e.fileSize,t.content=JSON.stringify(s),t.extra||(t.extra={}),t.extra.url=e.fileUrl,delete t.extra.file}const s=A((i=t.content,n=t.conversationId,o=t.conversationType===e.ConversationType.SINGLE?m.SINGLE:m.GROUP,g=t.from,c=t.msgType,d=t.extra||{},l=t.msgId,{cmd:v.CHAT_MESSAGE,type:1,id:l||M(),to:n,chatType:o,content:i,createTimestamp:Date.now(),msgType:c,from:g,data:JSON.stringify(d)}));return await this.socketService.sendMessage(s),t.status=e.MessageStatus.SUCCESS,t.timestamp=Date.now(),await this.storageService.saveMessage(t),this.eventBus.emitEvent(e.IMEventType.MESSAGE_SENT,t),this.logger.info("[MessageManager] Message sent successfully:",t.msgId),this.fetchMessageSeqId(t.conversationId,t.msgId).catch(e=>{this.logger.warn("[MessageManager] Failed to fetch message seqId:",e)}),t}catch(s){throw this.logger.error("[MessageManager] Send message failed:",s),t.status=e.MessageStatus.FAILED,null===(r=t.extra)||void 0===r||delete r.file,await this.storageService.saveMessage(this.cleanMessageForStorage(t)),this.eventBus.emitEvent("MESSAGE_SEND_FAILED",{message:t,error:s}),s}var i,n,o,g,c,d,l}async revokeMessage(t){this.logger.info("[MessageManager] Revoking message:",t.msgId);if(Date.now()-t.timestamp>12e4)throw new Error("Message revoke timeout (2 minutes)");if(t.from!==this.currentUserId)throw new Error("Can only revoke own messages");try{const s=function(e){return A({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType||2,content:"",createTimestamp:e.createTimestamp,msgType:0,from:e.from,data:JSON.stringify({msgId:e.msgId})})}(function(e,t,s,r=2){return{cmd:v.CHAT_MESSAGE,type:3,id:M(),to:t,msgId:e,from:s,chatType:r,createTimestamp:Date.now()}}(t.msgId,t.conversationId,t.from));await this.socketService.sendMessage(s);const r=this.cleanMessageForStorage(t);r.isRevoked=!0,await this.storageService.saveMessage(r),this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,r),this.logger.info("[MessageManager] Message revoked:",t.msgId)}catch(e){throw this.logger.error("[MessageManager] Revoke message failed:",e),e}}cleanMessageForStorage(e){var t;const s=JSON.parse(JSON.stringify(e));return(null===(t=s.extra)||void 0===t?void 0:t.file)&&delete s.extra.file,s}async fetchMessageSeqId(e,t){await new Promise(e=>setTimeout(e,500));try{const s=(await this.apiService.searchRoamingMsg({groupId:e,limitSize:5,syncType:"BACK"})).find(e=>e.id===t||e.msgId===t);s&&s.seqId?(this.logger.info("[MessageManager] Found message seqId from server, msgId:",t,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(t,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t,seqId:s.seqId})):this.logger.warn("[MessageManager] Message not found on server or no seqId, msgId:",t)}catch(e){this.logger.error("[MessageManager] Failed to fetch message seqId:",e)}}async getMessageList(e,t=20,s){this.logger.info("[MessageManager] Getting message list:",e,"lastMsgSeqId:",s);try{const r=(await this.apiService.searchRoamingMsg({groupId:e,msgSeqId:null!=s?s:"",limitSize:t,syncType:"FORWARD"})).map(e=>k.fromServerData(e));r.length>0&&await this.storageService.saveMessages(r);const a=r.length>=t;return r.sort((e,t)=>e.timestamp-t.timestamp),{messages:r,hasMore:a}}catch(s){this.logger.error("[MessageManager] Get message list failed:",s);try{return{messages:await this.storageService.getMessages(e,t),hasMore:!1}}catch(e){throw s}}}async markMessageAsRead(t,s){try{await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:t,seqId:s.seqId}),s.isRead=!0,await this.storageService.saveMessage(s),this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{conversationId:t,message:s})}catch(e){throw this.logger.error("[MessageManager] Mark message as read failed:",e),e}}async sendReadReceipt(t){this.logger.info("[MessageManager] Sending read receipt for message:",t.msgId,"seqId:",t.seqId);try{if(t.from===this.currentUserId)return;if(!t.seqId)return void this.logger.warn("[MessageManager] Message has no seqId, skip read receipt");const s=t.conversationType===e.ConversationType.GROUP,r=function(e,t,s,r,a,i){return{cmd:v.CHAT_MESSAGE,type:2,id:M(),to:e,chatType:r,msgType:a,from:i,groupId:t,seqId:s,createTimestamp:Date.now()}}(s?t.conversationId:t.from,t.conversationId,t.seqId,s?m.GROUP:m.SINGLE,t.msgType,this.currentUserId),a=function(e){return A({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType,content:"",createTimestamp:e.createTimestamp,msgType:e.msgType,from:e.from,data:JSON.stringify({groupId:e.groupId,lastReadSeqId:e.seqId})})}(r);await this.socketService.sendMessage(a),this.logger.info("[MessageManager] Read receipt sent for message:",t.msgId,"seqId:",t.seqId)}catch(e){throw this.logger.error("[MessageManager] Send read receipt failed:",e),e}}async deleteMessage(e){try{await this.storageService.deleteMessage(e.msgId),this.logger.info("[MessageManager] Message deleted:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Delete message failed:",e),e}}setupSocketListeners(){this.eventBus.onEvent("SOCKET_MESSAGE",async t=>{this.logger.debug("[MessageManager] Received socket message:",t);try{const s=t.cmd,r=t.data;if(51===s){const t=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",from:"",to:"",handle:0,seqId:0,chatType:0,msgType:0,content:""};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=b(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 9:t.handle=r;break;case 10:t.seqId=r;break;case 11:t.chatType=r;break;case 12:t.msgType=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=b(e,s);s=n;const o=e.slice(s,s+a),g=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=g;break;case 6:t.data=g;break;case 7:t.from=g;break;case 8:t.to=g;break;case 13:t.content=g}}}}return t}(r);if(this.logger.info("[MessageManager] Decoded C2C message, type:",t.type,"from:",t.from,"to:",t.to,"seqId:",t.seqId),1===t.type){const s=k.fromServerData(t);if(s.from===this.currentUserId)return this.logger.info("[MessageManager] Received own message from server, msgId:",s.msgId,"seqId:",s.seqId,"rawId:",t.id),void(s.seqId&&s.msgId?(this.logger.info("[MessageManager] Updating local message seqId, msgId:",s.msgId,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(s.msgId,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:s.msgId,seqId:s.seqId}),this.logger.info("[MessageManager] MESSAGE_SEQID_UPDATED event emitted")):this.logger.warn("[MessageManager] Missing seqId or msgId, cannot update. seqId:",s.seqId,"msgId:",s.msgId));await this.storageService.saveMessage(s),this.eventBus.emitEvent(e.IMEventType.MESSAGE_RECEIVED,s)}else if(2===t.type||3===t.type){let s="";try{if(t.data){s=JSON.parse(t.data).msgId||""}}catch(e){}if(s||(s=t.id||""),3===t.type){this.logger.debug("[MessageManager] Message revoked:",s);try{await this.storageService.updateMessageRevoked(s,!0)}catch(e){this.logger.error("[MessageManager] Failed to update revoked status in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,{msgId:s,conversationId:t.to})}else{let r=t.seqId,a=t.to;if(t.data)try{const e=JSON.parse(t.data);e.lastReadSeqId&&(r=e.lastReadSeqId),e.groupId&&(a=e.groupId)}catch(e){}if(this.logger.debug("[MessageManager] Message read receipt, seqId:",r,"groupId:",a,"from:",t.from),t.from&&r&&a)try{await this.storageService.updateMessageReadMembersBySeqId(a,r,t.from)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{msgId:s,seqId:r,conversationId:a,from:t.from})}}}else if(53===s){const t=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",broadcast:0,to:"",seqId:0};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=b(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 7:t.broadcast=r;break;case 9:t.seqId=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=b(e,s);s=n;const o=e.slice(s,s+a),g=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=g;break;case 6:t.data=g;break;case 8:t.to=g}}}}return t}(r);if(this.logger.info("[MessageManager] ===== 收到S2C通知消息 ===== cmd=53, type:",t.type,"data:",t.data),2===t.type)try{const e=JSON.parse(t.data);this.logger.info("[MessageManager] New group notification, groupId:",e.groupId),this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"NEW_GROUP",groupId:e.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse new group notification:",e)}else if(1===t.type)this.logger.warn("[MessageManager] Kicked offline notification"),this.eventBus.emitEvent(e.IMEventType.KICKED_OFFLINE);else if(7===t.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"MEMBER_ADDED",data:t.data});else if(8===t.type||11===t.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:8===t.type?"MEMBER_QUIT":"MEMBER_REMOVED",data:t.data});else if(9===t.type)try{const e=JSON.parse(t.data);this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"GROUP_DISMISSED",groupId:e.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse group dismiss notification:",e)}else if(18===t.type||19===t.type)this.eventBus.emitEvent(e.IMEventType.FRIEND_APPLICATION_RECEIVED,t);else if(23===t.type)try{const s=JSON.parse(t.data),{from:r,groupId:a,lastReadSeqId:i}=s;if(this.logger.info("[MessageManager] Received read receipt notification, from:",r,"groupId:",a,"seqId:",i),r&&a&&i)try{await this.storageService.updateMessageReadMembersBySeqId(a,i,r)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{seqId:i,conversationId:a,from:r})}catch(e){this.logger.error("[MessageManager] Failed to parse read receipt notification:",e)}}}catch(e){this.logger.error("[MessageManager] Failed to decode message:",e)}}),this.eventBus.onEvent("SOCKET_RECEIPT",async t=>{3===t.type?(this.logger.debug("[MessageManager] Message revoked:",t.msgId),this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,{msgId:t.msgId,conversationId:t.to})):2===t.type&&(this.logger.debug("[MessageManager] Message read receipt:",t.msgId),this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{msgId:t.msgId,conversationId:t.to}))})}}class K{constructor(e,t,s){this.apiService=e,this.storageService=t,this.conversationMap=new Map,this.currentUserId="",this.logger=s,this.eventBus=E.getInstance(),this.setupMessageListeners()}setCurrentUserId(e){this.currentUserId=e}async getConversationList(t){this.logger.info("[ConversationManager] Getting conversation list");try{const{pageNo:s=1,pageSize:r=100}=t||{},a=await this.apiService.getChatList({pageNo:s,pageSize:r});let i=[];try{const e=await this.apiService.getUnreadMsgList();i=Array.isArray(e)?e:[],this.logger.debug("[ConversationManager] Unread messages:",i.length)}catch(e){this.logger.warn("[ConversationManager] Get unread msg list failed:",e)}const n=new Map;for(const e of i)if(51===e.cmd&&e.from!==this.currentUserId&&3!==e.type&&1!==e.isUndo){const t=e.to,s=n.get(t)||0;n.set(t,s+1)}const o=a.result.map(e=>e.groupId);let g=new Map;try{if(o.length>0){const e=await this.apiService.getOfflineMsg(o,1),t=(null==e?void 0:e.groupList)||[];for(const e of t)e.msgDetail&&e.msgDetail.length>0&&g.set(e.groupId,e.msgDetail[0])}}catch(e){this.logger.warn("[ConversationManager] Get offline msg failed:",e)}const c=a.result.map(t=>{const s=g.get(t.groupId)||t.lastMsg,r=s?this.parseLastMessage(s):void 0,a=t.createTime?new Date(t.createTime).getTime():0,i=t.lastMsgTime||(null==r?void 0:r.timestamp)||a||Date.now(),o={conversationId:t.groupId,conversationType:"SINGLE_CHAT"===t.groupType?e.ConversationType.SINGLE:e.ConversationType.GROUP,displayName:t.displayName||t.name||"",avatarUrl:t.groupImg||"",lastMessage:r,lastMessageTime:i,unreadCount:n.get(t.groupId)||0,isPinned:t.onTop||!1,isHidden:t.hidden||!1,pinnedTime:t.pinnedTime};return this.conversationMap.set(o.conversationId,o),o});c.sort((e,t)=>e.isPinned&&!t.isPinned?-1:!e.isPinned&&t.isPinned?1:(t.lastMessageTime||0)-(e.lastMessageTime||0));for(const e of c)await this.storageService.saveConversation(e);return this.eventBus.emitEvent("CONVERSATION_LIST_UPDATED",c),{total:a.total||c.length,conversations:c}}catch(e){this.logger.error("[ConversationManager] Get conversation list failed:",e);const t=await this.storageService.getConversations();return{total:t.length,conversations:t}}}async getConversation(e){return this.logger.info("[ConversationManager] Getting conversation:",e),this.conversationMap.has(e)?this.conversationMap.get(e):(await this.getConversationList(),this.conversationMap.get(e)||null)}async deleteConversation(e){this.logger.info("[ConversationManager] Deleting conversation:",e);try{await this.apiService.hideGroup({groupId:e}),await this.storageService.deleteConversation(e),this.conversationMap.delete(e),this.eventBus.emitEvent("CONVERSATION_DELETED",{conversationId:e}),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Delete conversation failed:",e),e}}async pinConversation(t,s){this.logger.info("[ConversationManager] Pin conversation:",t,s);try{await this.apiService.onTopGroup({groupId:t,onTop:s});const r=this.conversationMap.get(t);r&&(r.isPinned=s,r.pinnedTime=s?Date.now():void 0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,r)),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Pin conversation failed:",e),e}}getTotalUnreadCount(){let e=0;return this.conversationMap.forEach(t=>{e+=t.unreadCount}),e}async clearUnreadCount(t,s){var r;this.logger.info("[ConversationManager] Clearing unread count:",t,"seqId:",s);try{const a=this.conversationMap.get(t);let i=s;if(i&&0!==i&&""!==i||(i=null===(r=null==a?void 0:a.lastMessage)||void 0===r?void 0:r.seqId),!i||0===i)return this.logger.warn("[ConversationManager] No valid seqId found, skip clearing unread count"),void(a&&(a.unreadCount=0,await this.storageService.saveConversation(a),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,a)));await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:t,seqId:i}),a&&(a.unreadCount=0,await this.storageService.saveConversation(a),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,a))}catch(e){throw this.logger.error("[ConversationManager] Clear unread count failed:",e),e}}async updateConversationLastMessage(t){this.logger.debug("[ConversationManager] Updating conversation last message:",t.msgId);try{let s=this.conversationMap.get(t.conversationId);if(s){s.lastMessage=t,s.lastMessageTime=t.timestamp;this.currentUserId&&t.from===this.currentUserId||t.isRead||s.unreadCount++}else{const r=this.currentUserId&&t.from===this.currentUserId;let a=t.fromUserName||t.conversationId,i=t.fromUserImg||"";if(t.conversationType===e.ConversationType.GROUP)try{const e=await this.apiService.getGroupBaseInfo({groupId:t.conversationId});a=e.name||e.displayName||t.conversationId,i=e.groupImg||"",this.logger.debug("[ConversationManager] Got group info for new conversation:",a)}catch(e){this.logger.warn("[ConversationManager] Failed to get group info:",e)}s={conversationId:t.conversationId,conversationType:t.conversationType,displayName:a,avatarUrl:i,lastMessage:t,lastMessageTime:t.timestamp,unreadCount:r?0:1,isPinned:!1,isHidden:!1},this.conversationMap.set(s.conversationId,s)}await this.storageService.saveConversation(s),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,s)}catch(e){this.logger.error("[ConversationManager] Update conversation last message failed:",e)}}parseLastMessage(t){if(t)return{msgId:t.id||t.msgId||"",conversationId:t.to||t.groupId||"",conversationType:1===t.chatType?e.ConversationType.SINGLE:e.ConversationType.GROUP,from:t.from||"",fromUserName:t.fromUserName,fromUserImg:t.fromUserImg,content:t.content||"",msgType:t.msgType||0,status:1,seqId:t.seqId||0,timestamp:t.createTimestamp||t.createTime||0,isRead:!1}}setupMessageListeners(){this.eventBus.onEvent(e.IMEventType.MESSAGE_RECEIVED,async e=>{await this.updateConversationLastMessage(e)}),this.eventBus.onEvent(e.IMEventType.MESSAGE_SENT,async e=>{await this.updateConversationLastMessage(e)})}}class z{constructor(e,t){this.apiService=e,this.logger=t,this.eventBus=E.getInstance(),this.setupGroupListeners()}async createGroup(e){this.logger.info("[GroupManager] Creating group");try{const t=await this.apiService.createGroup({groupType:e.groupType,userIdList:e.userIdList,name:e.groupName,groupImg:e.groupAvatar}),s=await this.getGroupInfo(t.groupId);return this.eventBus.emitEvent("GROUP_CREATED",s),s}catch(e){throw this.logger.error("[GroupManager] Create group failed:",e),e}}async getGroupInfo(e){this.logger.info("[GroupManager] Getting group info:",e);try{const t=await this.apiService.getGroupBaseInfo({groupId:e});return{groupId:t.groupId,groupType:t.groupType,groupName:t.name||t.displayName,groupAvatar:t.groupImg,notice:t.notice,ownerId:t.owner,memberCount:t.memberCurrent,maxMemberCount:t.memberLimit,createTime:t.createTime}}catch(e){throw this.logger.error("[GroupManager] Get group info failed:",e),e}}async updateGroupInfo(e){this.logger.info("[GroupManager] Updating group info:",e.groupId);try{await this.apiService.updateGroupBaseInfo({groupId:e.groupId,name:e.groupName,groupImg:e.groupAvatar,notice:e.notice}),this.eventBus.emitEvent("GROUP_INFO_UPDATED",{groupId:e.groupId})}catch(e){throw this.logger.error("[GroupManager] Update group info failed:",e),e}}async getGroupMemberList(e){this.logger.info("[GroupManager] Getting group member list:",e.groupId);try{const[t,s]=await Promise.all([this.apiService.getGroupBaseInfo({groupId:e.groupId}),this.apiService.getGroupMemberList({groupId:e.groupId,pageNo:e.pageNo,pageSize:e.pageSize})]),r=t.owner,a=null==r?void 0:r.toLowerCase();return{total:s.total,members:s.result.map(e=>{var t;return{userId:e.userId,userName:e.userName,userAvatar:e.userImg,groupNickname:e.groupNickName,role:(null===(t=e.userId)||void 0===t?void 0:t.toLowerCase())===a?0:1===e.isGroupManager?1:2,joinTime:e.joinTime}})}}catch(e){throw this.logger.error("[GroupManager] Get group member list failed:",e),e}}async addGroupMembers(e,t){this.logger.info("[GroupManager] Adding group members:",e,t);try{await this.apiService.addGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_JOINED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Add group members failed:",e),e}}async removeGroupMembers(e,t){this.logger.info("[GroupManager] Removing group members:",e,t);try{await this.apiService.removeGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_REMOVED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Remove group members failed:",e),e}}async quitGroup(e){this.logger.info("[GroupManager] Quitting group:",e);try{await this.apiService.quitGroup({groupId:e}),this.eventBus.emitEvent("MEMBER_QUIT",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Quit group failed:",e),e}}async dismissGroup(e){this.logger.info("[GroupManager] Dismissing group:",e);try{await this.apiService.dismissGroup({groupId:e}),this.eventBus.emitEvent("GROUP_DISMISSED",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Dismiss group failed:",e),e}}setupGroupListeners(){this.eventBus.onEvent("SOCKET_GROUP_NOTIFICATION",t=>{this.logger.debug("[GroupManager] Group notification:",t),this.eventBus.emitEvent(e.IMEventType.GROUP_NOTIFICATION,t)})}}class V{constructor(e,t){this.apiService=e,this.logger=t}async getCurrentUserInfo(){return this.getUserInfo()}async getUserInfo(e){this.logger.info("[UserManager] Getting user info:",e);try{const t=await this.apiService.getUserInfo({userId:e});return{userId:t.userId,userName:t.userName,userImg:t.userImg,companyName:t.companyName,imRole:t.imRole}}catch(e){throw this.logger.error("[UserManager] Get user info failed:",e),e}}async updateUserInfo(e){this.logger.info("[UserManager] Updating user info:",e.userId);try{await this.apiService.updateUserInfo(e)}catch(e){throw this.logger.error("[UserManager] Update user info failed:",e),e}}async getBlacklist(e=1,t=100){this.logger.info("[UserManager] Getting blacklist");try{return(await this.apiService.getBlacklist({pageNo:e,pageSize:t})).result.map(e=>({userId:e.userId,userName:e.userName,userImg:e.userImg}))}catch(e){throw this.logger.error("[UserManager] Get blacklist failed:",e),e}}async addToBlacklist(e){this.logger.info("[UserManager] Adding to blacklist:",e);try{await this.apiService.addToBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Add to blacklist failed:",e),e}}async removeFromBlacklist(e){this.logger.info("[UserManager] Removing from blacklist:",e);try{await this.apiService.removeFromBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Remove from blacklist failed:",e),e}}async getUserPrivacy(e){this.logger.info("[UserManager] Getting user privacy:",e);try{const t=await this.apiService.getUserPrivacy({userId:e});return{isSetAuth:t.isSetAuth||0,isChatStranger:t.isChatStranger||0}}catch(e){throw this.logger.error("[UserManager] Get user privacy failed:",e),e}}async updatePrivacy(e,t){this.logger.info("[UserManager] Updating user privacy:",e,t);try{await this.apiService.updatePrivacy({userId:e,...t})}catch(e){throw this.logger.error("[UserManager] Update user privacy failed:",e),e}}async changePassword(e,t){this.logger.info("[UserManager] Changing password");try{await this.apiService.changePassword({oldPassword:e,newPassword:t}),this.logger.info("[UserManager] Password changed successfully")}catch(e){throw this.logger.error("[UserManager] Change password failed:",e),e}}}class j{constructor(e,t){this.apiService=e,this.currentUserId="",this.logger=t,this.eventBus=E.getInstance(),this.setupFriendListeners()}setCurrentUserId(e){this.currentUserId=e}async getFriendList(){this.logger.info("[FriendManager] Getting friend list");try{const e=await this.apiService.getFriendList({userId:this.currentUserId}),t=[],s=(null==e?void 0:e.jsonData)||e||[];if(Array.isArray(s))for(const e of s)if(e.friendList&&Array.isArray(e.friendList))for(const s of e.friendList)t.push({userId:s.friendUserId||s.userId,userName:s.friendUserName||s.userName,userImg:s.friendUserImg||s.userImg});return t}catch(e){throw this.logger.error("[FriendManager] Get friend list failed:",e),e}}async getFriendApplicationList(){this.logger.info("[FriendManager] Getting friend application list");try{const e=await this.apiService.getFriendRequestList({userId:this.currentUserId}),t=Array.isArray(e)?e:(null==e?void 0:e.jsonData)||(null==e?void 0:e.result)||[];this.logger.debug("[FriendManager] Friend request list raw data:",t),this.logger.debug("[FriendManager] Current user ID:",this.currentUserId);const s=this.currentUserId.toLowerCase(),r=t.filter(e=>{var t;return(null===(t=e.friendUserId)||void 0===t?void 0:t.toLowerCase())===s});return this.logger.debug("[FriendManager] Incoming requests after filter:",r),r.map(e=>({requestId:e.requestId,userId:e.requestUserId,userName:e.friendUserName||e.requestUserId,userAvatar:e.friendUserImg,applyMessage:e.requestReason,createTime:e.requestTime,status:e.requestStatus}))}catch(e){throw this.logger.error("[FriendManager] Get friend application list failed:",e),e}}async addFriend(e,t,s){this.logger.info("[FriendManager] Adding friend:",e);try{const r=await this.apiService.addFriend({friendUserId:e,requestUserId:this.currentUserId,requestReason:t,requestRemark:s});return this.eventBus.emitEvent("FRIEND_APPLICATION_SENT",{friendUserId:e,requestReason:t}),r}catch(e){throw this.logger.error("[FriendManager] Add friend failed:",e),e}}async acceptFriendApplication(t){this.logger.info("[FriendManager] Accepting friend application:",t);try{const s=await this.apiService.agreeFriendRequest({requestId:t});return this.eventBus.emitEvent(e.IMEventType.FRIEND_ADDED,{requestId:t}),s}catch(e){throw this.logger.error("[FriendManager] Accept friend application failed:",e),e}}async deleteFriend(t){this.logger.info("[FriendManager] Deleting friend:",t);try{await this.apiService.deleteFriend({userId:this.currentUserId,friendUserId:t}),this.eventBus.emitEvent(e.IMEventType.FRIEND_DELETED,{friendUserId:t})}catch(e){throw this.logger.error("[FriendManager] Delete friend failed:",e),e}}setupFriendListeners(){this.eventBus.onEvent("SOCKET_FRIEND_NOTIFICATION",t=>{switch(this.logger.debug("[FriendManager] Friend notification:",t),t.type){case"friend_request":this.eventBus.emitEvent(e.IMEventType.FRIEND_APPLICATION_RECEIVED,t);break;case"friend_added":this.eventBus.emitEvent(e.IMEventType.FRIEND_ADDED,t);break;case"friend_deleted":this.eventBus.emitEvent(e.IMEventType.FRIEND_DELETED,t);break;default:this.logger.warn("[FriendManager] Unknown friend notification type:",t.type)}})}}class W{constructor(t){if(this.logger=l.getInstance(),this.eventBus=E.getInstance(),this.configManager=new u(t),this.stateManager=new h,void 0!==t.logLevel){const s="string"==typeof t.logLevel?e.LogLevel[t.logLevel]:t.logLevel;this.logger.setLevel(s)}!1===t.enableLog&&this.logger.setEnabled(!1),this.apiService=new G(t,this.logger),this.socketService=new x(t,this.logger),this.storageService=new F(this.logger),this.fileService=new P(this.apiService,this.logger),this.traceLogService=new B(t,this.logger),this.message=new q(this.apiService,this.socketService,this.storageService,this.fileService,this.logger),this.conversation=new K(this.apiService,this.storageService,this.logger),this.group=new z(this.apiService,this.logger),this.user=new V(this.apiService,this.logger),this.friend=new j(this.apiService,this.logger),this.logger.info("[IMSDK] SDK initialized")}static create(e){return W.instance||(W.instance=new W(e)),W.instance}static getInstance(){return W.instance}async login(t){this.logger.info("[IMSDK] Logging in:",t.userId);try{let s=t.token,r=0;if(!s){const e=await this.apiService.getToken({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userId:t.userId,userName:t.userName,userAvatar:t.userAvatar});s=e.token,r=e.expireIn}return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setUserId(t.userId),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.traceLogService.setUserId(t.userId),this.message.setCurrentUserId(t.userId),this.conversation.setCurrentUserId(t.userId),this.friend.setCurrentUserId(t.userId),await this.storageService.init(),await this.socketService.connect(s,t.userId),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userId,token:s,expireTime:r}),this.logger.info("[IMSDK] Login successful"),{userId:t.userId,token:s,expireTime:r}}catch(t){throw this.logger.error("[IMSDK] Login failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async register(t){this.logger.info("[IMSDK] Registering user:",t.userName);try{const s=await this.apiService.registerWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:t.userName,password:t.password,userAvatar:t.userAvatar,companyName:t.companyName}),r=s.token,a=s.expireIn;return this.apiService.setToken(r),this.stateManager.setToken(r),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(r),this.message.setCurrentUserId(t.userName),this.conversation.setCurrentUserId(t.userName),this.friend.setCurrentUserId(t.userName),await this.storageService.init(),await this.socketService.connect(r,t.userName),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userName,token:r,expireTime:a}),this.logger.info("[IMSDK] Registration and login successful"),{userId:t.userName,token:r,expireTime:a}}catch(t){throw this.logger.error("[IMSDK] Registration failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async loginWithPassword(t){this.logger.info("[IMSDK] Logging in with password:",t.userName);try{const s=await this.apiService.loginWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:t.userName,password:t.password}),r=s.token,a=s.expireIn;return this.apiService.setToken(r),this.stateManager.setToken(r),this.stateManager.setUserId(t.userName),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(r),this.traceLogService.setUserId(t.userName),this.message.setCurrentUserId(t.userName),this.conversation.setCurrentUserId(t.userName),this.friend.setCurrentUserId(t.userName),await this.storageService.init(),await this.socketService.connect(r,t.userName),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userName,token:r,expireTime:a}),this.logger.info("[IMSDK] Login with password successful"),{userId:t.userName,token:r,expireTime:a}}catch(t){throw this.logger.error("[IMSDK] Login with password failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async logout(){this.logger.info("[IMSDK] Logging out");try{this.socketService.disconnect(),this.stateManager.clear(),this.apiService.setToken(null),this.traceLogService.setToken(null),this.traceLogService.setUserId(null),this.eventBus.emitEvent(e.IMEventType.LOGOUT),this.logger.info("[IMSDK] Logout successful")}catch(e){throw this.logger.error("[IMSDK] Logout failed:",e),e}}destroy(){this.logger.info("[IMSDK] Destroying SDK instance"),this.isLoggedIn()&&this.logout().catch(()=>{}),this.eventBus.removeAllListeners(),this.traceLogService.destroy(),W.instance=null,this.logger.info("[IMSDK] SDK instance destroyed")}isLoggedIn(){return this.stateManager.isLoggedIn()}getCurrentUserId(){return this.stateManager.getUserId()}getConnectionStatus(){return this.socketService.getStatus()}on(e,t){this.eventBus.onEvent(e,t)}off(e,t){this.eventBus.offEvent(e,t)}once(e,t){this.eventBus.once(e,t)}setLogLevel(e){this.logger.setLevel(e)}setLogEnabled(e){this.logger.setEnabled(e)}static getVersion(){return"1.0.0"}getTraceLogService(){return this.traceLogService}async uploadFile(e,t){return this.fileService.uploadFile(e,{onProgress:t})}}W.instance=null,e.EventBus=E,e.IMError=d,e.IMSDK=W,e.Logger=l,e.TraceLogService=B,e.createIMSDK=function(e){return W.create(e)},e.default=W,e.formatDate=L,e.formatRelativeTime=function(e){if(!e)return"";let t;if(e instanceof Date)t=e;else if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);if(isNaN(t.getTime()))return String(e);const s=new Date,r=s.getTime()-t.getTime();return r<0||r>31536e6?L(t,"YYYY/MM/DD"):r<6e4?"刚刚":r<36e5?`${Math.floor(r/6e4)}分钟前`:r<864e5?t.getDate()===s.getDate()&&t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear()?`今天 ${L(t,"HH:mm")}`:`昨天 ${L(t,"HH:mm")}`:r<6048e5?`${Math.floor(r/864e5)}天前`:t.getFullYear()===s.getFullYear()?L(t,"MM/DD"):L(t,"YYYY/MM/DD")},e.parseDate=function(e){if(!e)return null;let t;if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);return isNaN(t.getTime())?null:t},Object.defineProperty(e,"__esModule",{value:!0})});
@@ -0,0 +1 @@
1
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports,require("axios"),require("socket.io-client")):"function"==typeof define&&define.amd?define(["exports","axios","socket.io-client"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).ComindIMSDK={},e.axios,e.io)}(this,function(e,t,s){"use strict";var r,a,i,n,o,g,c;e.LogLevel=void 0,(r=e.LogLevel||(e.LogLevel={}))[r.VERBOSE=0]="VERBOSE",r[r.DEBUG=1]="DEBUG",r[r.INFO=2]="INFO",r[r.WARN=3]="WARN",r[r.ERROR=4]="ERROR",r[r.NONE=5]="NONE",e.ConversationType=void 0,(a=e.ConversationType||(e.ConversationType={}))[a.SINGLE=1]="SINGLE",a[a.GROUP=2]="GROUP",e.MessageType=void 0,(i=e.MessageType||(e.MessageType={}))[i.TEXT=0]="TEXT",i[i.FILE=1]="FILE",i[i.IMAGE=2]="IMAGE",i[i.VOICE=4]="VOICE",i[i.AUDIO=5]="AUDIO",i[i.VIDEO=6]="VIDEO",i[i.AT_TEXT=8]="AT_TEXT",i[i.CUSTOM=9]="CUSTOM",e.MessageStatus=void 0,(n=e.MessageStatus||(e.MessageStatus={}))[n.SENDING=0]="SENDING",n[n.SUCCESS=1]="SUCCESS",n[n.FAILED=2]="FAILED",e.IMErrorCode=void 0,(o=e.IMErrorCode||(e.IMErrorCode={}))[o.SUCCESS=0]="SUCCESS",o[o.UNKNOWN_ERROR=1e3]="UNKNOWN_ERROR",o[o.NETWORK_ERROR=1001]="NETWORK_ERROR",o[o.INVALID_PARAMETER=1002]="INVALID_PARAMETER",o[o.NOT_INITIALIZED=1003]="NOT_INITIALIZED",o[o.NOT_LOGGED_IN=1004]="NOT_LOGGED_IN",o[o.ALREADY_LOGGED_IN=1005]="ALREADY_LOGGED_IN",o[o.LOGIN_FAILED=2e3]="LOGIN_FAILED",o[o.TOKEN_EXPIRED=2001]="TOKEN_EXPIRED",o[o.TOKEN_INVALID=2002]="TOKEN_INVALID",o[o.USER_NOT_EXIST=2003]="USER_NOT_EXIST",o[o.MESSAGE_SEND_FAILED=3e3]="MESSAGE_SEND_FAILED",o[o.MESSAGE_REVOKE_TIMEOUT=3001]="MESSAGE_REVOKE_TIMEOUT",o[o.MESSAGE_NOT_FOUND=3002]="MESSAGE_NOT_FOUND",o[o.GROUP_NOT_EXIST=4e3]="GROUP_NOT_EXIST",o[o.GROUP_MEMBER_LIMIT=4001]="GROUP_MEMBER_LIMIT",o[o.NOT_GROUP_MEMBER=4002]="NOT_GROUP_MEMBER",o[o.NO_PERMISSION=4003]="NO_PERMISSION",o[o.GROUP_DISMISSED=4004]="GROUP_DISMISSED",o[o.FRIEND_NOT_EXIST=5e3]="FRIEND_NOT_EXIST",o[o.FRIEND_ALREADY_EXIST=5001]="FRIEND_ALREADY_EXIST",o[o.FILE_UPLOAD_FAILED=6e3]="FILE_UPLOAD_FAILED",o[o.FILE_DOWNLOAD_FAILED=6001]="FILE_DOWNLOAD_FAILED",o[o.FILE_SIZE_LIMIT=6002]="FILE_SIZE_LIMIT",o[o.FILE_TYPE_NOT_ALLOWED=6003]="FILE_TYPE_NOT_ALLOWED";class d extends Error{constructor(t,s,r){super(s),this.name="IMError",this.code="string"==typeof t?e.IMErrorCode.UNKNOWN_ERROR:t,this.detail=r,Object.setPrototypeOf(this,d.prototype)}}e.IMEventType=void 0,(g=e.IMEventType||(e.IMEventType={})).CONNECT_SUCCESS="CONNECT_SUCCESS",g.DISCONNECT="DISCONNECT",g.RECONNECTING="RECONNECTING",g.RECONNECTED="RECONNECTED",g.LOGIN_SUCCESS="LOGIN_SUCCESS",g.LOGIN_FAILED="LOGIN_FAILED",g.LOGOUT="LOGOUT",g.KICKED_OFFLINE="KICKED_OFFLINE",g.MESSAGE_RECEIVED="MESSAGE_RECEIVED",g.MESSAGE_SENT="MESSAGE_SENT",g.MESSAGE_REVOKED="MESSAGE_REVOKED",g.MESSAGE_READ="MESSAGE_READ",g.CONVERSATION_UPDATED="CONVERSATION_UPDATED",g.GROUP_NOTIFICATION="GROUP_NOTIFICATION",g.FRIEND_NOTIFICATION="FRIEND_NOTIFICATION",g.FRIEND_ADDED="FRIEND_ADDED",g.FRIEND_DELETED="FRIEND_DELETED",g.FRIEND_APPLICATION_RECEIVED="FRIEND_APPLICATION_RECEIVED",g.ERROR="ERROR",e.SocketEventType=void 0,(c=e.SocketEventType||(e.SocketEventType={})).CONNECT="connect",c.DISCONNECT="disconnect",c.CONNECT_ERROR="connect_error",c.RECONNECT_ATTEMPT="reconnect_attempt",c.RECONNECT="reconnect",c.RECONNECT_FAILED="reconnect_failed",c.ERROR="error",c.MESSAGE="message",c.GROUP_NOTIFICATION="group_notification",c.FRIEND_NOTIFICATION="friend_notification";class l{constructor(){this.level=e.LogLevel.INFO,this.enabled=!0}static getInstance(){return l.instance||(l.instance=new l),l.instance}setLevel(t){this.level="string"==typeof t?e.LogLevel[t]||e.LogLevel.INFO:t}setEnabled(e){this.enabled=e}verbose(...t){this.log(e.LogLevel.VERBOSE,...t)}debug(...t){this.log(e.LogLevel.DEBUG,...t)}info(...t){this.log(e.LogLevel.INFO,...t)}warn(...t){this.log(e.LogLevel.WARN,...t)}error(...t){this.log(e.LogLevel.ERROR,...t)}log(t,...s){if(!this.enabled||t<this.level)return;(new Date).toISOString(),e.LogLevel[t];switch(t){case e.LogLevel.ERROR:case e.LogLevel.WARN:}}}l.instance=null;class u{constructor(e){this.config=null,e&&(this.config=e)}setConfig(e){this.config=e}getConfig(){if(!this.config)throw new Error("SDK not initialized");return this.config}getAppId(){return this.getConfig().appId}getAppSecret(){return this.getConfig().appSecret}getApiBaseUrl(){return this.getConfig().apiBaseUrl}getWsUrl(){return this.getConfig().wsUrl}getWsPath(){return this.getConfig().wsPath||"/socket.io"}}class h{constructor(){this.isLoggedInFlag=!1,this.userId=null,this.token=null}setLoginStatus(e){this.isLoggedInFlag=e}isLoggedIn(){return this.isLoggedInFlag}setUserId(e){this.userId=e;try{localStorage.setItem("im_userId",e)}catch(e){}}getUserId(){return this.userId}setToken(e){this.token=e;try{localStorage.setItem("im_token",e)}catch(e){}}getToken(){return this.token}loadToken(){try{const e=localStorage.getItem("im_token");return e&&(this.token=e),e}catch(e){return null}}loadUserId(){try{const e=localStorage.getItem("im_userId");return e&&(this.userId=e),e}catch(e){return null}}clear(){this.isLoggedInFlag=!1,this.userId=null,this.token=null;try{localStorage.removeItem("im_token"),localStorage.removeItem("im_userId")}catch(e){}}}function p(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}var I={exports:{}};!function(e){var t=Object.prototype.hasOwnProperty,s="~";function r(){}function a(e,t,s){this.fn=e,this.context=t,this.once=s||!1}function i(e,t,r,i,n){if("function"!=typeof r)throw new TypeError("The listener must be a function");var o=new a(r,i||e,n),g=s?s+t:t;return e._events[g]?e._events[g].fn?e._events[g]=[e._events[g],o]:e._events[g].push(o):(e._events[g]=o,e._eventsCount++),e}function n(e,t){0===--e._eventsCount?e._events=new r:delete e._events[t]}function o(){this._events=new r,this._eventsCount=0}Object.create&&(r.prototype=Object.create(null),(new r).__proto__||(s=!1)),o.prototype.eventNames=function(){var e,r,a=[];if(0===this._eventsCount)return a;for(r in e=this._events)t.call(e,r)&&a.push(s?r.slice(1):r);return Object.getOwnPropertySymbols?a.concat(Object.getOwnPropertySymbols(e)):a},o.prototype.listeners=function(e){var t=s?s+e:e,r=this._events[t];if(!r)return[];if(r.fn)return[r.fn];for(var a=0,i=r.length,n=new Array(i);a<i;a++)n[a]=r[a].fn;return n},o.prototype.listenerCount=function(e){var t=s?s+e:e,r=this._events[t];return r?r.fn?1:r.length:0},o.prototype.emit=function(e,t,r,a,i,n){var o=s?s+e:e;if(!this._events[o])return!1;var g,c,d=this._events[o],l=arguments.length;if(d.fn){switch(d.once&&this.removeListener(e,d.fn,void 0,!0),l){case 1:return d.fn.call(d.context),!0;case 2:return d.fn.call(d.context,t),!0;case 3:return d.fn.call(d.context,t,r),!0;case 4:return d.fn.call(d.context,t,r,a),!0;case 5:return d.fn.call(d.context,t,r,a,i),!0;case 6:return d.fn.call(d.context,t,r,a,i,n),!0}for(c=1,g=new Array(l-1);c<l;c++)g[c-1]=arguments[c];d.fn.apply(d.context,g)}else{var u,h=d.length;for(c=0;c<h;c++)switch(d[c].once&&this.removeListener(e,d[c].fn,void 0,!0),l){case 1:d[c].fn.call(d[c].context);break;case 2:d[c].fn.call(d[c].context,t);break;case 3:d[c].fn.call(d[c].context,t,r);break;case 4:d[c].fn.call(d[c].context,t,r,a);break;default:if(!g)for(u=1,g=new Array(l-1);u<l;u++)g[u-1]=arguments[u];d[c].fn.apply(d[c].context,g)}}return!0},o.prototype.on=function(e,t,s){return i(this,e,t,s,!1)},o.prototype.once=function(e,t,s){return i(this,e,t,s,!0)},o.prototype.removeListener=function(e,t,r,a){var i=s?s+e:e;if(!this._events[i])return this;if(!t)return n(this,i),this;var o=this._events[i];if(o.fn)o.fn!==t||a&&!o.once||r&&o.context!==r||n(this,i);else{for(var g=0,c=[],d=o.length;g<d;g++)(o[g].fn!==t||a&&!o[g].once||r&&o[g].context!==r)&&c.push(o[g]);c.length?this._events[i]=1===c.length?c[0]:c:n(this,i)}return this},o.prototype.removeAllListeners=function(e){var t;return e?(t=s?s+e:e,this._events[t]&&n(this,t)):(this._events=new r,this._eventsCount=0),this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prefixed=s,o.EventEmitter=o,e.exports=o}(I);var v,m,S,f=p(I.exports);class E extends f{constructor(){super()}static getInstance(){return E.instance||(E.instance=new E),E.instance}emitEvent(e,t){this.emit(e,t)}onEvent(e,t){this.on(e,t)}offEvent(e,t){t?this.off(e,t):this.removeAllListeners(e)}onceEvent(e,t){this.once(e,t)}clearAll(){this.removeAllListeners()}}function M(){return"undefined"!=typeof crypto&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{const t=16*Math.random()|0;return("x"===e?t:3&t|8).toString(16)})}E.instance=null,function(e){e[e.CONNECT=1]="CONNECT",e[e.CONNECT_ACK=2]="CONNECT_ACK",e[e.PING=10]="PING",e[e.PONG=11]="PONG",e[e.GROUP_NOTIFICATION=20]="GROUP_NOTIFICATION",e[e.FRIEND_NOTIFICATION=30]="FRIEND_NOTIFICATION",e[e.CHAT_MESSAGE=51]="CHAT_MESSAGE",e[e.RECEIPT_MESSAGE=52]="RECEIPT_MESSAGE",e[e.KICK_OFF=99]="KICK_OFF"}(v||(v={})),function(e){e[e.SINGLE=1]="SINGLE",e[e.GROUP=2]="GROUP"}(m||(m={})),function(e){e[e.DESC=1]="DESC",e[e.ASC=2]="ASC"}(S||(S={}));const y=104857600;var T;!function(e){e[e.UNKNOW_REQ=0]="UNKNOW_REQ",e[e.PING=1]="PING",e[e.PONG=2]="PONG",e[e.CONNECT=3]="CONNECT",e[e.CONNECT_ACK=4]="CONNECT_ACK",e[e.DISCONNECT=5]="DISCONNECT",e[e.Reserved=6]="Reserved",e[e.MESSAGE=7]="MESSAGE",e[e.MESSAGE_ACK=8]="MESSAGE_ACK"}(T||(T={}));let N=Math.floor(1e4*Math.random());function w(e){const t=function(e){const t=null!=e.ackId?6:2,s=new ArrayBuffer(t),r=new DataView(s);return r.setUint8(0,e.version),r.setUint8(1,e.type),null!=e.ackId&&r.setUint32(2,e.ackId),r}(e.header),s=function(e){if(null==e)return null;const t=new ArrayBuffer(e.byteLength),s=new DataView(t);for(let t=0;t<e.byteLength;t++)s.setUint8(t,e[t]);return s}(e.payload||null);let r=t.byteLength;null!=s&&(r+=s.byteLength);const a=new ArrayBuffer(r),i=new DataView(a);for(let e=0;e<t.byteLength;e++)i.setUint8(e,t.getUint8(e));if(null!=s)for(let e=0;e<s.byteLength;e++)i.setUint8(e+t.byteLength,s.getUint8(e));return a}function C(e){const t=[];for(;e>127;)t.push(127&e|128),e>>>=7;return t.push(127&e),t}function D(e,t){return C(e<<3|t)}function O(e){const t=function(e){const t=[];if(t.push(...D(1,0)),t.push(...C(e.cmd)),e.token.length>0){const s=(new TextEncoder).encode(e.token);t.push(...D(2,2)),t.push(...C(s.length)),t.push(...Array.from(s))}return t.push(...D(3,0)),t.push(...C(e.clientType)),new Uint8Array(t)}({cmd:3,token:e,clientType:1});return w({header:{version:2,type:T.CONNECT},payload:t})}function _(e){const t=new DataView(new Uint8Array(e).buffer),s=t.getUint8(0);let r=null;if(0!==s&&t.byteLength>1){r=function(e){if("string"==typeof e)return e;let t="";for(let s=0;s<e.length;s++){const r=e[s].toString(2),a=r.match(/^1+?(?=0)/);if(a&&8===r.length){const r=a[0].length;let i=e[s].toString(2).slice(7-r);for(let t=1;t<r;t++)i+=e[t+s].toString(2).slice(2);t+=String.fromCharCode(parseInt(i,2)),s+=r-1}else t+=String.fromCharCode(e[s])}return t}(e.slice(1))}return{status:s,errMsg:r}}function R(e){const t=Array.from(new Uint8Array(e)),s=function(e){const t=e.getUint8(0),s=e.getUint8(1);let r;return s!==T.MESSAGE&&s!==T.MESSAGE_ACK||(r=e.getUint32(2)),{version:t,type:s,ackId:r}}(new DataView(new Uint8Array(t).buffer));let r=2;s.type!==T.MESSAGE&&s.type!==T.MESSAGE_ACK||(r+=4);const a=t.slice(r);let i=null;return s.type===T.CONNECT_ACK?i=_(a):s.type===T.MESSAGE&&(i=function(e){let t=0;if(e.length>=2&&8===e[0]){let s,r=1,a=0;do{s=e[r++],t|=(127&s)<<a,a+=7}while(s>=128&&r<e.length)}return{cmd:t,bytes:e}}(a)),{header:s,payload:i}}function A(e){const t=[];if(0!==e.cmd&&(t.push(...D(1,0)),t.push(...C(e.cmd))),e.id.length>0){const s=(new TextEncoder).encode(e.id);t.push(...D(2,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(0!==e.createTimestamp&&(t.push(...D(3,0)),t.push(...function(e){const t=[];for(;e>127;)t.push(127&e|128),e=Math.floor(e/128);return t.push(127&e),t}(e.createTimestamp))),0!==e.type&&(t.push(...D(4,0)),t.push(...C(e.type))),e.data&&e.data.length>0){const s=(new TextEncoder).encode(e.data);t.push(...D(6,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(e.from.length>0){const s=(new TextEncoder).encode(e.from);t.push(...D(7,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(e.to.length>0){const s=(new TextEncoder).encode(e.to);t.push(...D(8,2)),t.push(...C(s.length)),t.push(...Array.from(s))}if(0!==e.chatType&&(t.push(...D(11,0)),t.push(...C(e.chatType))),0!==e.msgType&&(t.push(...D(12,0)),t.push(...C(e.msgType))),e.content.length>0){const s=(new TextEncoder).encode(e.content);t.push(...D(13,2)),t.push(...C(s.length)),t.push(...Array.from(s))}return new Uint8Array(t)}function b(e,t){let s,r=0,a=0;do{s=e[t++],r|=(127&s)<<a,a+=7}while(s>=128&&t<e.length);return{value:r,newOffset:t}}const U="imchat";function L(e,t="YYYY-MM-DD HH:mm:ss"){if(!e)return"";let s;if(e instanceof Date)s=e;else if("string"==typeof e){const t=e.replace(/-/g,"/").replace(" ","T")+"Z";s=new Date(t),isNaN(s.getTime())&&(s=new Date(e.replace(/-/g,"/")))}else s=new Date(e);if(isNaN(s.getTime()))return String(e);const r=s.getFullYear(),a=s.getMonth()+1,i=s.getDate(),n=s.getHours(),o=s.getMinutes(),g=s.getSeconds();return t.replace("YYYY",String(r)).replace("MM",String(a).padStart(2,"0")).replace("DD",String(i).padStart(2,"0")).replace("HH",String(n).padStart(2,"0")).replace("mm",String(o).padStart(2,"0")).replace("ss",String(g).padStart(2,"0"))}class k{static createTextMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:a.text,msgType:e.MessageType.TEXT,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{msgdata:"txt"}}}static createImageMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type}),msgType:e.MessageType.IMAGE,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,msgdata:"img"}}}static createFileMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type}),msgType:e.MessageType.FILE,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,msgdata:"file"}}}static createAudioMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type,duration:a.duration||0}),msgType:e.MessageType.AUDIO,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,duration:a.duration||0,msgdata:"audio"}}}static createVideoMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:JSON.stringify({fileName:a.file.name,fileSize:a.file.size,fileType:a.file.type,duration:a.duration||0,width:a.width||0,height:a.height||0,thumbnailUrl:a.thumbnailUrl||""}),msgType:e.MessageType.VIDEO,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{file:a.file,duration:a.duration||0,width:a.width||0,height:a.height||0,thumbnailUrl:a.thumbnailUrl||"",msgdata:"video"}}}static createCustomMessage(t){const{to:s,conversationType:r,payload:a}=t;return{msgId:M(),conversationId:s,conversationType:r,from:"",content:a.description||"[自定义消息]",msgType:e.MessageType.CUSTOM,status:e.MessageStatus.SENDING,seqId:0,timestamp:Date.now(),isRead:!1,extra:{data:a.data,extension:a.extension}}}static fromServerData(t){let s;return t.readRecords&&Array.isArray(t.readRecords)&&(s=t.readRecords.filter(e=>e.readFlag).map(e=>e.userId)),{msgId:t.id||t.msgId,conversationId:t.to||t.groupId,conversationType:1===t.chatType?e.ConversationType.SINGLE:e.ConversationType.GROUP,from:t.from,fromUserName:t.fromUserName,fromUserImg:t.fromUserImg,content:t.content,msgType:Number(t.msgType),status:e.MessageStatus.SUCCESS,seqId:t.seqId||0,timestamp:t.createTimestamp||t.createTime||Date.now(),isRead:t.isRead||!1,isRevoked:t.isRevoked||1===t.isUndo||!1,readMembers:s,extra:t.data?JSON.parse(t.data):void 0}}}class G{constructor(s,r){this.token=null,this.config=s,this.logger=r,this.axiosInstance=t.create({baseURL:`${s.apiBaseUrl}/comind-im-api`,timeout:3e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),this.logger.debug("[APIService] Request:",e.method,e.url),e),e=>(this.logger.error("[APIService] Request error:",e),Promise.reject(e))),this.axiosInstance.interceptors.response.use(t=>{this.logger.debug("[APIService] Response:",t.config.url,t.status,t.data);const s=t.data;if(!0===s.success)return s.jsonData;throw new d(s.errorCode||e.IMErrorCode.UNKNOWN_ERROR,s.errorMessage||s.errorMsg||"Unknown error")},t=>{var s,r,a;throw this.logger.error("[APIService] Response error:",t),t.response?new d((null===(s=t.response.data)||void 0===s?void 0:s.errorCode)||e.IMErrorCode.UNKNOWN_ERROR,(null===(r=t.response.data)||void 0===r?void 0:r.errorMessage)||(null===(a=t.response.data)||void 0===a?void 0:a.errorMsg)||t.message):t.request?new d(e.IMErrorCode.NETWORK_ERROR,"Network error, please check your connection"):new d(e.IMErrorCode.UNKNOWN_ERROR,t.message)})}setToken(e){this.token=e}getCurrentToken(){return this.token}getConfig(){return this.config}async getToken(e){return this.axiosInstance.post("/v1/token/get",{appId:e.appId,appSecret:e.appSecret,userId:e.userId,userName:e.userName,userImg:e.userAvatar})}async registerWithPassword(e){return this.axiosInstance.post("/v1/token/registerWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password,userImg:e.userAvatar,companyName:e.companyName})}async loginWithPassword(e){return this.axiosInstance.post("/v1/token/loginWithPassword",{appId:e.appId,appSecret:e.appSecret,userName:e.userName,password:e.password})}async getUserInfo(e){return this.axiosInstance.post("/v1/user/getUserInfo",e)}async updateUserInfo(e){return this.axiosInstance.post("/v1/user/updateName",e)}async changePassword(e){return this.axiosInstance.post("/v1/user/changePassword",e)}async getChatList(e){return this.axiosInstance.post("/v2/group/list",e||{})}async getOfflineMsg(e,t=10){return this.axiosInstance.post("/v1/msg/getOfflineMsg",{groupIds:e,msgNumberNeedReturned:t})}async getUnreadMsgList(){return this.axiosInstance.post("/v1/msg/unreadMsg")}async searchRoamingMsg(e){var t,s;const r={...e,detailType:null!==(t=e.detailType)&&void 0!==t?t:3,syncType:null!==(s=e.syncType)&&void 0!==s?s:"BACK"};return this.axiosInstance.post("/v1/msg/searchRoamingMsg",r)}async saveLastReadMsgSeqIdOfGroup(e){return this.axiosInstance.post("/v1/msg/saveLastReadMsgSeqIdOfGroup",{groupId:e.groupId,seqId:e.seqId})}async createGroup(e){return this.axiosInstance.post("/v1/group/create",e)}async getGroupBaseInfo(e){return this.axiosInstance.post("/v2/group/getBaseInfo",e)}async updateGroupBaseInfo(e){return this.axiosInstance.post("/v1/group/updateBaseInfo",e)}async getGroupMemberList(e){return this.axiosInstance.post("/v1/groupMember/list",e)}async addGroupMember(e){return this.axiosInstance.post("/v1/groupMember/add",e)}async removeGroupMember(e){return this.axiosInstance.post("/v1/groupMember/remove",e)}async quitGroup(e){return this.axiosInstance.post("/v1/group/quit",e)}async dismissGroup(e){return this.axiosInstance.post("/v2/group/dismiss",e)}async onTopGroup(e){return this.axiosInstance.post("/v1/group/onTop",e)}async hideGroup(e){return this.axiosInstance.post("/v1/group/hide",e)}async getFriendList(e){return this.axiosInstance.post("/v1/friend/list",e||{})}async addFriend(e){return this.axiosInstance.post("/v1/friendRequest/add",e)}async getFriendRequestList(e){return this.axiosInstance.post("/v1/friendRequest/list",e||{})}async agreeFriendRequest(e){return this.axiosInstance.post("/v1/friendRequest/agree",e)}async deleteFriend(e){return this.axiosInstance.post("/v1/friend/delete",e)}async getUserPrivacy(e){return this.axiosInstance.post("/v1/user/getUserPrivacy",e)}async updatePrivacy(e){return this.axiosInstance.post("/v1/user/updatePrivacy",e)}async getBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/list",e||{})}async addToBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/add",e)}async removeFromBlacklist(e){return this.axiosInstance.post("/v1/blacklist/user/delete",e)}}class F{constructor(e){this.db=null,this.dbName="comind-im-sdk",this.version=1,this.logger=e}async init(){return new Promise((e,t)=>{const s=indexedDB.open(this.dbName,this.version);s.onerror=()=>{this.logger.error("[StorageService] Failed to open IndexedDB:",s.error),t(s.error)},s.onsuccess=()=>{this.db=s.result,this.logger.info("[StorageService] IndexedDB initialized successfully"),e()},s.onupgradeneeded=e=>{const t=e.target.result;if(!t.objectStoreNames.contains("messages")){const e=t.createObjectStore("messages",{keyPath:"msgId"});e.createIndex("conversationId","conversationId",{unique:!1}),e.createIndex("timestamp","timestamp",{unique:!1}),e.createIndex("conv_time",["conversationId","timestamp"],{unique:!1})}if(!t.objectStoreNames.contains("conversations")){t.createObjectStore("conversations",{keyPath:"conversationId"}).createIndex("lastMessageTime","lastMessageTime",{unique:!1})}}})}async saveMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message saved:",e.msgId),this.cleanOldMessages(e.conversationId).catch(e=>{this.logger.warn("[StorageService] Failed to clean old messages:",e)}),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async saveMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite"),a=r.objectStore("messages");let i=e.length;0!==i?(e.forEach(e=>{const t=a.get(e.msgId);t.onsuccess=()=>{const s=t.result;if(s&&(s.isRevoked&&(e.isRevoked=!0),s.readMembers||e.readMembers)){const t=s.readMembers||[],r=e.readMembers||[],a=[...new Set([...t,...r])];e.readMembers=a.length>0?a:void 0}a.put(e),i--},t.onerror=()=>{a.put(e),i--}}),r.oncomplete=()=>{this.logger.debug("[StorageService] Messages saved:",e.length),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save messages:",r.error),s(r.error)}):t()});this.logger.warn("[StorageService] Database not initialized")}async getMessages(e,t=20,s=0){return this.db?new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readonly").objectStore("messages").index("conv_time"),n=IDBKeyRange.bound([e,0],[e,Date.now()]),o=i.openCursor(n,"prev"),g=[];let c=0;o.onsuccess=e=>{const a=e.target.result;a&&c<s+t?(c>=s&&g.push(a.value),c++,a.continue()):(this.logger.debug("[StorageService] Messages loaded:",g.length),r(g.reverse()))},o.onerror=()=>{this.logger.error("[StorageService] Failed to load messages:",o.error),a(o.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async updateMessageRevoked(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.isRevoked=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message revoked status updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message revoked status:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for revoke update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for revoke update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageSeqId(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){n.seqId=t;const i=a.put(n);i.onsuccess=()=>{this.logger.debug("[StorageService] Message seqId updated:",e,t),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update message seqId:",i.error),r(i.error)}}else this.logger.debug("[StorageService] Message not found for seqId update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for seqId update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembers(e,t){if(this.db)return new Promise((s,r)=>{const a=this.db.transaction(["messages"],"readwrite").objectStore("messages"),i=a.get(e);i.onsuccess=()=>{const n=i.result;if(n){const i=n.readMembers||[];if(i.includes(t))s();else{i.push(t),n.readMembers=i;const o=a.put(n);o.onsuccess=()=>{this.logger.debug("[StorageService] Message readMembers updated:",e,t),s()},o.onerror=()=>{this.logger.error("[StorageService] Failed to update message readMembers:",o.error),r(o.error)}}}else this.logger.debug("[StorageService] Message not found for readMembers update:",e),s()},i.onerror=()=>{this.logger.error("[StorageService] Failed to get message for readMembers update:",i.error),r(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async updateMessageReadMembersBySeqId(e,t,s){if(this.db)return new Promise((r,a)=>{const i=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));let n=0;i.onsuccess=e=>{const a=e.target.result;if(a){const e=a.value;if(e.seqId&&e.seqId<=t){const t=e.readMembers||[];t.includes(s)||(t.push(s),e.readMembers=t,a.update(e),n++)}a.continue()}else n>0&&this.logger.debug("[StorageService] Updated readMembers for",n,"messages, seqId <=",t,"readUserId:",s),r()},i.onerror=()=>{this.logger.error("[StorageService] Failed to update readMembers by seqId:",i.error),a(i.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteMessage(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Message deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete message:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async deleteConversationMessages(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["messages"],"readwrite").objectStore("messages").index("conversationId").openCursor(IDBKeyRange.only(e));r.onsuccess=s=>{const r=s.target.result;r?(r.delete(),r.continue()):(this.logger.debug("[StorageService] Conversation messages deleted:",e),t())},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation messages:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async cleanOldMessages(e){if(!this.db)return;const t=await this.getMessages(e,Number.MAX_SAFE_INTEGER);if(t.length>500){const e=t.slice(500),s=this.db.transaction(["messages"],"readwrite").objectStore("messages");e.forEach(e=>{s.delete(e.msgId)}),this.logger.debug("[StorageService] Old messages cleaned:",e.length)}}async saveConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").put(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation saved:",e.conversationId),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to save conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}async getConversations(){return this.db?new Promise((e,t)=>{const s=this.db.transaction(["conversations"],"readonly").objectStore("conversations").getAll();s.onsuccess=()=>{const t=s.result;this.logger.debug("[StorageService] Conversations loaded:",t.length),e(t)},s.onerror=()=>{this.logger.error("[StorageService] Failed to load conversations:",s.error),t(s.error)}}):(this.logger.warn("[StorageService] Database not initialized"),[])}async deleteConversation(e){if(this.db)return new Promise((t,s)=>{const r=this.db.transaction(["conversations"],"readwrite").objectStore("conversations").delete(e);r.onsuccess=()=>{this.logger.debug("[StorageService] Conversation deleted:",e),t()},r.onerror=()=>{this.logger.error("[StorageService] Failed to delete conversation:",r.error),s(r.error)}});this.logger.warn("[StorageService] Database not initialized")}setItem(e,t){try{localStorage.setItem(`im_${e}`,t)}catch(e){this.logger.error("[StorageService] Failed to set localStorage item:",e)}}getItem(e){try{return localStorage.getItem(`im_${e}`)}catch(e){return this.logger.error("[StorageService] Failed to get localStorage item:",e),null}}removeItem(e){try{localStorage.removeItem(`im_${e}`)}catch(e){this.logger.error("[StorageService] Failed to remove localStorage item:",e)}}async clear(){if(this.db){const e=Array.from(this.db.objectStoreNames),t=this.db.transaction(e,"readwrite");e.forEach(e=>{t.objectStore(e).clear()}),await new Promise((e,s)=>{t.oncomplete=()=>{this.logger.info("[StorageService] IndexedDB cleared"),e()},t.onerror=()=>s(t.error)})}try{const e=[];for(let t=0;t<localStorage.length;t++){const s=localStorage.key(t);s&&s.startsWith("im_")&&e.push(s)}e.forEach(e=>localStorage.removeItem(e)),this.logger.info("[StorageService] localStorage cleared")}catch(e){this.logger.error("[StorageService] Failed to clear localStorage:",e)}}}class P{constructor(e,t){this.apiService=e,this.logger=t}async uploadFile(t,s){if(this.logger.info("[FileService] Uploading file:",t.name,t.size),t.size>y)throw new d(e.IMErrorCode.FILE_SIZE_LIMIT,"File size exceeds limit (100MB)");const r=new FormData;r.append("file",t);try{if(null==s?void 0:s.onProgress)return await this.uploadWithProgress(r,s.onProgress);const t=this.apiService.getCurrentToken(),a=this.apiService.getConfig(),i=await fetch(`${a.apiBaseUrl}/comind-im-api/v1/file/upload`,{method:"POST",headers:{token:t||""},body:r});if(!i.ok)throw new Error(`Upload failed: ${i.statusText}`);const n=await i.json();if(!n.success)throw new d(n.errorCode||e.IMErrorCode.FILE_UPLOAD_FAILED,n.errorMsg||"File upload failed");return this.logger.info("[FileService] File uploaded successfully"),{fileUrl:n.jsonData.filePath,fileName:n.jsonData.originFileName,fileSize:n.jsonData.originFileSize}}catch(e){throw this.logger.error("[FileService] Upload failed:",e),e}}uploadWithProgress(t,s){return new Promise((r,a)=>{const i=new XMLHttpRequest,n=this.apiService.getCurrentToken(),o=this.apiService.getConfig();i.upload.addEventListener("progress",e=>{if(e.lengthComputable){const t=Math.round(e.loaded/e.total*100);s(t)}}),i.addEventListener("load",()=>{if(200===i.status)try{const t=JSON.parse(i.responseText);t.success?r({fileUrl:t.jsonData.filePath,fileName:t.jsonData.originFileName,fileSize:t.jsonData.originFileSize}):a(new d(t.errorCode||e.IMErrorCode.FILE_UPLOAD_FAILED,t.errorMsg||"File upload failed"))}catch(t){a(new d(e.IMErrorCode.UNKNOWN_ERROR,"Parse response failed"))}else a(new d(e.IMErrorCode.FILE_UPLOAD_FAILED,`Upload failed: ${i.statusText}`))}),i.addEventListener("error",()=>{a(new d(e.IMErrorCode.NETWORK_ERROR,"Network error"))}),i.open("POST",`${o.apiBaseUrl}/comind-im-api/v1/file/upload`),i.setRequestHeader("token",n||""),i.send(t)})}async downloadFile(t,s){try{this.logger.info("[FileService] Downloading file:",t);const e=await fetch(t);if(!e.ok)throw new Error(`Download failed: ${e.statusText}`);const r=await e.blob(),a=URL.createObjectURL(r),i=document.createElement("a");i.href=a,i.download=s||this.getFileNameFromUrl(t),document.body.appendChild(i),i.click(),document.body.removeChild(i),URL.revokeObjectURL(a),this.logger.info("[FileService] Download completed")}catch(t){throw this.logger.error("[FileService] Download failed:",t),new d(e.IMErrorCode.FILE_DOWNLOAD_FAILED,t.message)}}getFileNameFromUrl(e){const t=e.split("/");return t[t.length-1]||"download"}}class x{constructor(e,t){this.socket=null,this.reconnectAttempts=0,this.heartbeatTimer=null,this.isManualDisconnect=!1,this.connectionPromise=null,this.currentToken="",this.authFlag=!1,this.config=e,this.logger=t,this.eventBus=E.getInstance()}async connect(e,t){if(this.connectionPromise)return this.connectionPromise;if(this.isConnected())return this.logger.info("[SocketService] Already connected"),Promise.resolve();this.currentToken=e,this.connectionPromise=this.doConnect(e,t);try{await this.connectionPromise}finally{this.connectionPromise=null}}doConnect(t,r){return new Promise((r,a)=>{this.logger.info("[SocketService] Connecting to WebSocket..."),this.isManualDisconnect=!1;const i=this.config.wsUrl,n=this.config.wsPath||"/socket.io";this.socket=s(i,{path:n,transports:["polling","websocket"],reconnection:!0,reconnectionAttempts:10,reconnectionDelay:1e3,reconnectionDelayMax:5e3,timeout:2e4,autoConnect:!1}),this.socket.on("connect",()=>{this.logger.info("[SocketService] Socket connected"),this.reconnectAttempts=0,this.authenticate(t)}),this.socket.on(U,e=>{this.handleBinaryMessage(e,r)}),this.socket.on("connect_error",t=>{this.logger.error("[SocketService] Connect error:",t),this.eventBus.emitEvent(e.IMEventType.ERROR,t),a(t)}),this.socket.on("disconnect",t=>{this.logger.warn("[SocketService] Disconnected:",t),this.stopHeartbeat(),this.isManualDisconnect||this.eventBus.emitEvent(e.IMEventType.DISCONNECT,{reason:t})}),this.socket.on("reconnect_attempt",t=>{this.logger.info("[SocketService] Reconnecting...",t),this.reconnectAttempts=t,this.eventBus.emitEvent(e.IMEventType.RECONNECTING,{attempt:t})}),this.socket.on("reconnect",t=>{this.logger.info("[SocketService] Reconnected after",t,"attempts"),this.authenticate(this.currentToken),this.eventBus.emitEvent(e.IMEventType.RECONNECTED)}),this.socket.on("reconnect_failed",()=>{this.logger.error("[SocketService] Reconnect failed"),this.eventBus.emitEvent(e.IMEventType.ERROR,new Error("Reconnect failed"))}),this.socket.connect(),this.authFlag=!1,setTimeout(()=>{this.authFlag||this.isManualDisconnect||a(new Error("Authentication timeout"))},15e3)})}authenticate(e){var t;const s=O(e);this.logger.debug("[SocketService] Sending auth packet"),null===(t=this.socket)||void 0===t||t.emit(U,s)}handleBinaryMessage(t,s){try{const r=R(t);switch(this.logger.debug("[SocketService] Received packet:",r.header.type,r.payload),r.header.type){case T.CONNECT_ACK:this.handleConnectAck(r.payload,s);break;case T.PONG:this.logger.debug("[SocketService] Heartbeat received");break;case T.MESSAGE:this.handleMessagePacket(r);break;case T.DISCONNECT:this.logger.warn("[SocketService] Server requested disconnect"),this.eventBus.emitEvent(e.IMEventType.KICKED_OFFLINE),this.disconnect();break;default:this.logger.warn("[SocketService] Unknown packet type:",r.header.type)}}catch(e){this.logger.error("[SocketService] Failed to decode packet:",e)}}handleConnectAck(t,s){if(this.authFlag=!0,0===t.status)this.logger.info("[SocketService] Authentication successful"),this.startHeartbeat(),this.eventBus.emitEvent(e.IMEventType.CONNECT_SUCCESS),null==s||s();else{const s=t.errMsg||"Authentication failed";this.logger.error("[SocketService] Authentication failed:",s),this.eventBus.emitEvent(e.IMEventType.ERROR,new Error(s))}}handleMessagePacket(e){var t,s;if(void 0!==e.header.ackId){const r=(s=e.header.ackId,w({header:{version:2,type:T.MESSAGE_ACK,ackId:s}}));null===(t=this.socket)||void 0===t||t.emit(U,r)}this.logger.info("[SocketService] Emitting SOCKET_MESSAGE, cmd:",e.payload.cmd),this.eventBus.emitEvent("SOCKET_MESSAGE",{cmd:e.payload.cmd,data:e.payload.bytes,ackId:e.header.ackId})}disconnect(){this.logger.info("[SocketService] Disconnecting..."),this.isManualDisconnect=!0,this.socket&&(this.stopHeartbeat(),this.socket.disconnect(),this.socket=null)}isConnected(){var e;return(null===(e=this.socket)||void 0===e?void 0:e.connected)||!1}async sendMessage(e,t){if(!this.socket||!this.isConnected())throw new Error("Socket not connected");const s=function(e,t){return w({header:{version:2,type:T.MESSAGE,ackId:null!=t?t:N++},payload:e})}(e,t);this.logger.debug("[SocketService] Sending message packet"),this.socket.emit(U,s)}startHeartbeat(){this.stopHeartbeat(),this.heartbeatTimer=setInterval(()=>{var e;if(this.isConnected()){const t=w({header:{version:2,type:T.PING}});null===(e=this.socket)||void 0===e||e.emit(U,t),this.logger.debug("[SocketService] Heartbeat sent")}},3e4)}stopHeartbeat(){this.heartbeatTimer&&(clearInterval(this.heartbeatTimer),this.heartbeatTimer=null)}getStatus(){return{connected:this.isConnected(),reconnectAttempts:this.reconnectAttempts}}}class B{constructor(e,s){this.logQueue=[],this.uploadTimer=null,this.userId=null,this.token=null,this.enabled=!1,this.consecutiveFailures=0,this.maxConsecutiveFailures=3,this.uploadDisabled=!1,this.maxPayloadSize=5e4,this.config=e,this.logger=s,this.enabled=!0===e.enableRemoteLog,this.batchSize=e.remoteLogBatchSize||50,this.uploadInterval=e.remoteLogInterval||3e4,this.clientId=this.generateClientId(),this.sessionId=this.generateSessionId(),this.axiosInstance=t.create({baseURL:`${e.apiBaseUrl}/comind-im-api`,timeout:1e4,headers:{"Content-Type":"application/json"}}),this.axiosInstance.interceptors.request.use(e=>(this.token&&(e.headers.token=this.token),e)),this.enabled&&(this.startUploadTimer(),this.setupUnloadHandler())}setToken(e){this.token=e}generateClientId(){const e="undefined"!=typeof localStorage?localStorage.getItem("im_sdk_client_id"):null;if(e)return e;const t="client_"+Date.now()+"_"+Math.random().toString(36).substring(2,11);return"undefined"!=typeof localStorage&&localStorage.setItem("im_sdk_client_id",t),t}generateSessionId(){return"session_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateLogId(){return"log_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}generateBatchId(){return"batch_"+Date.now()+"_"+Math.random().toString(36).substring(2,11)}setUserId(e){this.userId=e}setEnabled(e){this.enabled=e,e&&!this.uploadTimer?this.startUploadTimer():!e&&this.uploadTimer&&this.stopUploadTimer()}log(e){if(!this.enabled)return;const t={id:this.generateLogId(),level:e.level||"info",category:e.category||"system",timestamp:Date.now(),...e,context:{userId:this.userId||void 0,sessionId:this.sessionId,...e.context}};this.logQueue.push(t),this.logQueue.length>=this.batchSize&&this.flush()}info(e,t,s){this.log({level:"info",category:e,message:t,data:s})}warn(e,t,s){this.log({level:"warn",category:e,message:t,data:s})}error(e,t,s,r){this.log({level:"error",category:e,message:t,error:s,data:r,status:"error"})}performance(e,t,s,r){this.log({level:"info",category:"performance",module:e,action:t,status:"success",metrics:{duration:s,...r}})}aiCall(e,t,s,r,a){this.log({level:"error"===r?"error":"info",category:"ai_call",action:e,status:r,data:a,metrics:{tokenCount:t,duration:s}})}startUploadTimer(){this.uploadTimer||(this.uploadTimer=window.setInterval(()=>{this.flush()},this.uploadInterval))}stopUploadTimer(){this.uploadTimer&&(window.clearInterval(this.uploadTimer),this.uploadTimer=null)}setupUnloadHandler(){"undefined"!=typeof window&&(window.addEventListener("beforeunload",()=>{this.flushSync()}),window.addEventListener("visibilitychange",()=>{"hidden"===document.visibilityState&&this.flushSync()}))}flushSync(){}async flush(){}cleanLogEntry(e){var t,s;const r={...e};if(r.message&&r.message.length>500&&(r.message=r.message.substring(0,500)+"... [truncated]"),r.data){const e=JSON.stringify(r.data);e.length>1e3&&(r.data={_truncated:!0,_originalSize:e.length})}return(null===(t=r.error)||void 0===t?void 0:t.stack)&&r.error.stack.length>500&&(r.error={...r.error,stack:r.error.stack.substring(0,500)+"... [truncated]"}),(null===(s=r.error)||void 0===s?void 0:s.message)&&r.error.message.length>200&&(r.error={...r.error,message:r.error.message.substring(0,200)+"..."}),r}resetUploadState(){this.consecutiveFailures=0,this.uploadDisabled=!1,this.logger.info("[TraceLogService] Upload state reset")}getEnvironment(){if("undefined"!=typeof window){const e=window.location.hostname;if("localhost"===e||"127.0.0.1"===e)return"development";if(e.includes("staging")||e.includes("test")||e.includes("qa"))return"staging"}return"production"}destroy(){this.flushSync(),this.stopUploadTimer(),this.logQueue=[]}}class q{constructor(e,t,s,r,a){this.apiService=e,this.socketService=t,this.storageService=s,this.fileService=r,this.currentUserId="",this.logger=a,this.eventBus=E.getInstance(),this.setupSocketListeners()}setCurrentUserId(e){this.currentUserId=e}createTextMessage(e){return k.createTextMessage(e)}createImageMessage(e){return k.createImageMessage(e)}createFileMessage(e){return k.createFileMessage(e)}createCustomMessage(e){return k.createCustomMessage(e)}createAudioMessage(e){return k.createAudioMessage(e)}createVideoMessage(e){return k.createVideoMessage(e)}async sendMessage(t){var s,r;this.logger.info("[MessageManager] Sending message:",t.msgId);const a=null===(s=t.extra)||void 0===s?void 0:s.file;try{if(t.from=this.currentUserId,t.status=e.MessageStatus.SENDING,this.eventBus.emitEvent("MESSAGE_SENDING",t),await this.storageService.saveMessage(this.cleanMessageForStorage(t)),(t.msgType===e.MessageType.IMAGE||t.msgType===e.MessageType.FILE||t.msgType===e.MessageType.AUDIO||t.msgType===e.MessageType.VIDEO)&&a){const e=await this.fileService.uploadFile(a,{onProgress:e=>{this.eventBus.emitEvent("UPLOAD_PROGRESS",{msgId:t.msgId,progress:e})}}),s=JSON.parse(t.content);s.url=e.fileUrl,s.fileName=e.fileName,s.fileSize=e.fileSize,t.content=JSON.stringify(s),t.extra||(t.extra={}),t.extra.url=e.fileUrl,delete t.extra.file}const s=A((i=t.content,n=t.conversationId,o=t.conversationType===e.ConversationType.SINGLE?m.SINGLE:m.GROUP,g=t.from,c=t.msgType,d=t.extra||{},l=t.msgId,{cmd:v.CHAT_MESSAGE,type:1,id:l||M(),to:n,chatType:o,content:i,createTimestamp:Date.now(),msgType:c,from:g,data:JSON.stringify(d)}));return await this.socketService.sendMessage(s),t.status=e.MessageStatus.SUCCESS,t.timestamp=Date.now(),await this.storageService.saveMessage(t),this.eventBus.emitEvent(e.IMEventType.MESSAGE_SENT,t),this.logger.info("[MessageManager] Message sent successfully:",t.msgId),this.fetchMessageSeqId(t.conversationId,t.msgId).catch(e=>{this.logger.warn("[MessageManager] Failed to fetch message seqId:",e)}),t}catch(s){throw this.logger.error("[MessageManager] Send message failed:",s),t.status=e.MessageStatus.FAILED,null===(r=t.extra)||void 0===r||delete r.file,await this.storageService.saveMessage(this.cleanMessageForStorage(t)),this.eventBus.emitEvent("MESSAGE_SEND_FAILED",{message:t,error:s}),s}var i,n,o,g,c,d,l}async revokeMessage(t){this.logger.info("[MessageManager] Revoking message:",t.msgId);if(Date.now()-t.timestamp>12e4)throw new Error("Message revoke timeout (2 minutes)");if(t.from!==this.currentUserId)throw new Error("Can only revoke own messages");try{const s=function(e){return A({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType||2,content:"",createTimestamp:e.createTimestamp,msgType:0,from:e.from,data:JSON.stringify({msgId:e.msgId})})}(function(e,t,s,r=2){return{cmd:v.CHAT_MESSAGE,type:3,id:M(),to:t,msgId:e,from:s,chatType:r,createTimestamp:Date.now()}}(t.msgId,t.conversationId,t.from));await this.socketService.sendMessage(s);const r=this.cleanMessageForStorage(t);r.isRevoked=!0,await this.storageService.saveMessage(r),this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,r),this.logger.info("[MessageManager] Message revoked:",t.msgId)}catch(e){throw this.logger.error("[MessageManager] Revoke message failed:",e),e}}cleanMessageForStorage(e){var t;const s=JSON.parse(JSON.stringify(e));return(null===(t=s.extra)||void 0===t?void 0:t.file)&&delete s.extra.file,s}async fetchMessageSeqId(e,t){await new Promise(e=>setTimeout(e,500));try{const s=(await this.apiService.searchRoamingMsg({groupId:e,limitSize:5,syncType:"BACK"})).find(e=>e.id===t||e.msgId===t);s&&s.seqId?(this.logger.info("[MessageManager] Found message seqId from server, msgId:",t,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(t,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:t,seqId:s.seqId})):this.logger.warn("[MessageManager] Message not found on server or no seqId, msgId:",t)}catch(e){this.logger.error("[MessageManager] Failed to fetch message seqId:",e)}}async getMessageList(e,t=20,s){this.logger.info("[MessageManager] Getting message list:",e,"lastMsgSeqId:",s);try{const r=(await this.apiService.searchRoamingMsg({groupId:e,msgSeqId:null!=s?s:"",limitSize:t,syncType:"FORWARD"})).map(e=>k.fromServerData(e));r.length>0&&await this.storageService.saveMessages(r);const a=r.length>=t;return r.sort((e,t)=>e.timestamp-t.timestamp),{messages:r,hasMore:a}}catch(s){this.logger.error("[MessageManager] Get message list failed:",s);try{return{messages:await this.storageService.getMessages(e,t),hasMore:!1}}catch(e){throw s}}}async markMessageAsRead(t,s){try{await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:t,seqId:s.seqId}),s.isRead=!0,await this.storageService.saveMessage(s),this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{conversationId:t,message:s})}catch(e){throw this.logger.error("[MessageManager] Mark message as read failed:",e),e}}async sendReadReceipt(t){this.logger.info("[MessageManager] Sending read receipt for message:",t.msgId,"seqId:",t.seqId);try{if(t.from===this.currentUserId)return;if(!t.seqId)return void this.logger.warn("[MessageManager] Message has no seqId, skip read receipt");const s=t.conversationType===e.ConversationType.GROUP,r=function(e,t,s,r,a,i){return{cmd:v.CHAT_MESSAGE,type:2,id:M(),to:e,chatType:r,msgType:a,from:i,groupId:t,seqId:s,createTimestamp:Date.now()}}(s?t.conversationId:t.from,t.conversationId,t.seqId,s?m.GROUP:m.SINGLE,t.msgType,this.currentUserId),a=function(e){return A({cmd:e.cmd,type:e.type,id:e.id,to:e.to,chatType:e.chatType,content:"",createTimestamp:e.createTimestamp,msgType:e.msgType,from:e.from,data:JSON.stringify({groupId:e.groupId,lastReadSeqId:e.seqId})})}(r);await this.socketService.sendMessage(a),this.logger.info("[MessageManager] Read receipt sent for message:",t.msgId,"seqId:",t.seqId)}catch(e){throw this.logger.error("[MessageManager] Send read receipt failed:",e),e}}async deleteMessage(e){try{await this.storageService.deleteMessage(e.msgId),this.logger.info("[MessageManager] Message deleted:",e.msgId)}catch(e){throw this.logger.error("[MessageManager] Delete message failed:",e),e}}setupSocketListeners(){this.eventBus.onEvent("SOCKET_MESSAGE",async t=>{this.logger.debug("[MessageManager] Received socket message:",t);try{const s=t.cmd,r=t.data;if(51===s){const t=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",from:"",to:"",handle:0,seqId:0,chatType:0,msgType:0,content:""};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=b(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 9:t.handle=r;break;case 10:t.seqId=r;break;case 11:t.chatType=r;break;case 12:t.msgType=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=b(e,s);s=n;const o=e.slice(s,s+a),g=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=g;break;case 6:t.data=g;break;case 7:t.from=g;break;case 8:t.to=g;break;case 13:t.content=g}}}}return t}(r);if(this.logger.info("[MessageManager] Decoded C2C message, type:",t.type,"from:",t.from,"to:",t.to,"seqId:",t.seqId),1===t.type){const s=k.fromServerData(t);if(s.from===this.currentUserId)return this.logger.info("[MessageManager] Received own message from server, msgId:",s.msgId,"seqId:",s.seqId,"rawId:",t.id),void(s.seqId&&s.msgId?(this.logger.info("[MessageManager] Updating local message seqId, msgId:",s.msgId,"seqId:",s.seqId),await this.storageService.updateMessageSeqId(s.msgId,s.seqId),this.eventBus.emitEvent("MESSAGE_SEQID_UPDATED",{msgId:s.msgId,seqId:s.seqId}),this.logger.info("[MessageManager] MESSAGE_SEQID_UPDATED event emitted")):this.logger.warn("[MessageManager] Missing seqId or msgId, cannot update. seqId:",s.seqId,"msgId:",s.msgId));await this.storageService.saveMessage(s),this.eventBus.emitEvent(e.IMEventType.MESSAGE_RECEIVED,s)}else if(2===t.type||3===t.type){let s="";try{if(t.data){s=JSON.parse(t.data).msgId||""}}catch(e){}if(s||(s=t.id||""),3===t.type){this.logger.debug("[MessageManager] Message revoked:",s);try{await this.storageService.updateMessageRevoked(s,!0)}catch(e){this.logger.error("[MessageManager] Failed to update revoked status in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,{msgId:s,conversationId:t.to})}else{let r=t.seqId,a=t.to;if(t.data)try{const e=JSON.parse(t.data);e.lastReadSeqId&&(r=e.lastReadSeqId),e.groupId&&(a=e.groupId)}catch(e){}if(this.logger.debug("[MessageManager] Message read receipt, seqId:",r,"groupId:",a,"from:",t.from),t.from&&r&&a)try{await this.storageService.updateMessageReadMembersBySeqId(a,r,t.from)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{msgId:s,seqId:r,conversationId:a,from:t.from})}}}else if(53===s){const t=function(e){const t={cmd:0,id:"",createTimestamp:0,type:0,serialize:0,data:"",broadcast:0,to:"",seqId:0};let s=0;const r=new TextDecoder;for(;s<e.length;){const a=e[s],i=a>>3,n=7&a;if(s++,0===n){const{value:r,newOffset:a}=b(e,s);switch(s=a,i){case 1:t.cmd=r;break;case 3:t.createTimestamp=r;break;case 4:t.type=r;break;case 5:t.serialize=r;break;case 7:t.broadcast=r;break;case 9:t.seqId=r}}else{if(2!==n)break;{const{value:a,newOffset:n}=b(e,s);s=n;const o=e.slice(s,s+a),g=r.decode(new Uint8Array(o));switch(s+=a,i){case 2:t.id=g;break;case 6:t.data=g;break;case 8:t.to=g}}}}return t}(r);if(this.logger.info("[MessageManager] ===== 收到S2C通知消息 ===== cmd=53, type:",t.type,"data:",t.data),2===t.type)try{const e=JSON.parse(t.data);this.logger.info("[MessageManager] New group notification, groupId:",e.groupId),this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"NEW_GROUP",groupId:e.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse new group notification:",e)}else if(1===t.type)this.logger.warn("[MessageManager] Kicked offline notification"),this.eventBus.emitEvent(e.IMEventType.KICKED_OFFLINE);else if(7===t.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"MEMBER_ADDED",data:t.data});else if(8===t.type||11===t.type)this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:8===t.type?"MEMBER_QUIT":"MEMBER_REMOVED",data:t.data});else if(9===t.type)try{const e=JSON.parse(t.data);this.eventBus.emitEvent("SOCKET_GROUP_NOTIFICATION",{type:"GROUP_DISMISSED",groupId:e.groupId})}catch(e){this.logger.error("[MessageManager] Failed to parse group dismiss notification:",e)}else if(18===t.type||19===t.type)this.eventBus.emitEvent(e.IMEventType.FRIEND_APPLICATION_RECEIVED,t);else if(23===t.type)try{const s=JSON.parse(t.data),{from:r,groupId:a,lastReadSeqId:i}=s;if(this.logger.info("[MessageManager] Received read receipt notification, from:",r,"groupId:",a,"seqId:",i),r&&a&&i)try{await this.storageService.updateMessageReadMembersBySeqId(a,i,r)}catch(e){this.logger.error("[MessageManager] Failed to update readMembers in storage:",e)}this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{seqId:i,conversationId:a,from:r})}catch(e){this.logger.error("[MessageManager] Failed to parse read receipt notification:",e)}}}catch(e){this.logger.error("[MessageManager] Failed to decode message:",e)}}),this.eventBus.onEvent("SOCKET_RECEIPT",async t=>{3===t.type?(this.logger.debug("[MessageManager] Message revoked:",t.msgId),this.eventBus.emitEvent(e.IMEventType.MESSAGE_REVOKED,{msgId:t.msgId,conversationId:t.to})):2===t.type&&(this.logger.debug("[MessageManager] Message read receipt:",t.msgId),this.eventBus.emitEvent(e.IMEventType.MESSAGE_READ,{msgId:t.msgId,conversationId:t.to}))})}}class K{constructor(e,t,s){this.apiService=e,this.storageService=t,this.conversationMap=new Map,this.currentUserId="",this.logger=s,this.eventBus=E.getInstance(),this.setupMessageListeners()}setCurrentUserId(e){this.currentUserId=e}async getConversationList(t){this.logger.info("[ConversationManager] Getting conversation list");try{const{pageNo:s=1,pageSize:r=100}=t||{},a=await this.apiService.getChatList({pageNo:s,pageSize:r});let i=[];try{const e=await this.apiService.getUnreadMsgList();i=Array.isArray(e)?e:[],this.logger.debug("[ConversationManager] Unread messages:",i.length)}catch(e){this.logger.warn("[ConversationManager] Get unread msg list failed:",e)}const n=new Map;for(const e of i)if(51===e.cmd&&e.from!==this.currentUserId&&3!==e.type&&1!==e.isUndo){const t=e.to,s=n.get(t)||0;n.set(t,s+1)}const o=a.result.map(e=>e.groupId);let g=new Map;try{if(o.length>0){const e=await this.apiService.getOfflineMsg(o,1),t=(null==e?void 0:e.groupList)||[];for(const e of t)e.msgDetail&&e.msgDetail.length>0&&g.set(e.groupId,e.msgDetail[0])}}catch(e){this.logger.warn("[ConversationManager] Get offline msg failed:",e)}const c=a.result.map(t=>{const s=g.get(t.groupId)||t.lastMsg,r=s?this.parseLastMessage(s):void 0,a=t.createTime?new Date(t.createTime).getTime():0,i=t.lastMsgTime||(null==r?void 0:r.timestamp)||a||Date.now(),o={conversationId:t.groupId,conversationType:"SINGLE_CHAT"===t.groupType?e.ConversationType.SINGLE:e.ConversationType.GROUP,displayName:t.displayName||t.name||"",avatarUrl:t.groupImg||"",lastMessage:r,lastMessageTime:i,unreadCount:n.get(t.groupId)||0,isPinned:t.onTop||!1,isHidden:t.hidden||!1,pinnedTime:t.pinnedTime};return this.conversationMap.set(o.conversationId,o),o});c.sort((e,t)=>e.isPinned&&!t.isPinned?-1:!e.isPinned&&t.isPinned?1:(t.lastMessageTime||0)-(e.lastMessageTime||0));for(const e of c)await this.storageService.saveConversation(e);return this.eventBus.emitEvent("CONVERSATION_LIST_UPDATED",c),{total:a.total||c.length,conversations:c}}catch(e){this.logger.error("[ConversationManager] Get conversation list failed:",e);const t=await this.storageService.getConversations();return{total:t.length,conversations:t}}}async getConversation(e){return this.logger.info("[ConversationManager] Getting conversation:",e),this.conversationMap.has(e)?this.conversationMap.get(e):(await this.getConversationList(),this.conversationMap.get(e)||null)}async deleteConversation(e){this.logger.info("[ConversationManager] Deleting conversation:",e);try{await this.apiService.hideGroup({groupId:e}),await this.storageService.deleteConversation(e),this.conversationMap.delete(e),this.eventBus.emitEvent("CONVERSATION_DELETED",{conversationId:e}),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Delete conversation failed:",e),e}}async pinConversation(t,s){this.logger.info("[ConversationManager] Pin conversation:",t,s);try{await this.apiService.onTopGroup({groupId:t,onTop:s});const r=this.conversationMap.get(t);r&&(r.isPinned=s,r.pinnedTime=s?Date.now():void 0,await this.storageService.saveConversation(r),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,r)),await this.getConversationList()}catch(e){throw this.logger.error("[ConversationManager] Pin conversation failed:",e),e}}getTotalUnreadCount(){let e=0;return this.conversationMap.forEach(t=>{e+=t.unreadCount}),e}async clearUnreadCount(t,s){var r;this.logger.info("[ConversationManager] Clearing unread count:",t,"seqId:",s);try{const a=this.conversationMap.get(t);let i=s;if(i&&0!==i&&""!==i||(i=null===(r=null==a?void 0:a.lastMessage)||void 0===r?void 0:r.seqId),!i||0===i)return this.logger.warn("[ConversationManager] No valid seqId found, skip clearing unread count"),void(a&&(a.unreadCount=0,await this.storageService.saveConversation(a),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,a)));await this.apiService.saveLastReadMsgSeqIdOfGroup({groupId:t,seqId:i}),a&&(a.unreadCount=0,await this.storageService.saveConversation(a),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,a))}catch(e){throw this.logger.error("[ConversationManager] Clear unread count failed:",e),e}}async updateConversationLastMessage(t){this.logger.debug("[ConversationManager] Updating conversation last message:",t.msgId);try{let s=this.conversationMap.get(t.conversationId);if(s){s.lastMessage=t,s.lastMessageTime=t.timestamp;this.currentUserId&&t.from===this.currentUserId||t.isRead||s.unreadCount++}else{const r=this.currentUserId&&t.from===this.currentUserId;let a=t.fromUserName||t.conversationId,i=t.fromUserImg||"";if(t.conversationType===e.ConversationType.GROUP)try{const e=await this.apiService.getGroupBaseInfo({groupId:t.conversationId});a=e.name||e.displayName||t.conversationId,i=e.groupImg||"",this.logger.debug("[ConversationManager] Got group info for new conversation:",a)}catch(e){this.logger.warn("[ConversationManager] Failed to get group info:",e)}s={conversationId:t.conversationId,conversationType:t.conversationType,displayName:a,avatarUrl:i,lastMessage:t,lastMessageTime:t.timestamp,unreadCount:r?0:1,isPinned:!1,isHidden:!1},this.conversationMap.set(s.conversationId,s)}await this.storageService.saveConversation(s),this.eventBus.emitEvent(e.IMEventType.CONVERSATION_UPDATED,s)}catch(e){this.logger.error("[ConversationManager] Update conversation last message failed:",e)}}parseLastMessage(t){if(t)return{msgId:t.id||t.msgId||"",conversationId:t.to||t.groupId||"",conversationType:1===t.chatType?e.ConversationType.SINGLE:e.ConversationType.GROUP,from:t.from||"",fromUserName:t.fromUserName,fromUserImg:t.fromUserImg,content:t.content||"",msgType:t.msgType||0,status:1,seqId:t.seqId||0,timestamp:t.createTimestamp||t.createTime||0,isRead:!1}}setupMessageListeners(){this.eventBus.onEvent(e.IMEventType.MESSAGE_RECEIVED,async e=>{await this.updateConversationLastMessage(e)}),this.eventBus.onEvent(e.IMEventType.MESSAGE_SENT,async e=>{await this.updateConversationLastMessage(e)})}}class z{constructor(e,t){this.apiService=e,this.logger=t,this.eventBus=E.getInstance(),this.setupGroupListeners()}async createGroup(e){this.logger.info("[GroupManager] Creating group");try{const t=await this.apiService.createGroup({groupType:e.groupType,userIdList:e.userIdList,name:e.groupName,groupImg:e.groupAvatar}),s=await this.getGroupInfo(t.groupId);return this.eventBus.emitEvent("GROUP_CREATED",s),s}catch(e){throw this.logger.error("[GroupManager] Create group failed:",e),e}}async getGroupInfo(e){this.logger.info("[GroupManager] Getting group info:",e);try{const t=await this.apiService.getGroupBaseInfo({groupId:e});return{groupId:t.groupId,groupType:t.groupType,groupName:t.name||t.displayName,groupAvatar:t.groupImg,notice:t.notice,ownerId:t.owner,memberCount:t.memberCurrent,maxMemberCount:t.memberLimit,createTime:t.createTime}}catch(e){throw this.logger.error("[GroupManager] Get group info failed:",e),e}}async updateGroupInfo(e){this.logger.info("[GroupManager] Updating group info:",e.groupId);try{await this.apiService.updateGroupBaseInfo({groupId:e.groupId,name:e.groupName,groupImg:e.groupAvatar,notice:e.notice}),this.eventBus.emitEvent("GROUP_INFO_UPDATED",{groupId:e.groupId})}catch(e){throw this.logger.error("[GroupManager] Update group info failed:",e),e}}async getGroupMemberList(e){this.logger.info("[GroupManager] Getting group member list:",e.groupId);try{const[t,s]=await Promise.all([this.apiService.getGroupBaseInfo({groupId:e.groupId}),this.apiService.getGroupMemberList({groupId:e.groupId,pageNo:e.pageNo,pageSize:e.pageSize})]),r=t.owner,a=null==r?void 0:r.toLowerCase();return{total:s.total,members:s.result.map(e=>{var t;return{userId:e.userId,userName:e.userName,userAvatar:e.userImg,groupNickname:e.groupNickName,role:(null===(t=e.userId)||void 0===t?void 0:t.toLowerCase())===a?0:1===e.isGroupManager?1:2,joinTime:e.joinTime}})}}catch(e){throw this.logger.error("[GroupManager] Get group member list failed:",e),e}}async addGroupMembers(e,t){this.logger.info("[GroupManager] Adding group members:",e,t);try{await this.apiService.addGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_JOINED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Add group members failed:",e),e}}async removeGroupMembers(e,t){this.logger.info("[GroupManager] Removing group members:",e,t);try{await this.apiService.removeGroupMember({groupId:e,userIdList:t}),this.eventBus.emitEvent("MEMBER_REMOVED",{groupId:e,userIdList:t})}catch(e){throw this.logger.error("[GroupManager] Remove group members failed:",e),e}}async quitGroup(e){this.logger.info("[GroupManager] Quitting group:",e);try{await this.apiService.quitGroup({groupId:e}),this.eventBus.emitEvent("MEMBER_QUIT",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Quit group failed:",e),e}}async dismissGroup(e){this.logger.info("[GroupManager] Dismissing group:",e);try{await this.apiService.dismissGroup({groupId:e}),this.eventBus.emitEvent("GROUP_DISMISSED",{groupId:e})}catch(e){throw this.logger.error("[GroupManager] Dismiss group failed:",e),e}}setupGroupListeners(){this.eventBus.onEvent("SOCKET_GROUP_NOTIFICATION",t=>{this.logger.debug("[GroupManager] Group notification:",t),this.eventBus.emitEvent(e.IMEventType.GROUP_NOTIFICATION,t)})}}class V{constructor(e,t){this.apiService=e,this.logger=t}async getCurrentUserInfo(){return this.getUserInfo()}async getUserInfo(e){this.logger.info("[UserManager] Getting user info:",e);try{const t=await this.apiService.getUserInfo({userId:e});return{userId:t.userId,userName:t.userName,userImg:t.userImg,companyName:t.companyName,imRole:t.imRole}}catch(e){throw this.logger.error("[UserManager] Get user info failed:",e),e}}async updateUserInfo(e){this.logger.info("[UserManager] Updating user info:",e.userId);try{await this.apiService.updateUserInfo(e)}catch(e){throw this.logger.error("[UserManager] Update user info failed:",e),e}}async getBlacklist(e=1,t=100){this.logger.info("[UserManager] Getting blacklist");try{return(await this.apiService.getBlacklist({pageNo:e,pageSize:t})).result.map(e=>({userId:e.userId,userName:e.userName,userImg:e.userImg}))}catch(e){throw this.logger.error("[UserManager] Get blacklist failed:",e),e}}async addToBlacklist(e){this.logger.info("[UserManager] Adding to blacklist:",e);try{await this.apiService.addToBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Add to blacklist failed:",e),e}}async removeFromBlacklist(e){this.logger.info("[UserManager] Removing from blacklist:",e);try{await this.apiService.removeFromBlacklist({userList:e})}catch(e){throw this.logger.error("[UserManager] Remove from blacklist failed:",e),e}}async getUserPrivacy(e){this.logger.info("[UserManager] Getting user privacy:",e);try{const t=await this.apiService.getUserPrivacy({userId:e});return{isSetAuth:t.isSetAuth||0,isChatStranger:t.isChatStranger||0}}catch(e){throw this.logger.error("[UserManager] Get user privacy failed:",e),e}}async updatePrivacy(e,t){this.logger.info("[UserManager] Updating user privacy:",e,t);try{await this.apiService.updatePrivacy({userId:e,...t})}catch(e){throw this.logger.error("[UserManager] Update user privacy failed:",e),e}}async changePassword(e,t){this.logger.info("[UserManager] Changing password");try{await this.apiService.changePassword({oldPassword:e,newPassword:t}),this.logger.info("[UserManager] Password changed successfully")}catch(e){throw this.logger.error("[UserManager] Change password failed:",e),e}}}class j{constructor(e,t){this.apiService=e,this.currentUserId="",this.logger=t,this.eventBus=E.getInstance(),this.setupFriendListeners()}setCurrentUserId(e){this.currentUserId=e}async getFriendList(){this.logger.info("[FriendManager] Getting friend list");try{const e=await this.apiService.getFriendList({userId:this.currentUserId}),t=[],s=(null==e?void 0:e.jsonData)||e||[];if(Array.isArray(s))for(const e of s)if(e.friendList&&Array.isArray(e.friendList))for(const s of e.friendList)t.push({userId:s.friendUserId||s.userId,userName:s.friendUserName||s.userName,userImg:s.friendUserImg||s.userImg});return t}catch(e){throw this.logger.error("[FriendManager] Get friend list failed:",e),e}}async getFriendApplicationList(){this.logger.info("[FriendManager] Getting friend application list");try{const e=await this.apiService.getFriendRequestList({userId:this.currentUserId}),t=Array.isArray(e)?e:(null==e?void 0:e.jsonData)||(null==e?void 0:e.result)||[];this.logger.debug("[FriendManager] Friend request list raw data:",t),this.logger.debug("[FriendManager] Current user ID:",this.currentUserId);const s=this.currentUserId.toLowerCase(),r=t.filter(e=>{var t;return(null===(t=e.friendUserId)||void 0===t?void 0:t.toLowerCase())===s});return this.logger.debug("[FriendManager] Incoming requests after filter:",r),r.map(e=>({requestId:e.requestId,userId:e.requestUserId,userName:e.friendUserName||e.requestUserId,userAvatar:e.friendUserImg,applyMessage:e.requestReason,createTime:e.requestTime,status:e.requestStatus}))}catch(e){throw this.logger.error("[FriendManager] Get friend application list failed:",e),e}}async addFriend(e,t,s){this.logger.info("[FriendManager] Adding friend:",e);try{const r=await this.apiService.addFriend({friendUserId:e,requestUserId:this.currentUserId,requestReason:t,requestRemark:s});return this.eventBus.emitEvent("FRIEND_APPLICATION_SENT",{friendUserId:e,requestReason:t}),r}catch(e){throw this.logger.error("[FriendManager] Add friend failed:",e),e}}async acceptFriendApplication(t){this.logger.info("[FriendManager] Accepting friend application:",t);try{const s=await this.apiService.agreeFriendRequest({requestId:t});return this.eventBus.emitEvent(e.IMEventType.FRIEND_ADDED,{requestId:t}),s}catch(e){throw this.logger.error("[FriendManager] Accept friend application failed:",e),e}}async deleteFriend(t){this.logger.info("[FriendManager] Deleting friend:",t);try{await this.apiService.deleteFriend({userId:this.currentUserId,friendUserId:t}),this.eventBus.emitEvent(e.IMEventType.FRIEND_DELETED,{friendUserId:t})}catch(e){throw this.logger.error("[FriendManager] Delete friend failed:",e),e}}setupFriendListeners(){this.eventBus.onEvent("SOCKET_FRIEND_NOTIFICATION",t=>{switch(this.logger.debug("[FriendManager] Friend notification:",t),t.type){case"friend_request":this.eventBus.emitEvent(e.IMEventType.FRIEND_APPLICATION_RECEIVED,t);break;case"friend_added":this.eventBus.emitEvent(e.IMEventType.FRIEND_ADDED,t);break;case"friend_deleted":this.eventBus.emitEvent(e.IMEventType.FRIEND_DELETED,t);break;default:this.logger.warn("[FriendManager] Unknown friend notification type:",t.type)}})}}class W{constructor(t){if(this.logger=l.getInstance(),this.eventBus=E.getInstance(),this.configManager=new u(t),this.stateManager=new h,void 0!==t.logLevel){const s="string"==typeof t.logLevel?e.LogLevel[t.logLevel]:t.logLevel;this.logger.setLevel(s)}!1===t.enableLog&&this.logger.setEnabled(!1),this.apiService=new G(t,this.logger),this.socketService=new x(t,this.logger),this.storageService=new F(this.logger),this.fileService=new P(this.apiService,this.logger),this.traceLogService=new B(t,this.logger),this.message=new q(this.apiService,this.socketService,this.storageService,this.fileService,this.logger),this.conversation=new K(this.apiService,this.storageService,this.logger),this.group=new z(this.apiService,this.logger),this.user=new V(this.apiService,this.logger),this.friend=new j(this.apiService,this.logger),this.logger.info("[IMSDK] SDK initialized")}static create(e){return W.instance||(W.instance=new W(e)),W.instance}static getInstance(){return W.instance}async login(t){this.logger.info("[IMSDK] Logging in:",t.userId);try{let s=t.token,r=0;if(!s){const e=await this.apiService.getToken({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userId:t.userId,userName:t.userName,userAvatar:t.userAvatar});s=e.token,r=e.expireIn}return this.apiService.setToken(s),this.stateManager.setToken(s),this.stateManager.setUserId(t.userId),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(s),this.traceLogService.setUserId(t.userId),this.message.setCurrentUserId(t.userId),this.conversation.setCurrentUserId(t.userId),this.friend.setCurrentUserId(t.userId),await this.storageService.init(),await this.socketService.connect(s,t.userId),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userId,token:s,expireTime:r}),this.logger.info("[IMSDK] Login successful"),{userId:t.userId,token:s,expireTime:r}}catch(t){throw this.logger.error("[IMSDK] Login failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async register(t){this.logger.info("[IMSDK] Registering user:",t.userName);try{const s=await this.apiService.registerWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:t.userName,password:t.password,userAvatar:t.userAvatar,companyName:t.companyName}),r=s.token,a=s.expireIn;return this.apiService.setToken(r),this.stateManager.setToken(r),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(r),this.message.setCurrentUserId(t.userName),this.conversation.setCurrentUserId(t.userName),this.friend.setCurrentUserId(t.userName),await this.storageService.init(),await this.socketService.connect(r,t.userName),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userName,token:r,expireTime:a}),this.logger.info("[IMSDK] Registration and login successful"),{userId:t.userName,token:r,expireTime:a}}catch(t){throw this.logger.error("[IMSDK] Registration failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async loginWithPassword(t){this.logger.info("[IMSDK] Logging in with password:",t.userName);try{const s=await this.apiService.loginWithPassword({appId:this.configManager.getConfig().appId,appSecret:this.configManager.getConfig().appSecret,userName:t.userName,password:t.password}),r=s.token,a=s.expireIn;return this.apiService.setToken(r),this.stateManager.setToken(r),this.stateManager.setUserId(t.userName),this.stateManager.setLoginStatus(!0),this.traceLogService.setToken(r),this.traceLogService.setUserId(t.userName),this.message.setCurrentUserId(t.userName),this.conversation.setCurrentUserId(t.userName),this.friend.setCurrentUserId(t.userName),await this.storageService.init(),await this.socketService.connect(r,t.userName),this.eventBus.emitEvent(e.IMEventType.LOGIN_SUCCESS,{userId:t.userName,token:r,expireTime:a}),this.logger.info("[IMSDK] Login with password successful"),{userId:t.userName,token:r,expireTime:a}}catch(t){throw this.logger.error("[IMSDK] Login with password failed:",t),this.eventBus.emitEvent(e.IMEventType.LOGIN_FAILED,t),t}}async logout(){this.logger.info("[IMSDK] Logging out");try{this.socketService.disconnect(),this.stateManager.clear(),this.apiService.setToken(null),this.traceLogService.setToken(null),this.traceLogService.setUserId(null),this.eventBus.emitEvent(e.IMEventType.LOGOUT),this.logger.info("[IMSDK] Logout successful")}catch(e){throw this.logger.error("[IMSDK] Logout failed:",e),e}}destroy(){this.logger.info("[IMSDK] Destroying SDK instance"),this.isLoggedIn()&&this.logout().catch(()=>{}),this.eventBus.removeAllListeners(),this.traceLogService.destroy(),W.instance=null,this.logger.info("[IMSDK] SDK instance destroyed")}isLoggedIn(){return this.stateManager.isLoggedIn()}getCurrentUserId(){return this.stateManager.getUserId()}getConnectionStatus(){return this.socketService.getStatus()}on(e,t){this.eventBus.onEvent(e,t)}off(e,t){this.eventBus.offEvent(e,t)}once(e,t){this.eventBus.once(e,t)}setLogLevel(e){this.logger.setLevel(e)}setLogEnabled(e){this.logger.setEnabled(e)}static getVersion(){return"1.0.0"}getTraceLogService(){return this.traceLogService}async uploadFile(e,t){return this.fileService.uploadFile(e,{onProgress:t})}}W.instance=null,e.EventBus=E,e.IMError=d,e.IMSDK=W,e.Logger=l,e.TraceLogService=B,e.createIMSDK=function(e){return W.create(e)},e.default=W,e.formatDate=L,e.formatRelativeTime=function(e){if(!e)return"";let t;if(e instanceof Date)t=e;else if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);if(isNaN(t.getTime()))return String(e);const s=new Date,r=s.getTime()-t.getTime();return r<0||r>31536e6?L(t,"YYYY/MM/DD"):r<6e4?"刚刚":r<36e5?`${Math.floor(r/6e4)}分钟前`:r<864e5?t.getDate()===s.getDate()&&t.getMonth()===s.getMonth()&&t.getFullYear()===s.getFullYear()?`今天 ${L(t,"HH:mm")}`:`昨天 ${L(t,"HH:mm")}`:r<6048e5?`${Math.floor(r/864e5)}天前`:t.getFullYear()===s.getFullYear()?L(t,"MM/DD"):L(t,"YYYY/MM/DD")},e.parseDate=function(e){if(!e)return null;let t;if("string"==typeof e){const s=e.replace(/-/g,"/").replace(" ","T")+"Z";t=new Date(s),isNaN(t.getTime())&&(t=new Date(e.replace(/-/g,"/")))}else t=new Date(e);return isNaN(t.getTime())?null:t},Object.defineProperty(e,"__esModule",{value:!0})});
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@anyaipartner/im-sdk",
3
+ "version": "2.0.1",
4
+ "description": "Official IM SDK for Comind - A powerful instant messaging solution for web applications",
5
+ "publishConfig": {
6
+ "registry": "https://registry.npmjs.org/",
7
+ "access": "public"
8
+ },
9
+ "main": "dist/index.js",
10
+ "module": "dist/index.esm.js",
11
+ "types": "dist/index.d.ts",
12
+ "unpkg": "dist/index.umd.min.js",
13
+ "jsdelivr": "dist/index.umd.min.js",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "import": "./dist/index.esm.js",
18
+ "require": "./dist/index.js"
19
+ }
20
+ },
21
+ "scripts": {
22
+ "build": "npm run clean && npm run build:rollup && npm run build:types && npm run cleanup:dist",
23
+ "build:rollup": "rollup -c rollup.config.mjs",
24
+ "build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
25
+ "cleanup:dist": "node scripts/cleanup-dist.js",
26
+ "clean": "node -e \"require('fs').rmSync('dist', {recursive: true, force: true})\"",
27
+ "dev": "rollup -c rollup.config.mjs -w",
28
+ "test": "jest",
29
+ "test:watch": "jest --watch",
30
+ "lint": "eslint src --ext .ts",
31
+ "lint:fix": "eslint src --ext .ts --fix",
32
+ "format": "prettier --write \"src/**/*.ts\"",
33
+ "prepublishOnly": "npm run build",
34
+ "version:patch": "npm version patch -m \"chore: release v%s\"",
35
+ "version:minor": "npm version minor -m \"chore: release v%s\"",
36
+ "version:major": "npm version major -m \"chore: release v%s\"",
37
+ "release": "npm run build && npm publish"
38
+ },
39
+ "keywords": [
40
+ "im",
41
+ "chat",
42
+ "messaging",
43
+ "websocket",
44
+ "socket.io",
45
+ "web",
46
+ "browser",
47
+ "typescript",
48
+ "instant-messaging",
49
+ "real-time",
50
+ "comind"
51
+ ],
52
+ "author": {
53
+ "name": "Comind Team",
54
+ "email": "support@comind.com"
55
+ },
56
+ "license": "MIT",
57
+ "repository": {
58
+ "type": "git",
59
+ "url": "https://github.com/comind/comind-im-sdk.git"
60
+ },
61
+ "bugs": {
62
+ "url": "https://github.com/comind/comind-im-sdk/issues"
63
+ },
64
+ "homepage": "https://github.com/comind/comind-im-sdk#readme",
65
+ "dependencies": {
66
+ "axios": "^1.6.0",
67
+ "eventemitter3": "^5.0.1",
68
+ "socket.io-client": "^2.5.0"
69
+ },
70
+ "devDependencies": {
71
+ "@rollup/plugin-commonjs": "^25.0.0",
72
+ "@rollup/plugin-node-resolve": "^15.0.0",
73
+ "@rollup/plugin-terser": "^0.4.0",
74
+ "@rollup/plugin-typescript": "^11.0.0",
75
+ "@types/jest": "^30.0.0",
76
+ "@types/node": "^20.0.0",
77
+ "@types/socket.io-client": "^1.4.36",
78
+ "@typescript-eslint/eslint-plugin": "^6.0.0",
79
+ "@typescript-eslint/parser": "^6.0.0",
80
+ "eslint": "^8.0.0",
81
+ "jest": "^30.2.0",
82
+ "prettier": "^3.0.0",
83
+ "rollup": "^4.0.0",
84
+ "rollup-plugin-dts": "^6.3.0",
85
+ "ts-jest": "^29.4.5",
86
+ "tslib": "^2.8.1",
87
+ "typescript": "^5.0.0"
88
+ },
89
+ "files": [
90
+ "dist",
91
+ "README.md",
92
+ "LICENSE"
93
+ ]
94
+ }