@typexim/web-sdk 0.0.4-alpha.4 → 0.0.4-alpha.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -48,7 +48,7 @@ chat.once(
48
48
  1. SDK_READY
49
49
  2. SDK_NOT_READY
50
50
  3. MESSAGE_RECEIVED
51
- 4. MESSAGE_UPDATED
51
+ 4. MESSAGE_RECALLED
52
52
  5. MESSAGE_RECEIPT_RECEIVED
53
53
  6. FEED_LIST_UPDATED
54
54
  7. ROOM_MESSAGE_RECEIVED
@@ -65,6 +65,16 @@ export declare enum ChatType {
65
65
  */
66
66
  groupChat = 2
67
67
  }
68
+ export declare enum FeedType {
69
+ /**
70
+ * 常规
71
+ */
72
+ normal = 0,
73
+ /**
74
+ * 消息串
75
+ */
76
+ thread = 1
77
+ }
68
78
  export declare enum MessageKind {
69
79
  text = 0,//普通
70
80
  system = 1
@@ -81,11 +91,6 @@ export declare enum MessageType {
81
91
  richText = 8,//富文本消息
82
92
  custom = 9
83
93
  }
84
- export declare enum MessageSendStatus {
85
- success = 0,
86
- sending = 1,
87
- failed = 2
88
- }
89
94
  /** 群成员角色 */
90
95
  export declare enum GroupRole {
91
96
  Owner = 1,
@@ -94,14 +99,12 @@ export declare enum GroupRole {
94
99
  Bot = 4
95
100
  }
96
101
  export declare enum MessageOperation {
97
- normal = 0,//正常
102
+ /**
103
+ * 正常
104
+ */
105
+ normal = 0,
106
+ /**
107
+ * 撤回
108
+ */
98
109
  recall = 1
99
110
  }
100
- export declare enum GroupType {
101
- /** 加密群聊 */
102
- private = 1,
103
- /** 超级群聊 */
104
- public = 0,
105
- /** 匿名群聊,新增群聊类型 */
106
- anonymous = 2
107
- }
@@ -1,4 +1,4 @@
1
- import { Feed, Message, PushMessageUpdateMessage } from './interfaces';
1
+ import { Feed, Message } from './interfaces';
2
2
  export declare const CHAT_SDK_EVENT: {
3
3
  /**
4
4
  * sdk用户已登录,可以调用发送消息等API
@@ -17,9 +17,9 @@ export declare const CHAT_SDK_EVENT: {
17
17
  */
18
18
  readonly MESSAGE_RECEIVED: "messageReceived";
19
19
  /**
20
- * message有更新
20
+ * message撤回
21
21
  */
22
- readonly MESSAGE_UPDATED: "messageUpdated";
22
+ readonly MESSAGE_RECALLED: "messageRecalled";
23
23
  /**
24
24
  * sdk收到message已读回执
25
25
  */
@@ -33,11 +33,31 @@ export type CHAT_SDK_EVENT_MAP = {
33
33
  [CHAT_SDK_EVENT.SDK_READY]: void;
34
34
  [CHAT_SDK_EVENT.SDK_NOT_READY]: void;
35
35
  [CHAT_SDK_EVENT.FEED_LIST_UPDATED]: {
36
+ /**
37
+ * feed同步是否完成
38
+ */
36
39
  is_sync_completed: boolean;
40
+ /**
41
+ * feed列表
42
+ */
37
43
  list: Feed[];
38
44
  };
39
- [CHAT_SDK_EVENT.MESSAGE_RECEIVED]: Message;
40
- [CHAT_SDK_EVENT.MESSAGE_UPDATED]: PushMessageUpdateMessage['content'];
45
+ [CHAT_SDK_EVENT.MESSAGE_RECEIVED]: {
46
+ /**
47
+ * 收到的消息所属的feed_id
48
+ */
49
+ feed_id: string;
50
+ /**
51
+ * 收到的消息
52
+ */
53
+ message: Message;
54
+ };
55
+ [CHAT_SDK_EVENT.MESSAGE_RECALLED]: {
56
+ /**
57
+ * 撤回的消息id列表
58
+ */
59
+ message_ids: string[];
60
+ };
41
61
  [CHAT_SDK_EVENT.MESSAGE_RECEIPT_RECEIVED]: {
42
62
  /**
43
63
  * feed id
@@ -52,5 +72,10 @@ export type CHAT_SDK_EVENT_MAP = {
52
72
  */
53
73
  reader_user_ids: string[];
54
74
  };
55
- [CHAT_SDK_EVENT.ROOM_MESSAGE_RECEIVED]: string;
75
+ [CHAT_SDK_EVENT.ROOM_MESSAGE_RECEIVED]: {
76
+ /**
77
+ * 收到的消息
78
+ */
79
+ content: string;
80
+ };
56
81
  };
@@ -1,4 +1,4 @@
1
- import { ChatType, MessageKind, MessageOperation, MessageType } from '../enums';
1
+ import { ChatType, FeedType, MessageKind, MessageOperation, MessageType } from '../enums';
2
2
  export type ApiResponse<T = any> = {
3
3
  code: number;
4
4
  data: T;
@@ -29,19 +29,27 @@ export type Feed = {
29
29
  */
30
30
  id: string;
31
31
  /**
32
- * 会话id
32
+ * feed类型
33
+ */
34
+ feed_type: FeedType;
35
+ /**
36
+ * chat id,feed和在这个feed发起的消息串chat_id相同
33
37
  */
34
38
  chat_id: string;
35
39
  /**
36
- * 单聊时对方的id
40
+ * 消息串id
41
+ */
42
+ thread_id: string;
43
+ /**
44
+ * 单聊时对方的user_id
37
45
  */
38
46
  target_id: string;
39
47
  /**
40
- * 聊天类型
48
+ * chat类型
41
49
  */
42
50
  chat_type: ChatType;
43
51
  /**
44
- * 会话成员id
52
+ * 会话成员的user_id列表
45
53
  */
46
54
  chat_member: string[];
47
55
  /**
@@ -111,9 +119,13 @@ export type Message = {
111
119
  */
112
120
  id: string;
113
121
  /**
114
- * chat id
122
+ * chat id,feed和在这个feed发起的消息串chat_id相同
115
123
  */
116
124
  chat_id: string;
125
+ /**
126
+ * 消息串id
127
+ */
128
+ thread_id: string;
117
129
  /**
118
130
  * 消息位置
119
131
  */
@@ -142,6 +154,10 @@ export type Message = {
142
154
  * 已读信息的用户id
143
155
  */
144
156
  reader_ids: string[];
157
+ /**
158
+ * 未读信息的用户id
159
+ */
160
+ unreader_ids: string[];
145
161
  /**
146
162
  * 存放对某些隐藏消息的用户的Id
147
163
  */
@@ -14,7 +14,7 @@ export type PushMessageBigPackage = PushMessageBase<PushMessageType.BIG_PACKAGE_
14
14
  export type PushMessageCreateFeed = PushMessageBase<PushMessageType.CREATE_FEED, Feed>;
15
15
  export type PushMessageUpdateFeeds = PushMessageBase<PushMessageType.UPDATE_FEED>;
16
16
  export type PushMessageAddMessage = PushMessageBase<PushMessageType.ADD_MESSAGE, Message>;
17
- export type PushMessageUpdateMessage = PushMessageBase<PushMessageType.UPDATE_MESSAGE, Pick<Message, 'chat_id' | 'content' | 'id' | 'message_kind_id' | 'message_type_id' | 'operation' | 'operation_user_id' | 'position'>>;
17
+ export type PushMessageUpdateMessage = PushMessageBase<PushMessageType.UPDATE_MESSAGE, Partial<Message> & Pick<Message, 'id' | 'chat_id' | 'thread_id'>>;
18
18
  export type PushMessageDeleteFeed = PushMessageBase<PushMessageType.DELETE_FEED, {
19
19
  /**
20
20
  * feed id
@@ -26,7 +26,7 @@ export type PushMessageReadMessage = PushMessageBase<PushMessageType.READ_MESSAG
26
26
  chat_id: string;
27
27
  message_ids: string[];
28
28
  reader_ids: string[];
29
- threadid: string;
29
+ thread_id: string;
30
30
  }>;
31
31
  export type SpecialPushMessage = PushMessagePong | PushMessageBigPackage | PushMessageCreateFeed | PushMessageUpdateFeeds | PushMessageAddMessage | PushMessageUpdateMessage | PushMessageDeleteFeed | PushMessagePushLiveMessage | PushMessageReadMessage;
32
32
  export type PushMessage = PushMessageBase<Exclude<PushMessageType, SpecialPushMessage['type']>> | SpecialPushMessage;
@@ -1,17 +1,21 @@
1
1
  import { Feed } from '../interfaces';
2
2
  export default class FeedCache {
3
- private _isSyncCompleted;
3
+ private syncCompleted;
4
4
  private map;
5
5
  private chatMap;
6
+ private threadMap;
6
7
  private list;
7
8
  private waitMap;
8
9
  constructor();
9
10
  getAll(): Feed[];
10
11
  get(feedId: string): Feed | null;
11
- getByChatId(chatId: string): Feed | null;
12
+ getByChat(chatId: string, threadId: string): Feed | null;
12
13
  waitFor(feedId: string): Promise<Feed | null>;
13
14
  private resolveWait;
15
+ private removeFromList;
14
16
  remove(feedId: string): boolean;
17
+ private beforeSave;
18
+ private afterSave;
15
19
  push(feed: Feed): void;
16
20
  unshift(feed: Feed): void;
17
21
  update(feed: Feed): void;
@@ -7,7 +7,7 @@ export default class Logger {
7
7
  private createLogHandler;
8
8
  private log;
9
9
  setLogLevel(level: LogLevel): void;
10
- info(message: any, ...args: any[]): void;
11
- warn(message: any, ...args: any[]): void;
12
- error(message: any, ...args: any[]): void;
10
+ info(...args: any[]): void;
11
+ warn(...args: any[]): void;
12
+ error(...args: any[]): void;
13
13
  }
@@ -0,0 +1 @@
1
+ export declare function getCurrentISOString(): string;
@@ -1 +1 @@
1
- import e from"js-cookie";import t from"axios";import i from"crypto-js";var s,n,o,r,a,l,c,d,h,u,_,g;!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(s||(s={})),function(e){e[e.CREATE_FEED=0]="CREATE_FEED",e[e.UPDATE_FEED=1]="UPDATE_FEED",e[e.ADD_MESSAGE=2]="ADD_MESSAGE",e[e.UPDATE_MESSAGE=3]="UPDATE_MESSAGE",e[e.UPDATE_USER_DATA=4]="UPDATE_USER_DATA",e[e.USER_LOGIN=5]="USER_LOGIN",e[e.READ_MESSAGE=6]="READ_MESSAGE",e[e.PONG_MESSAGE=8]="PONG_MESSAGE",e[e.DELETE_MESSAGE=9]="DELETE_MESSAGE",e[e.UPDATE_GROUP=12]="UPDATE_GROUP",e[e.DELETE_GROUP=13]="DELETE_GROUP",e[e.UPDATE_LOGIN_USER=17]="UPDATE_LOGIN_USER",e[e.UPDATE_MESSAGE_REACTION=19]="UPDATE_MESSAGE_REACTION",e[e.ADD_GROUP_MEMBER=21]="ADD_GROUP_MEMBER",e[e.DEL_GROUP_MEMBER=22]="DEL_GROUP_MEMBER",e[e.ADD_CONTACTS=23]="ADD_CONTACTS",e[e.UPDATE_CONTACTS=24]="UPDATE_CONTACTS",e[e.DEL_CONTACTS=25]="DEL_CONTACTS",e[e.BLOCK_USER=26]="BLOCK_USER",e[e.DEVICE_CODE=27]="DEVICE_CODE",e[e.MSG_OPEN_CLOCK=28]="MSG_OPEN_CLOCK",e[e.DELETE_SECRET_CHAT=29]="DELETE_SECRET_CHAT",e[e.DELETE_FEED=30]="DELETE_FEED",e[e.FAVORITE_UPDATE=31]="FAVORITE_UPDATE",e[e.STICKERS_UPDATE=32]="STICKERS_UPDATE",e[e.CUSTOM_STICKERS_UPDATE=33]="CUSTOM_STICKERS_UPDATE",e[e.MANAGE_DEVICE_UPDATE=34]="MANAGE_DEVICE_UPDATE",e[e.MASS_MESSAGE_UPDATE=35]="MASS_MESSAGE_UPDATE",e[e.CHAT_WALLPAPER_DELETE=36]="CHAT_WALLPAPER_DELETE",e[e.CHAT_WALLPAPER_ADD=37]="CHAT_WALLPAPER_ADD",e[e.CONTACT_REQUEST=40]="CONTACT_REQUEST",e[e.USER_PREFERENCE_CHANGE=38]="USER_PREFERENCE_CHANGE",e[e.UPDATE_GROUP_PIN=41]="UPDATE_GROUP_PIN",e[e.RTC_CANCEL=46]="RTC_CANCEL",e[e.ADD_FEED_FOLDER=43]="ADD_FEED_FOLDER",e[e.UPDATE_FEED_FOLDER=44]="UPDATE_FEED_FOLDER",e[e.UPDATE_FOLDER_FEED_LIST=47]="UPDATE_FOLDER_FEED_LIST",e[e.DELETE_FEED_FOLDER=45]="DELETE_FEED_FOLDER",e[e.UPDATE_CHATTER=42]="UPDATE_CHATTER",e[e.PAPER_KEY=48]="PAPER_KEY",e[e.PAPER_KEY_LOG=49]="PAPER_KEY_LOG",e[e.USER_LOGIN_SCAN=50]="USER_LOGIN_SCAN",e[e.RTC_RINGING=51]="RTC_RINGING",e[e.ON_UPDATE_PRIVATE_SETTING=52]="ON_UPDATE_PRIVATE_SETTING",e[e.ON_DELETE_PRIVATE_SETTING=53]="ON_DELETE_PRIVATE_SETTING",e[e.ON_UPDATE_LOGIN_PRIVATE_SETTING=54]="ON_UPDATE_LOGIN_PRIVATE_SETTING",e[e.PUSH_LIVE_MESSAGE=56]="PUSH_LIVE_MESSAGE",e[e.BIG_PACKAGE_PUSH=126]="BIG_PACKAGE_PUSH",e[e.KICK_OUT_DEVICE=127]="KICK_OUT_DEVICE",e[e.CLEAR_HISTORY=128]="CLEAR_HISTORY",e[e.CLEAR_DATA=255]="CLEAR_DATA"}(n||(n={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(o||(o={})),function(e){e[e.text=0]="text",e[e.system=1]="system"}(r||(r={})),function(e){e[e.text=0]="text",e[e.image=1]="image",e[e.card=2]="card",e[e.audio=3]="audio",e[e.video=4]="video",e[e.file=5]="file",e[e.mergeForward=6]="mergeForward",e[e.sticker=7]="sticker",e[e.richText=8]="richText",e[e.custom=9]="custom"}(a||(a={})),function(e){e[e.success=0]="success",e[e.sending=1]="sending",e[e.failed=2]="failed"}(l||(l={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(c||(c={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(d||(d={})),function(e){e[e.private=1]="private",e[e.public=0]="public",e[e.anonymous=2]="anonymous"}(h||(h={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(u||(u={})),function(e){e[e.SDK_ERROR=-1e4]="SDK_ERROR",e[e.NETWORK_ERROR=-9999]="NETWORK_ERROR",e[e.MAKE_SIGN_FAIL=-9998]="MAKE_SIGN_FAIL",e[e.REQUEST_SINGLETON_LOCK_FAIL=-9997]="REQUEST_SINGLETON_LOCK_FAIL",e[e.SUCCESS=0]="SUCCESS"}(_||(_={})),function(e){e[e.up=0]="up",e[e.down=1]="down"}(g||(g={}));var E=Object.freeze({__proto__:null,get Boolean(){return s},get ChatType(){return o},get GroupRole(){return c},get GroupType(){return h},get HttpClientResponseCode(){return _},get LogLevel(){return u},get MessageKind(){return r},get MessageOperation(){return d},get MessageSendStatus(){return l},get MessageType(){return a},get PushMessageType(){return n},get RequestDirection(){return g}});const p={SDK_READY:"sdkReady",SDK_NOT_READY:"sdkNotReady",FEED_LIST_UPDATED:"feedListUpdated",MESSAGE_RECEIVED:"messageReceived",MESSAGE_UPDATED:"messageUpdated",MESSAGE_RECEIPT_RECEIVED:"messageReceiptReceived",ROOM_MESSAGE_RECEIVED:"roomMessageReceived"};var m=Object.freeze({__proto__:null,CHAT_SDK_EVENT:p}),f=Object.freeze({__proto__:null});function b(e,t){return{ok:!1,code:e,msg:t}}function S(e){return{ok:!0,data:e}}const C=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},T=e=>{const t=C(e);if(null!==t){let e;return null!=t.content&&(e=C(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class A{constructor(e){Object.defineProperty(this,"all",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.all=e||new Map}on(e,t){const i=this.all.get(e);return i?i.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const i=this.all.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let i=this.all.get(e);i&&i.slice().map(e=>{e(t)}),i=this.all.get("*"),i&&i.slice().map(i=>{i(e,t)})}once(e,t){if("*"===e){const i=(e,s)=>{t(e,s),this.off("*",i)};this.on(e,i)}else{const i=s=>{t(s),this.off(e,i)};this.on(e,i)}}}class w extends A{constructor(e){super(),Object.defineProperty(this,"url",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"destroyed",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pingTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pongTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"reConnectTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.url=e.url,this.logger=e.logger,this.ws=null,this.destroyed=!1,this.pingTimeout=null,this.pongTimeout=null,this.reConnectTimeout=null,this.reConnect=this.reConnect.bind(this),window.addEventListener("online",this.reConnect),this.connect()}disconnect(){this.ws&&(this.ws.onopen=null,this.ws.onerror=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.close(),this.ws=null),null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null),null!==this.reConnectTimeout&&(clearTimeout(this.reConnectTimeout),this.reConnectTimeout=null)}connect(){if(this.ws)return void this.logger.warn("ReConnectWebsocket try connect but already connected");const e=new WebSocket(this.url);this.ws=e,e.onopen=()=>{this.delaySendPing()},e.onerror=e=>{this.logger.info("ReConnectWebsocket error",e)},e.onmessage=e=>{try{const t=JSON.parse(e.data);if(t.type===n.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(t.id),t.type===n.BIG_PACKAGE_PUSH)for(const e of t.content.big_push)this.emit("message",e);else this.emit("message",t)}catch(e){this.logger.error("ReConnectWebsocket message parse failed",e)}},e.onclose=e=>{4001===e.code?this.kickOff():this.reConnect()}}reConnect(){this.disconnect(),this.destroyed||(this.reConnectTimeout=setTimeout(()=>{this.reConnectTimeout=null,this.connect()},5e3))}send(e){if(this.destroyed)return!1;if(!this.ws)return this.logger.warn("ReConnectWebsocket send before connect"),!1;try{return this.ws.readyState!==this.ws.OPEN?(this.logger.warn("ReConnectWebsocket send but not open",this.ws.readyState),!1):(this.ws.send(JSON.stringify(e)),!0)}catch(e){return this.logger.warn("ReConnectWebsocket send error",e),!1}}sendAck(e){this.send({type:1,ids:[e]})}destroy(){this.destroyed||(this.destroyed=!0,this.disconnect(),window.removeEventListener("online",this.reConnect))}delaySendPing(){null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.pingTimeout=setTimeout(()=>{this.pingTimeout=null;this.send({type:0})?this.waitPong():this.reConnect()},2e4)}waitPong(){this.pongTimeout=setTimeout(()=>{this.logger.info("ReConnectWebsocket pong timeout"),this.reConnect()},1e4)}kickOff(){this.destroy(),this.emit("kickoff")}}class y extends A{constructor(e){super(),Object.defineProperty(this,"host",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(null===this.context.loginUser)return void this.logger.warn("BusinessWebsocket try connect but not login");if(this.ws)return void this.logger.warn("BusinessWebsocket try connect but already connected");const e=`${this.host}/ws?token=${this.context.loginUser.sessionId}&platform=web`;this.ws=new w({url:e,logger:this.logger}),this.ws.on("message",e=>{this.emit("message",e)}),this.ws.on("kickoff",()=>{this.emit("kickoff")})}disconnect(){this.ws?(this.ws.destroy(),this.ws=null):this.logger.info("BusinessWebsocket already disconnected")}}class R{constructor(){Object.defineProperty(this,"_isSyncCompleted",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"map",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"chatMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"list",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"waitMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._isSyncCompleted=!1,this.map=new Map,this.chatMap=new Map,this.waitMap=new Map,this.list=[]}getAll(){const e=[];for(const t of this.list){const i=this.map.get(t);i&&e.push(i)}return e}get(e){return this.map.get(e)??null}getByChatId(e){const t=this.chatMap.get(e);return void 0!==t?this.get(t):null}async waitFor(e){const t=this.get(e);if(t)return t;if(this._isSyncCompleted)return null;let i=this.waitMap.get(e);return i||(i=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,i)),await i.promise,this.get(e)}resolveWait(e){const t=this.waitMap.get(e);t&&(t.resolve(!0),this.waitMap.delete(e))}remove(e){const t=this.map.get(e);return!!t&&(this.map.delete(e),this.chatMap.delete(t.chat_id),this.list.splice(this.list.indexOf(e),1),!0)}push(e){this.remove(e.id),this.map.set(e.id,e),this.list.push(e.id),this.chatMap.set(e.chat_id,e.id),this.resolveWait(e.id)}unshift(e){this.remove(e.id),this.map.set(e.id,e),this.list.unshift(e.id),this.chatMap.set(e.chat_id,e.id),this.resolveWait(e.id)}update(e){this.map.has(e.id)&&this.map.set(e.id,e)}markSyncComplete(){this._isSyncCompleted=!0;for(const[e,t]of this.waitMap)t.resolve(!0);this.waitMap.clear()}isSyncCompleted(){return this._isSyncCompleted}reset(){this._isSyncCompleted=!1,this.map.clear(),this.chatMap.clear(),this.waitMap.clear(),this.list=[]}}function v(e){return(new TextEncoder).encode(e).buffer}async function P(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=v(t),s=v(e),n=await crypto.subtle.importKey("raw",i,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,s);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return i.HmacSHA256(e,t).toString(i.enc.Hex)}(e,t)}const D=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=D(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=D(e[s]);return i}};function O(){return b(_.MAKE_SIGN_FAIL,"make sign fail")}class L{constructor(e){Object.defineProperty(this,"api",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.api=t.create({baseURL:e.host,headers:{"x-developer":e.developer}}),this.context=e.context,this.logger=e.logger}async request(e){try{const{needSign:t=!0,...i}=e;if(i.headers||(i.headers={}),i.headers.platform="web",t&&"POST"===e.method?.toUpperCase()&&i.data){if(null===this.context.loginUser)return this.logger.warn("HttpClient needs make sign but not login"),O();try{const e=await(async(e,t)=>{const i=await D(e);return await P(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),O()}}const s=await this.api(i),n=s.data;return n.code===_.SUCCESS?{ok:!0,data:n.data}:(this.logger.info("HttpClient server error",s),{ok:!1,code:n.code,msg:n.msg,msg_i18n:n.msg_i18n})}catch{return{ok:!1,code:_.NETWORK_ERROR,msg:"network error"}}}get(e,t,i){return this.request({url:e,method:"GET",params:t,...i})}post(e,t,i){return this.request({url:e,method:"POST",data:t,...i})}}class U{constructor(){Object.defineProperty(this,"level",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logHandler",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.level=u.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case u.error:return 3;case u.warning:return 2;case u.info:return 1;default:return 0}}createLogHandler(){return(e,t,...i)=>{const s=`[tlog] ${(new Date).toISOString().split("T")[0]}`,n=t?`${s} ${t}`:s;switch(e){case u.error:console.error(n,...i);break;case u.warning:console.warn(n,...i);break;case u.info:console.info(n,...i);break;default:console.log(n,...i)}}}log(e,t,...i){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,t,...i)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(e,...t){this.log(u.info,e,...t)}warn(e,...t){this.log(u.warning,e,...t)}error(e,...t){this.log(u.error,e,...t)}}class I{constructor(e){Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"emitter",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"handleKickoff",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(p.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}processCreateFeed(e){this.feedCache.unshift(e.content),this.emitFeedListUpdated()}processDeleteFeed(e){this.feedCache.remove(e.content.id)&&this.emitFeedListUpdated()}processAddMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,s=this.feedCache.getByChatId(i.chat_id);if(null!==s){let e=!1;const n={};if(i.message_kind_id!==r.system&&i.sender_id!==t){e=!0;const t=new Set(s.unread_message_ids);t.add(i.id),n.unread_message_ids=[...t],n.badge=t.size}s.last_message_position<i.position&&(e=!0,n.last_message_id=i.id,n.last_message_position=i.position,n.last_message_sender_id=i.sender_id,n.last_message_send_at=i.send_at,n.last_message_kind_id=i.message_kind_id,n.last_message_type_id=i.message_type_id,n.last_message=i.content,n.last_message_operation=i.operation,n.last_message_operation_user_id=i.operation_user_id),e&&(this.feedCache.unshift({...s,...n}),this.emitFeedListUpdated()),this.emitter.emit(p.MESSAGE_RECEIVED,i)}}processUpdateMessage(e){const t=e.content;if(t.operation===d.recall){const i=this.feedCache.getByChatId(e.content.chat_id);if(null!==i){let e=!1;const s={};if(null!=i.unread_message_ids&&i.unread_message_ids.includes(t.id)){e=!0;const n=new Set(i.unread_message_ids);n.delete(t.id),s.unread_message_ids=[...n],s.badge=s.unread_message_ids.length}i.last_message_id===t.id&&(e=!0,s.last_message=t.content,s.last_message_operation=t.operation,s.last_message_operation_user_id=t.operation_user_id),e&&(this.feedCache.unshift({...i,...s}),this.emitFeedListUpdated())}}this.emitter.emit(p.MESSAGE_UPDATED,t)}processPushLiveMessage(e){this.emitter.emit(p.ROOM_MESSAGE_RECEIVED,e.content)}processReadMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=this.feedCache.getByChatId(e.content.chat_id);if(null!==i){let s=!1;const n={};if(e.content.reader_ids.includes(t)&&e.content.message_ids.length>0){s=!0;const t=new Set(i.unread_message_ids);e.content.message_ids.forEach(e=>{t.delete(e)}),n.unread_message_ids=[...t],n.badge=t.size}s&&(this.feedCache.update({...i,...n}),this.emitFeedListUpdated()),this.emitter.emit(p.MESSAGE_RECEIPT_RECEIVED,{feed_id:i.id,message_ids:e.content.message_ids,reader_user_ids:e.content.reader_ids})}}processKickOutDevice(){this.handleKickoff()}process(e){switch(this.logger.info("PushMessageProcessor process",e),e.type){case n.CREATE_FEED:this.processCreateFeed(e);break;case n.DELETE_FEED:this.processDeleteFeed(e);break;case n.ADD_MESSAGE:this.processAddMessage(e);break;case n.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case n.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case n.READ_MESSAGE:this.processReadMessage(e);break;case n.KICK_OUT_DEVICE:this.processKickOutDevice()}}}class k{constructor(){Object.defineProperty(this,"obtained",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"abortLockObtain",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.obtained=!1,this.abortLockObtain=null}async requestLock(){if(this.obtained)return!0;let e=()=>{};const t=new Promise(t=>{e=t}),i=new Promise(e=>{this.abortLockObtain=e});navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{t?(this.obtained=!0,e(!0),await i):e(!1)});return await t}releaseLock(){this.obtained=!1,null!==this.abortLockObtain&&(this.abortLockObtain(),this.abortLockObtain=null)}}class M{static set(e){localStorage.setItem(this.key,JSON.stringify(e))}static get(){try{const e=localStorage.getItem(this.key);if(!e)return null;return JSON.parse(e)}catch{return null}}static clear(){localStorage.removeItem(this.key)}}Object.defineProperty(M,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class G{constructor(){Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class x extends A{constructor(e){super(),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"singletonLock",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"httpClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pushMessageProcessor",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context={isLogin:!1,loginUser:null,isReady:!1,deviceId:null},this.version=new G,this.singletonLock=new k,this.logger=new U,this.httpClient=new L({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new R,this.ws=new y({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new I({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.afterLogout()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.afterLogout()})}async requestDeviceId(){if(this.context.deviceId)return!0;const e=await this.httpClient.post("/device_api/device_id",{platform:"web",hash_str:""},{needSign:!1});return!!e.ok&&(this.context.deviceId=e.data,this.saveContext(),!0)}saveContext(){const{context:e}=this;M.set({deviceId:e.deviceId})}loadContext(){const e=M.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.ws.connect(),this.loadFeedList(),this.context.isReady=!0,this.emit(p.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(p.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const i=await this.httpClient.get("/feed",{limit:500,last_refresh_at:t.refresh_at??void 0,last_feed_id:t.feed_id??void 0});if(!this.version.check(e))break;if(!i.ok)break;if(t.refresh_at=i.data.refresh_at,t.feed_id=i.data.last_feed_id,i.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!i.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(p.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:!0}))}isReady(){return this.context.isReady}setLogLevel(e){this.logger.setLogLevel(e)}async login(t){if(this.context.isLogin)return S(null);if(!await this.singletonLock.requestLock())return this.logger.error("Another active TypeX SDK instance detected"),b(_.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),b(_.SDK_ERROR,"Get deviceId failed");const i=await this.httpClient.post("/user/session/login",{userCode:t.user_code,device_id:this.context.deviceId},{needSign:!1});if(!i.ok)return this.singletonLock.releaseLock(),i;const s=e.get("sessionid");return s?(this.context.isLogin=!0,this.context.loginUser={userId:i.data.id,secretKey:i.data.key,sessionId:s},this.applyLoginStatus(),S(null)):(this.singletonLock.releaseLock(),b(_.SDK_ERROR,"Get sessionId failed"))}async logout(){if(!this.context.isLogin)return S(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),S(null)):e}async afterLogout(){this.context.isLogin=!1,this.context.loginUser=null,this.applyLoginStatus()}getLoginUser(){return null===this.context.loginUser?null:this.context.loginUser.userId}async createSingleChatFeed(e){return await this.httpClient.post("/chat/single",{receiver_id:e})}async deleteFeed(e){return await this.httpClient.post("/feed/delete",{feed_id_list:[e],delete_peer:!0})}async getFeedList(){return S({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return S(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const i=t.data,{chat_id:s,first_position:n,last_message_position:o}=i,{positions:r,nextPosition:a,hasMore:l}=(e=>{const t=[];if(e.direction===g.up){let i=e.startPosition??e.maxPosition;for(;t.length<e.limit&&i>=e.minPosition;)t.push(i),i--;const s=i>=e.minPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}{let i=e.startPosition??e.minPosition;for(;t.length<e.limit&&i<=e.maxPosition;)t.push(i),i++;const s=i<=e.maxPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}})({maxPosition:o,minPosition:n,startPosition:e.message_position,limit:e.limit,direction:e.direction??g.up});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[s]:r}},{needSign:!1});if(e.ok&&e.data[s]){return S({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return S({has_more:!1,list:[]})}createCustomMessage(e){if(null===this.context.loginUser)return b(_.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return b(_.SDK_ERROR,"not found feed");var i;return S({id:"",chat_id:t.chat_id,position:t.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:r.text,message_type_id:a.custom,send_at:"",reader_ids:[],hide_ids:[],operation:d.normal,operation_user_id:"0",content:(i={client_msg_id:e.client_msg_id,content:e.content},JSON.stringify({client_msg_id:i.client_msg_id,content:JSON.stringify(i.content)}))})}async sendMessageToFeed(e){if(e.message_type_id===a.custom){const t=T(e.content);return this.httpClient.post("/message/send_custom",{chat_id:e.chat_id,client_id:t.client_msg_id,content:null==t.content?void 0:JSON.stringify(t.content)})}return b(_.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?b(_.SDK_ERROR,"not found feed"):await this.httpClient.post("/message/read",{chat_id:t.chat_id,message_ids:e.message_ids})}async joinRoom(e){return await this.httpClient.post("/liveshow/join",{room_id:e})}async leaveRoom(e){return await this.httpClient.post("/liveshow/leave",{room_id:e})}async getRoomRecentMessageList(e){const t=await this.httpClient.get("/liveshow/get_recent_message",{room_id:e});return t.ok?S(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const N=new Map;function F(e,t){let i=N.get(e);return void 0===i&&(i=new x(t),N.set(e,i)),i}const K={parseSystemMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:T};export{x as ChatSDK,F as create,E as enums,m as events,f as interfaces,K as utils};
1
+ import e from"js-cookie";import t from"axios";import i from"crypto-js";var s,n,o,r,a,l,c,d,h,u,_;!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(s||(s={})),function(e){e[e.CREATE_FEED=0]="CREATE_FEED",e[e.UPDATE_FEED=1]="UPDATE_FEED",e[e.ADD_MESSAGE=2]="ADD_MESSAGE",e[e.UPDATE_MESSAGE=3]="UPDATE_MESSAGE",e[e.UPDATE_USER_DATA=4]="UPDATE_USER_DATA",e[e.USER_LOGIN=5]="USER_LOGIN",e[e.READ_MESSAGE=6]="READ_MESSAGE",e[e.PONG_MESSAGE=8]="PONG_MESSAGE",e[e.DELETE_MESSAGE=9]="DELETE_MESSAGE",e[e.UPDATE_GROUP=12]="UPDATE_GROUP",e[e.DELETE_GROUP=13]="DELETE_GROUP",e[e.UPDATE_LOGIN_USER=17]="UPDATE_LOGIN_USER",e[e.UPDATE_MESSAGE_REACTION=19]="UPDATE_MESSAGE_REACTION",e[e.ADD_GROUP_MEMBER=21]="ADD_GROUP_MEMBER",e[e.DEL_GROUP_MEMBER=22]="DEL_GROUP_MEMBER",e[e.ADD_CONTACTS=23]="ADD_CONTACTS",e[e.UPDATE_CONTACTS=24]="UPDATE_CONTACTS",e[e.DEL_CONTACTS=25]="DEL_CONTACTS",e[e.BLOCK_USER=26]="BLOCK_USER",e[e.DEVICE_CODE=27]="DEVICE_CODE",e[e.MSG_OPEN_CLOCK=28]="MSG_OPEN_CLOCK",e[e.DELETE_SECRET_CHAT=29]="DELETE_SECRET_CHAT",e[e.DELETE_FEED=30]="DELETE_FEED",e[e.FAVORITE_UPDATE=31]="FAVORITE_UPDATE",e[e.STICKERS_UPDATE=32]="STICKERS_UPDATE",e[e.CUSTOM_STICKERS_UPDATE=33]="CUSTOM_STICKERS_UPDATE",e[e.MANAGE_DEVICE_UPDATE=34]="MANAGE_DEVICE_UPDATE",e[e.MASS_MESSAGE_UPDATE=35]="MASS_MESSAGE_UPDATE",e[e.CHAT_WALLPAPER_DELETE=36]="CHAT_WALLPAPER_DELETE",e[e.CHAT_WALLPAPER_ADD=37]="CHAT_WALLPAPER_ADD",e[e.CONTACT_REQUEST=40]="CONTACT_REQUEST",e[e.USER_PREFERENCE_CHANGE=38]="USER_PREFERENCE_CHANGE",e[e.UPDATE_GROUP_PIN=41]="UPDATE_GROUP_PIN",e[e.RTC_CANCEL=46]="RTC_CANCEL",e[e.ADD_FEED_FOLDER=43]="ADD_FEED_FOLDER",e[e.UPDATE_FEED_FOLDER=44]="UPDATE_FEED_FOLDER",e[e.UPDATE_FOLDER_FEED_LIST=47]="UPDATE_FOLDER_FEED_LIST",e[e.DELETE_FEED_FOLDER=45]="DELETE_FEED_FOLDER",e[e.UPDATE_CHATTER=42]="UPDATE_CHATTER",e[e.PAPER_KEY=48]="PAPER_KEY",e[e.PAPER_KEY_LOG=49]="PAPER_KEY_LOG",e[e.USER_LOGIN_SCAN=50]="USER_LOGIN_SCAN",e[e.RTC_RINGING=51]="RTC_RINGING",e[e.ON_UPDATE_PRIVATE_SETTING=52]="ON_UPDATE_PRIVATE_SETTING",e[e.ON_DELETE_PRIVATE_SETTING=53]="ON_DELETE_PRIVATE_SETTING",e[e.ON_UPDATE_LOGIN_PRIVATE_SETTING=54]="ON_UPDATE_LOGIN_PRIVATE_SETTING",e[e.PUSH_LIVE_MESSAGE=56]="PUSH_LIVE_MESSAGE",e[e.BIG_PACKAGE_PUSH=126]="BIG_PACKAGE_PUSH",e[e.KICK_OUT_DEVICE=127]="KICK_OUT_DEVICE",e[e.CLEAR_HISTORY=128]="CLEAR_HISTORY",e[e.CLEAR_DATA=255]="CLEAR_DATA"}(n||(n={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(o||(o={})),function(e){e[e.normal=0]="normal",e[e.thread=1]="thread"}(r||(r={})),function(e){e[e.text=0]="text",e[e.system=1]="system"}(a||(a={})),function(e){e[e.text=0]="text",e[e.image=1]="image",e[e.card=2]="card",e[e.audio=3]="audio",e[e.video=4]="video",e[e.file=5]="file",e[e.mergeForward=6]="mergeForward",e[e.sticker=7]="sticker",e[e.richText=8]="richText",e[e.custom=9]="custom"}(l||(l={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(c||(c={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(d||(d={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(h||(h={})),function(e){e[e.SDK_ERROR=-1e4]="SDK_ERROR",e[e.NETWORK_ERROR=-9999]="NETWORK_ERROR",e[e.MAKE_SIGN_FAIL=-9998]="MAKE_SIGN_FAIL",e[e.REQUEST_SINGLETON_LOCK_FAIL=-9997]="REQUEST_SINGLETON_LOCK_FAIL",e[e.SUCCESS=0]="SUCCESS"}(u||(u={})),function(e){e[e.up=0]="up",e[e.down=1]="down"}(_||(_={}));var g=Object.freeze({__proto__:null,get Boolean(){return s},get ChatType(){return o},get FeedType(){return r},get GroupRole(){return c},get HttpClientResponseCode(){return u},get LogLevel(){return h},get MessageKind(){return a},get MessageOperation(){return d},get MessageType(){return l},get PushMessageType(){return n},get RequestDirection(){return _}});const E={SDK_READY:"sdkReady",SDK_NOT_READY:"sdkNotReady",FEED_LIST_UPDATED:"feedListUpdated",MESSAGE_RECEIVED:"messageReceived",MESSAGE_RECALLED:"messageRecalled",MESSAGE_RECEIPT_RECEIVED:"messageReceiptReceived",ROOM_MESSAGE_RECEIVED:"roomMessageReceived"};var p=Object.freeze({__proto__:null,CHAT_SDK_EVENT:E}),f=Object.freeze({__proto__:null});function m(e,t){return{ok:!1,code:e,msg:t}}function b(e){return{ok:!0,data:e}}const C=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},S=e=>{const t=C(e);if(null!==t){let e;return null!=t.content&&(e=C(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class T{constructor(e){Object.defineProperty(this,"all",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.all=e||new Map}on(e,t){const i=this.all.get(e);return i?i.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const i=this.all.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let i=this.all.get(e);i&&i.slice().map(e=>{e(t)}),i=this.all.get("*"),i&&i.slice().map(i=>{i(e,t)})}once(e,t){if("*"===e){const i=(e,s)=>{t(e,s),this.off("*",i)};this.on(e,i)}else{const i=s=>{t(s),this.off(e,i)};this.on(e,i)}}}class A extends T{constructor(e){super(),Object.defineProperty(this,"url",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"destroyed",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pingTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pongTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"reConnectTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.url=e.url,this.logger=e.logger,this.ws=null,this.destroyed=!1,this.pingTimeout=null,this.pongTimeout=null,this.reConnectTimeout=null,this.reConnect=this.reConnect.bind(this),window.addEventListener("online",this.reConnect),this.connect()}disconnect(){this.ws&&(this.ws.onopen=null,this.ws.onerror=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.close(),this.ws=null),null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null),null!==this.reConnectTimeout&&(clearTimeout(this.reConnectTimeout),this.reConnectTimeout=null)}connect(){if(this.ws)return void this.logger.warn("ReConnectWebsocket try connect but already connected");const e=new WebSocket(this.url);this.ws=e,e.onopen=()=>{this.delaySendPing()},e.onerror=e=>{this.logger.info("ReConnectWebsocket error",e)},e.onmessage=e=>{try{const t=JSON.parse(e.data);if(t.type===n.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(t.id),t.type===n.BIG_PACKAGE_PUSH)for(const e of t.content.big_push)this.emit("message",e);else this.emit("message",t)}catch(e){this.logger.error("ReConnectWebsocket message parse failed",e)}},e.onclose=e=>{4001===e.code?this.kickOff():this.reConnect()}}reConnect(){this.disconnect(),this.destroyed||(this.reConnectTimeout=setTimeout(()=>{this.reConnectTimeout=null,this.connect()},5e3))}send(e){if(this.destroyed)return!1;if(!this.ws)return this.logger.warn("ReConnectWebsocket send before connect"),!1;try{return this.ws.readyState!==this.ws.OPEN?(this.logger.warn("ReConnectWebsocket send but not open",this.ws.readyState),!1):(this.ws.send(JSON.stringify(e)),!0)}catch(e){return this.logger.warn("ReConnectWebsocket send error",e),!1}}sendAck(e){this.send({type:1,ids:[e]})}destroy(){this.destroyed||(this.destroyed=!0,this.disconnect(),window.removeEventListener("online",this.reConnect))}delaySendPing(){null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.pingTimeout=setTimeout(()=>{this.pingTimeout=null;this.send({type:0})?this.waitPong():this.reConnect()},2e4)}waitPong(){this.pongTimeout=setTimeout(()=>{this.logger.info("ReConnectWebsocket pong timeout"),this.reConnect()},1e4)}kickOff(){this.destroy(),this.emit("kickoff")}}class R extends T{constructor(e){super(),Object.defineProperty(this,"host",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(null===this.context.loginUser)return void this.logger.warn("BusinessWebsocket try connect but not login");if(this.ws)return void this.logger.warn("BusinessWebsocket try connect but already connected");const e=`${this.host}/ws?token=${this.context.loginUser.sessionId}&platform=web`;this.ws=new A({url:e,logger:this.logger}),this.ws.on("message",e=>{this.emit("message",e)}),this.ws.on("kickoff",()=>{this.emit("kickoff")})}disconnect(){this.ws?(this.ws.destroy(),this.ws=null):this.logger.info("BusinessWebsocket already disconnected")}}class v{constructor(){Object.defineProperty(this,"syncCompleted",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"map",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"chatMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"threadMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"list",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"waitMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.syncCompleted=!1,this.map=new Map,this.chatMap=new Map,this.threadMap=new Map,this.waitMap=new Map,this.list=[]}getAll(){const e=[];for(const t of this.list){const i=this.map.get(t);i&&e.push(i)}return e}get(e){return this.map.get(e)??null}getByChat(e,t){let i;return i=t&&"0"!==t?this.threadMap.get(t):this.chatMap.get(e),void 0!==i?this.get(i):null}async waitFor(e){const t=this.get(e);if(t)return t;if(this.syncCompleted)return null;let i=this.waitMap.get(e);return i||(i=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,i)),await i.promise,this.get(e)}resolveWait(e){const t=this.waitMap.get(e);t&&(t.resolve(),this.waitMap.delete(e))}removeFromList(e){const t=this.list.indexOf(e);t>-1&&this.list.splice(t,1)}remove(e){const t=this.map.get(e);return!!t&&(this.map.delete(e),t.feed_type===r.thread?this.threadMap.delete(t.thread_id):this.chatMap.delete(t.chat_id),this.removeFromList(e),!0)}beforeSave(e){this.map.has(e.id)?this.removeFromList(e.id):e.feed_type===r.thread?this.threadMap.set(e.thread_id,e.id):this.chatMap.set(e.chat_id,e.id),this.map.set(e.id,e)}afterSave(e){this.resolveWait(e.id)}push(e){this.beforeSave(e),this.list.push(e.id),this.afterSave(e)}unshift(e){this.beforeSave(e),this.list.unshift(e.id),this.afterSave(e)}update(e){this.map.has(e.id)&&this.map.set(e.id,e)}markSyncComplete(){this.syncCompleted=!0;for(const[e,t]of this.waitMap)t.resolve();this.waitMap.clear()}isSyncCompleted(){return this.syncCompleted}reset(){this.syncCompleted=!1,this.map.clear(),this.chatMap.clear(),this.threadMap.clear(),this.waitMap.clear(),this.list=[]}}function w(e){return(new TextEncoder).encode(e).buffer}async function y(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=w(t),s=w(e),n=await crypto.subtle.importKey("raw",i,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,s);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return i.HmacSHA256(e,t).toString(i.enc.Hex)}(e,t)}const P=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=P(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=P(e[s]);return i}};function D(){return m(u.MAKE_SIGN_FAIL,"make sign fail")}class O{constructor(e){Object.defineProperty(this,"api",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.api=t.create({baseURL:e.host,headers:{"x-developer":e.developer}}),this.context=e.context,this.logger=e.logger}async request(e){try{const{needSign:t=!0,...i}=e;if(i.headers||(i.headers={}),i.headers.platform="web",t&&"POST"===e.method?.toUpperCase()&&i.data){if(null===this.context.loginUser)return this.logger.warn("HttpClient needs make sign but not login"),D();try{const e=await(async(e,t)=>{const i=await P(e);return await y(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),D()}}const s=await this.api(i),n=s.data;return n.code===u.SUCCESS?{ok:!0,data:n.data}:(this.logger.info("HttpClient server error",s),{ok:!1,code:n.code,msg:n.msg,msg_i18n:n.msg_i18n})}catch{return{ok:!1,code:u.NETWORK_ERROR,msg:"network error"}}}get(e,t,i){return this.request({url:e,method:"GET",params:t,...i})}post(e,t,i){return this.request({url:e,method:"POST",data:t,...i})}}function L(e){return`${e}`.padStart(2,"0")}class M{constructor(){Object.defineProperty(this,"level",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logHandler",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.level=h.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case h.error:return 3;case h.warning:return 2;case h.info:return 1;default:return 0}}createLogHandler(){return(e,...t)=>{const i=new Date,s=`TypeX >> [${`${i.getFullYear()}-${L(i.getMonth()+1)}-${L(i.getDate())} ${L(i.getHours())}:${L(i.getMinutes())}:${L(i.getSeconds())}.${i.getMilliseconds()}`}]`;switch(e){case h.error:console.error(s,"[ERR]",...t);break;case h.warning:console.warn(s,"[WARN]",...t);break;case h.info:console.info(s,"[INFO]",...t);break;default:console.log(s,...t)}}}log(e,...t){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,...t)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(...e){this.log(h.info,...e)}warn(...e){this.log(h.warning,...e)}error(...e){this.log(h.error,...e)}}class U{constructor(e){Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"emitter",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"handleKickoff",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(E.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}processCreateFeed(e){this.feedCache.unshift(e.content),this.emitFeedListUpdated()}processDeleteFeed(e){this.feedCache.remove(e.content.id)&&this.emitFeedListUpdated()}processAddMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,s=this.feedCache.getByChat(i.chat_id,i.thread_id);if(null===s)return;let n=!1;const o={};if(i.message_kind_id!==a.system&&i.sender_id!==t){n=!0;const e=new Set(s.unread_message_ids);e.add(i.id),o.unread_message_ids=[...e],o.badge=e.size}s.last_message_position<i.position&&(n=!0,o.last_message_id=i.id,o.last_message_position=i.position,o.last_message_sender_id=i.sender_id,o.last_message_send_at=i.send_at,o.last_message_kind_id=i.message_kind_id,o.last_message_type_id=i.message_type_id,o.last_message=i.content,o.last_message_operation=i.operation,o.last_message_operation_user_id=i.operation_user_id),n&&(this.feedCache.unshift({...s,...o}),this.emitFeedListUpdated()),this.emitter.emit(E.MESSAGE_RECEIVED,{feed_id:s.id,message:i})}processUpdateMessage(e){const t=e.content,i=this.feedCache.getByChat(t.chat_id,t.thread_id);if(null!==i&&null!=t.operation){let e=!1;const s={};if(t.operation===d.recall){if(null!=i.unread_message_ids&&i.unread_message_ids.includes(t.id)){e=!0;const n=new Set(i.unread_message_ids);n.delete(t.id),s.unread_message_ids=[...n],s.badge=s.unread_message_ids.length}i.last_message_id===t.id&&(e=!0,s.last_message=t.content??"{}",s.last_message_operation=t.operation,s.last_message_operation_user_id=t.operation_user_id??"0")}e&&(this.feedCache.unshift({...i,...s}),this.emitFeedListUpdated()),t.operation===d.recall&&this.emitter.emit(E.MESSAGE_RECALLED,{message_ids:[t.id]})}}processPushLiveMessage(e){this.emitter.emit(E.ROOM_MESSAGE_RECEIVED,{content:e.content})}processReadMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,s=this.feedCache.getByChat(i.chat_id,i.thread_id);if(null===s)return;let n=!1;const o={};if(i.reader_ids.includes(t)&&i.message_ids.length>0){n=!0;const e=new Set(s.unread_message_ids);i.message_ids.forEach(t=>{e.delete(t)}),o.unread_message_ids=[...e],o.badge=e.size}n&&(this.feedCache.update({...s,...o}),this.emitFeedListUpdated()),this.emitter.emit(E.MESSAGE_RECEIPT_RECEIVED,{feed_id:s.id,message_ids:i.message_ids,reader_user_ids:i.reader_ids})}processKickOutDevice(){this.handleKickoff()}process(e){switch(this.logger.info("PushMessageProcessor process",e),e.type){case n.CREATE_FEED:this.processCreateFeed(e);break;case n.DELETE_FEED:this.processDeleteFeed(e);break;case n.ADD_MESSAGE:this.processAddMessage(e);break;case n.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case n.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case n.READ_MESSAGE:this.processReadMessage(e);break;case n.KICK_OUT_DEVICE:this.processKickOutDevice()}}}class I{constructor(){Object.defineProperty(this,"obtained",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"abortLockObtain",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.obtained=!1,this.abortLockObtain=null}async requestLock(){if(this.obtained)return!0;let e=()=>{};const t=new Promise(t=>{e=t}),i=new Promise(e=>{this.abortLockObtain=e});navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{t?(this.obtained=!0,e(!0),await i):e(!1)});return await t}releaseLock(){this.obtained=!1,null!==this.abortLockObtain&&(this.abortLockObtain(),this.abortLockObtain=null)}}class k{static set(e){localStorage.setItem(this.key,JSON.stringify(e))}static get(){try{const e=localStorage.getItem(this.key);if(!e)return null;return JSON.parse(e)}catch{return null}}static clear(){localStorage.removeItem(this.key)}}Object.defineProperty(k,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class G{constructor(){Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class x extends T{constructor(e){super(),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"singletonLock",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"httpClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pushMessageProcessor",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context={isLogin:!1,loginUser:null,isReady:!1,deviceId:null},this.version=new G,this.singletonLock=new I,this.logger=new M,this.httpClient=new O({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new v,this.ws=new R({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new U({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.afterLogout()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.afterLogout()})}async requestDeviceId(){if(this.context.deviceId)return!0;const e=await this.httpClient.post("/device_api/device_id",{platform:"web",hash_str:""},{needSign:!1});return!!e.ok&&(this.context.deviceId=e.data,this.saveContext(),!0)}saveContext(){const{context:e}=this;k.set({deviceId:e.deviceId})}loadContext(){const e=k.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.ws.connect(),this.loadFeedList(),this.context.isReady=!0,this.emit(E.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(E.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const i=await this.httpClient.get("/feed",{limit:500,last_refresh_at:t.refresh_at??void 0,last_feed_id:t.feed_id??void 0});if(!this.version.check(e))break;if(!i.ok)break;if(t.refresh_at=i.data.refresh_at,t.feed_id=i.data.last_feed_id,i.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!i.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(E.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:!0}))}isReady(){return this.context.isReady}setLogLevel(e){this.logger.setLogLevel(e)}async login(t){if(this.context.isLogin)return b(null);if(!await this.singletonLock.requestLock())return this.logger.error("Another active TypeX SDK instance detected"),m(u.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),m(u.SDK_ERROR,"Get deviceId failed");const i=await this.httpClient.post("/user/session/login",{userCode:t.user_code,device_id:this.context.deviceId},{needSign:!1});if(!i.ok)return this.singletonLock.releaseLock(),i;const s=e.get("sessionid");return s?(this.context.isLogin=!0,this.context.loginUser={userId:i.data.id,secretKey:i.data.key,sessionId:s},this.applyLoginStatus(),b(null)):(this.singletonLock.releaseLock(),m(u.SDK_ERROR,"Get sessionId failed"))}async logout(){if(!this.context.isLogin)return b(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),b(null)):e}async afterLogout(){this.context.isLogin=!1,this.context.loginUser=null,this.applyLoginStatus()}getLoginUser(){return null===this.context.loginUser?null:this.context.loginUser.userId}async createSingleChatFeed(e){return await this.httpClient.post("/chat/single",{receiver_id:e})}async deleteFeed(e){return await this.httpClient.post("/feed/delete",{feed_id_list:[e],delete_peer:!0})}async getFeedList(){return b({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return b(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const i=t.data,{chat_id:s,first_position:n,last_message_position:o}=i,{positions:r,nextPosition:a,hasMore:l}=(e=>{const t=[];if(e.direction===_.up){let i=e.startPosition??e.maxPosition;for(;t.length<e.limit&&i>=e.minPosition;)t.push(i),i--;const s=i>=e.minPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}{let i=e.startPosition??e.minPosition;for(;t.length<e.limit&&i<=e.maxPosition;)t.push(i),i++;const s=i<=e.maxPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}})({maxPosition:o,minPosition:n,startPosition:e.message_position,limit:e.limit,direction:e.direction??_.up});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[s]:r}},{needSign:!1});if(e.ok&&e.data[s]){return b({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return b({has_more:!1,list:[]})}createCustomMessage(e){if(null===this.context.loginUser)return m(u.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return m(u.SDK_ERROR,"not found feed");var i;return b({id:"",chat_id:t.chat_id,thread_id:t.thread_id,position:t.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:a.text,message_type_id:l.custom,send_at:(new Date).toISOString(),reader_ids:[],unreader_ids:[],hide_ids:[],operation:d.normal,operation_user_id:"0",content:(i={client_msg_id:e.client_msg_id,content:e.content},JSON.stringify({client_msg_id:i.client_msg_id,content:JSON.stringify(i.content)}))})}async sendMessageToFeed(e){if(e.message_type_id===l.custom){const t=S(e.content);return this.httpClient.post("/message/send_custom",{chat_id:e.chat_id,thread_id:e.thread_id,client_id:t.client_msg_id,content:null==t.content?void 0:JSON.stringify(t.content)})}return m(u.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?m(u.SDK_ERROR,"not found feed"):await this.httpClient.post("/message/read",{chat_id:t.chat_id,message_ids:e.message_ids})}async joinRoom(e){return await this.httpClient.post("/liveshow/join",{room_id:e})}async leaveRoom(e){return await this.httpClient.post("/liveshow/leave",{room_id:e})}async getRoomRecentMessageList(e){const t=await this.httpClient.get("/liveshow/get_recent_message",{room_id:e});return t.ok?b(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const N=new Map;function F(e,t){let i=N.get(e);return void 0===i&&(i=new x(t),N.set(e,i)),i}const K={parseSystemMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:S};export{x as ChatSDK,F as create,g as enums,p as events,f as interfaces,K as utils};
package/dist/web-sdk.js CHANGED
@@ -1 +1 @@
1
- "use strict";var e,t,i,s,n,o,r,a,l,c,d,h,u=require("js-cookie"),_=require("axios"),g=require("crypto-js");!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(e||(e={})),function(e){e[e.CREATE_FEED=0]="CREATE_FEED",e[e.UPDATE_FEED=1]="UPDATE_FEED",e[e.ADD_MESSAGE=2]="ADD_MESSAGE",e[e.UPDATE_MESSAGE=3]="UPDATE_MESSAGE",e[e.UPDATE_USER_DATA=4]="UPDATE_USER_DATA",e[e.USER_LOGIN=5]="USER_LOGIN",e[e.READ_MESSAGE=6]="READ_MESSAGE",e[e.PONG_MESSAGE=8]="PONG_MESSAGE",e[e.DELETE_MESSAGE=9]="DELETE_MESSAGE",e[e.UPDATE_GROUP=12]="UPDATE_GROUP",e[e.DELETE_GROUP=13]="DELETE_GROUP",e[e.UPDATE_LOGIN_USER=17]="UPDATE_LOGIN_USER",e[e.UPDATE_MESSAGE_REACTION=19]="UPDATE_MESSAGE_REACTION",e[e.ADD_GROUP_MEMBER=21]="ADD_GROUP_MEMBER",e[e.DEL_GROUP_MEMBER=22]="DEL_GROUP_MEMBER",e[e.ADD_CONTACTS=23]="ADD_CONTACTS",e[e.UPDATE_CONTACTS=24]="UPDATE_CONTACTS",e[e.DEL_CONTACTS=25]="DEL_CONTACTS",e[e.BLOCK_USER=26]="BLOCK_USER",e[e.DEVICE_CODE=27]="DEVICE_CODE",e[e.MSG_OPEN_CLOCK=28]="MSG_OPEN_CLOCK",e[e.DELETE_SECRET_CHAT=29]="DELETE_SECRET_CHAT",e[e.DELETE_FEED=30]="DELETE_FEED",e[e.FAVORITE_UPDATE=31]="FAVORITE_UPDATE",e[e.STICKERS_UPDATE=32]="STICKERS_UPDATE",e[e.CUSTOM_STICKERS_UPDATE=33]="CUSTOM_STICKERS_UPDATE",e[e.MANAGE_DEVICE_UPDATE=34]="MANAGE_DEVICE_UPDATE",e[e.MASS_MESSAGE_UPDATE=35]="MASS_MESSAGE_UPDATE",e[e.CHAT_WALLPAPER_DELETE=36]="CHAT_WALLPAPER_DELETE",e[e.CHAT_WALLPAPER_ADD=37]="CHAT_WALLPAPER_ADD",e[e.CONTACT_REQUEST=40]="CONTACT_REQUEST",e[e.USER_PREFERENCE_CHANGE=38]="USER_PREFERENCE_CHANGE",e[e.UPDATE_GROUP_PIN=41]="UPDATE_GROUP_PIN",e[e.RTC_CANCEL=46]="RTC_CANCEL",e[e.ADD_FEED_FOLDER=43]="ADD_FEED_FOLDER",e[e.UPDATE_FEED_FOLDER=44]="UPDATE_FEED_FOLDER",e[e.UPDATE_FOLDER_FEED_LIST=47]="UPDATE_FOLDER_FEED_LIST",e[e.DELETE_FEED_FOLDER=45]="DELETE_FEED_FOLDER",e[e.UPDATE_CHATTER=42]="UPDATE_CHATTER",e[e.PAPER_KEY=48]="PAPER_KEY",e[e.PAPER_KEY_LOG=49]="PAPER_KEY_LOG",e[e.USER_LOGIN_SCAN=50]="USER_LOGIN_SCAN",e[e.RTC_RINGING=51]="RTC_RINGING",e[e.ON_UPDATE_PRIVATE_SETTING=52]="ON_UPDATE_PRIVATE_SETTING",e[e.ON_DELETE_PRIVATE_SETTING=53]="ON_DELETE_PRIVATE_SETTING",e[e.ON_UPDATE_LOGIN_PRIVATE_SETTING=54]="ON_UPDATE_LOGIN_PRIVATE_SETTING",e[e.PUSH_LIVE_MESSAGE=56]="PUSH_LIVE_MESSAGE",e[e.BIG_PACKAGE_PUSH=126]="BIG_PACKAGE_PUSH",e[e.KICK_OUT_DEVICE=127]="KICK_OUT_DEVICE",e[e.CLEAR_HISTORY=128]="CLEAR_HISTORY",e[e.CLEAR_DATA=255]="CLEAR_DATA"}(t||(t={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(i||(i={})),function(e){e[e.text=0]="text",e[e.system=1]="system"}(s||(s={})),function(e){e[e.text=0]="text",e[e.image=1]="image",e[e.card=2]="card",e[e.audio=3]="audio",e[e.video=4]="video",e[e.file=5]="file",e[e.mergeForward=6]="mergeForward",e[e.sticker=7]="sticker",e[e.richText=8]="richText",e[e.custom=9]="custom"}(n||(n={})),function(e){e[e.success=0]="success",e[e.sending=1]="sending",e[e.failed=2]="failed"}(o||(o={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(r||(r={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(a||(a={})),function(e){e[e.private=1]="private",e[e.public=0]="public",e[e.anonymous=2]="anonymous"}(l||(l={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(c||(c={})),function(e){e[e.SDK_ERROR=-1e4]="SDK_ERROR",e[e.NETWORK_ERROR=-9999]="NETWORK_ERROR",e[e.MAKE_SIGN_FAIL=-9998]="MAKE_SIGN_FAIL",e[e.REQUEST_SINGLETON_LOCK_FAIL=-9997]="REQUEST_SINGLETON_LOCK_FAIL",e[e.SUCCESS=0]="SUCCESS"}(d||(d={})),function(e){e[e.up=0]="up",e[e.down=1]="down"}(h||(h={}));var E=Object.freeze({__proto__:null,get Boolean(){return e},get ChatType(){return i},get GroupRole(){return r},get GroupType(){return l},get HttpClientResponseCode(){return d},get LogLevel(){return c},get MessageKind(){return s},get MessageOperation(){return a},get MessageSendStatus(){return o},get MessageType(){return n},get PushMessageType(){return t},get RequestDirection(){return h}});const p={SDK_READY:"sdkReady",SDK_NOT_READY:"sdkNotReady",FEED_LIST_UPDATED:"feedListUpdated",MESSAGE_RECEIVED:"messageReceived",MESSAGE_UPDATED:"messageUpdated",MESSAGE_RECEIPT_RECEIVED:"messageReceiptReceived",ROOM_MESSAGE_RECEIVED:"roomMessageReceived"};var f=Object.freeze({__proto__:null,CHAT_SDK_EVENT:p}),m=Object.freeze({__proto__:null});function b(e,t){return{ok:!1,code:e,msg:t}}function S(e){return{ok:!0,data:e}}const C=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},T=e=>{const t=C(e);if(null!==t){let e;return null!=t.content&&(e=C(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class A{constructor(e){Object.defineProperty(this,"all",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.all=e||new Map}on(e,t){const i=this.all.get(e);return i?i.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const i=this.all.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let i=this.all.get(e);i&&i.slice().map(e=>{e(t)}),i=this.all.get("*"),i&&i.slice().map(i=>{i(e,t)})}once(e,t){if("*"===e){const i=(e,s)=>{t(e,s),this.off("*",i)};this.on(e,i)}else{const i=s=>{t(s),this.off(e,i)};this.on(e,i)}}}class w extends A{constructor(e){super(),Object.defineProperty(this,"url",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"destroyed",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pingTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pongTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"reConnectTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.url=e.url,this.logger=e.logger,this.ws=null,this.destroyed=!1,this.pingTimeout=null,this.pongTimeout=null,this.reConnectTimeout=null,this.reConnect=this.reConnect.bind(this),window.addEventListener("online",this.reConnect),this.connect()}disconnect(){this.ws&&(this.ws.onopen=null,this.ws.onerror=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.close(),this.ws=null),null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null),null!==this.reConnectTimeout&&(clearTimeout(this.reConnectTimeout),this.reConnectTimeout=null)}connect(){if(this.ws)return void this.logger.warn("ReConnectWebsocket try connect but already connected");const e=new WebSocket(this.url);this.ws=e,e.onopen=()=>{this.delaySendPing()},e.onerror=e=>{this.logger.info("ReConnectWebsocket error",e)},e.onmessage=e=>{try{const i=JSON.parse(e.data);if(i.type===t.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(i.id),i.type===t.BIG_PACKAGE_PUSH)for(const e of i.content.big_push)this.emit("message",e);else this.emit("message",i)}catch(e){this.logger.error("ReConnectWebsocket message parse failed",e)}},e.onclose=e=>{4001===e.code?this.kickOff():this.reConnect()}}reConnect(){this.disconnect(),this.destroyed||(this.reConnectTimeout=setTimeout(()=>{this.reConnectTimeout=null,this.connect()},5e3))}send(e){if(this.destroyed)return!1;if(!this.ws)return this.logger.warn("ReConnectWebsocket send before connect"),!1;try{return this.ws.readyState!==this.ws.OPEN?(this.logger.warn("ReConnectWebsocket send but not open",this.ws.readyState),!1):(this.ws.send(JSON.stringify(e)),!0)}catch(e){return this.logger.warn("ReConnectWebsocket send error",e),!1}}sendAck(e){this.send({type:1,ids:[e]})}destroy(){this.destroyed||(this.destroyed=!0,this.disconnect(),window.removeEventListener("online",this.reConnect))}delaySendPing(){null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.pingTimeout=setTimeout(()=>{this.pingTimeout=null;this.send({type:0})?this.waitPong():this.reConnect()},2e4)}waitPong(){this.pongTimeout=setTimeout(()=>{this.logger.info("ReConnectWebsocket pong timeout"),this.reConnect()},1e4)}kickOff(){this.destroy(),this.emit("kickoff")}}class y extends A{constructor(e){super(),Object.defineProperty(this,"host",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(null===this.context.loginUser)return void this.logger.warn("BusinessWebsocket try connect but not login");if(this.ws)return void this.logger.warn("BusinessWebsocket try connect but already connected");const e=`${this.host}/ws?token=${this.context.loginUser.sessionId}&platform=web`;this.ws=new w({url:e,logger:this.logger}),this.ws.on("message",e=>{this.emit("message",e)}),this.ws.on("kickoff",()=>{this.emit("kickoff")})}disconnect(){this.ws?(this.ws.destroy(),this.ws=null):this.logger.info("BusinessWebsocket already disconnected")}}class v{constructor(){Object.defineProperty(this,"_isSyncCompleted",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"map",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"chatMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"list",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"waitMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this._isSyncCompleted=!1,this.map=new Map,this.chatMap=new Map,this.waitMap=new Map,this.list=[]}getAll(){const e=[];for(const t of this.list){const i=this.map.get(t);i&&e.push(i)}return e}get(e){return this.map.get(e)??null}getByChatId(e){const t=this.chatMap.get(e);return void 0!==t?this.get(t):null}async waitFor(e){const t=this.get(e);if(t)return t;if(this._isSyncCompleted)return null;let i=this.waitMap.get(e);return i||(i=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,i)),await i.promise,this.get(e)}resolveWait(e){const t=this.waitMap.get(e);t&&(t.resolve(!0),this.waitMap.delete(e))}remove(e){const t=this.map.get(e);return!!t&&(this.map.delete(e),this.chatMap.delete(t.chat_id),this.list.splice(this.list.indexOf(e),1),!0)}push(e){this.remove(e.id),this.map.set(e.id,e),this.list.push(e.id),this.chatMap.set(e.chat_id,e.id),this.resolveWait(e.id)}unshift(e){this.remove(e.id),this.map.set(e.id,e),this.list.unshift(e.id),this.chatMap.set(e.chat_id,e.id),this.resolveWait(e.id)}update(e){this.map.has(e.id)&&this.map.set(e.id,e)}markSyncComplete(){this._isSyncCompleted=!0;for(const[e,t]of this.waitMap)t.resolve(!0);this.waitMap.clear()}isSyncCompleted(){return this._isSyncCompleted}reset(){this._isSyncCompleted=!1,this.map.clear(),this.chatMap.clear(),this.waitMap.clear(),this.list=[]}}function R(e){return(new TextEncoder).encode(e).buffer}async function P(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=R(t),s=R(e),n=await crypto.subtle.importKey("raw",i,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,s);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return g.HmacSHA256(e,t).toString(g.enc.Hex)}(e,t)}const D=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=D(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=D(e[s]);return i}};function O(){return b(d.MAKE_SIGN_FAIL,"make sign fail")}class L{constructor(e){Object.defineProperty(this,"api",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.api=_.create({baseURL:e.host,headers:{"x-developer":e.developer}}),this.context=e.context,this.logger=e.logger}async request(e){try{const{needSign:t=!0,...i}=e;if(i.headers||(i.headers={}),i.headers.platform="web",t&&"POST"===e.method?.toUpperCase()&&i.data){if(null===this.context.loginUser)return this.logger.warn("HttpClient needs make sign but not login"),O();try{const e=await(async(e,t)=>{const i=await D(e);return await P(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),O()}}const s=await this.api(i),n=s.data;return n.code===d.SUCCESS?{ok:!0,data:n.data}:(this.logger.info("HttpClient server error",s),{ok:!1,code:n.code,msg:n.msg,msg_i18n:n.msg_i18n})}catch{return{ok:!1,code:d.NETWORK_ERROR,msg:"network error"}}}get(e,t,i){return this.request({url:e,method:"GET",params:t,...i})}post(e,t,i){return this.request({url:e,method:"POST",data:t,...i})}}class U{constructor(){Object.defineProperty(this,"level",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logHandler",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.level=c.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case c.error:return 3;case c.warning:return 2;case c.info:return 1;default:return 0}}createLogHandler(){return(e,t,...i)=>{const s=`[tlog] ${(new Date).toISOString().split("T")[0]}`,n=t?`${s} ${t}`:s;switch(e){case c.error:console.error(n,...i);break;case c.warning:console.warn(n,...i);break;case c.info:console.info(n,...i);break;default:console.log(n,...i)}}}log(e,t,...i){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,t,...i)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(e,...t){this.log(c.info,e,...t)}warn(e,...t){this.log(c.warning,e,...t)}error(e,...t){this.log(c.error,e,...t)}}class I{constructor(e){Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"emitter",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"handleKickoff",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(p.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}processCreateFeed(e){this.feedCache.unshift(e.content),this.emitFeedListUpdated()}processDeleteFeed(e){this.feedCache.remove(e.content.id)&&this.emitFeedListUpdated()}processAddMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,n=this.feedCache.getByChatId(i.chat_id);if(null!==n){let e=!1;const o={};if(i.message_kind_id!==s.system&&i.sender_id!==t){e=!0;const t=new Set(n.unread_message_ids);t.add(i.id),o.unread_message_ids=[...t],o.badge=t.size}n.last_message_position<i.position&&(e=!0,o.last_message_id=i.id,o.last_message_position=i.position,o.last_message_sender_id=i.sender_id,o.last_message_send_at=i.send_at,o.last_message_kind_id=i.message_kind_id,o.last_message_type_id=i.message_type_id,o.last_message=i.content,o.last_message_operation=i.operation,o.last_message_operation_user_id=i.operation_user_id),e&&(this.feedCache.unshift({...n,...o}),this.emitFeedListUpdated()),this.emitter.emit(p.MESSAGE_RECEIVED,i)}}processUpdateMessage(e){const t=e.content;if(t.operation===a.recall){const i=this.feedCache.getByChatId(e.content.chat_id);if(null!==i){let e=!1;const s={};if(null!=i.unread_message_ids&&i.unread_message_ids.includes(t.id)){e=!0;const n=new Set(i.unread_message_ids);n.delete(t.id),s.unread_message_ids=[...n],s.badge=s.unread_message_ids.length}i.last_message_id===t.id&&(e=!0,s.last_message=t.content,s.last_message_operation=t.operation,s.last_message_operation_user_id=t.operation_user_id),e&&(this.feedCache.unshift({...i,...s}),this.emitFeedListUpdated())}}this.emitter.emit(p.MESSAGE_UPDATED,t)}processPushLiveMessage(e){this.emitter.emit(p.ROOM_MESSAGE_RECEIVED,e.content)}processReadMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=this.feedCache.getByChatId(e.content.chat_id);if(null!==i){let s=!1;const n={};if(e.content.reader_ids.includes(t)&&e.content.message_ids.length>0){s=!0;const t=new Set(i.unread_message_ids);e.content.message_ids.forEach(e=>{t.delete(e)}),n.unread_message_ids=[...t],n.badge=t.size}s&&(this.feedCache.update({...i,...n}),this.emitFeedListUpdated()),this.emitter.emit(p.MESSAGE_RECEIPT_RECEIVED,{feed_id:i.id,message_ids:e.content.message_ids,reader_user_ids:e.content.reader_ids})}}processKickOutDevice(){this.handleKickoff()}process(e){switch(this.logger.info("PushMessageProcessor process",e),e.type){case t.CREATE_FEED:this.processCreateFeed(e);break;case t.DELETE_FEED:this.processDeleteFeed(e);break;case t.ADD_MESSAGE:this.processAddMessage(e);break;case t.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case t.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case t.READ_MESSAGE:this.processReadMessage(e);break;case t.KICK_OUT_DEVICE:this.processKickOutDevice()}}}class k{constructor(){Object.defineProperty(this,"obtained",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"abortLockObtain",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.obtained=!1,this.abortLockObtain=null}async requestLock(){if(this.obtained)return!0;let e=()=>{};const t=new Promise(t=>{e=t}),i=new Promise(e=>{this.abortLockObtain=e});navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{t?(this.obtained=!0,e(!0),await i):e(!1)});return await t}releaseLock(){this.obtained=!1,null!==this.abortLockObtain&&(this.abortLockObtain(),this.abortLockObtain=null)}}class M{static set(e){localStorage.setItem(this.key,JSON.stringify(e))}static get(){try{const e=localStorage.getItem(this.key);if(!e)return null;return JSON.parse(e)}catch{return null}}static clear(){localStorage.removeItem(this.key)}}Object.defineProperty(M,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class x{constructor(){Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class G extends A{constructor(e){super(),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"singletonLock",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"httpClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pushMessageProcessor",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context={isLogin:!1,loginUser:null,isReady:!1,deviceId:null},this.version=new x,this.singletonLock=new k,this.logger=new U,this.httpClient=new L({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new v,this.ws=new y({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new I({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.afterLogout()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.afterLogout()})}async requestDeviceId(){if(this.context.deviceId)return!0;const e=await this.httpClient.post("/device_api/device_id",{platform:"web",hash_str:""},{needSign:!1});return!!e.ok&&(this.context.deviceId=e.data,this.saveContext(),!0)}saveContext(){const{context:e}=this;M.set({deviceId:e.deviceId})}loadContext(){const e=M.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.ws.connect(),this.loadFeedList(),this.context.isReady=!0,this.emit(p.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(p.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const i=await this.httpClient.get("/feed",{limit:500,last_refresh_at:t.refresh_at??void 0,last_feed_id:t.feed_id??void 0});if(!this.version.check(e))break;if(!i.ok)break;if(t.refresh_at=i.data.refresh_at,t.feed_id=i.data.last_feed_id,i.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!i.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(p.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:!0}))}isReady(){return this.context.isReady}setLogLevel(e){this.logger.setLogLevel(e)}async login(e){if(this.context.isLogin)return S(null);if(!await this.singletonLock.requestLock())return this.logger.error("Another active TypeX SDK instance detected"),b(d.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),b(d.SDK_ERROR,"Get deviceId failed");const t=await this.httpClient.post("/user/session/login",{userCode:e.user_code,device_id:this.context.deviceId},{needSign:!1});if(!t.ok)return this.singletonLock.releaseLock(),t;const i=u.get("sessionid");return i?(this.context.isLogin=!0,this.context.loginUser={userId:t.data.id,secretKey:t.data.key,sessionId:i},this.applyLoginStatus(),S(null)):(this.singletonLock.releaseLock(),b(d.SDK_ERROR,"Get sessionId failed"))}async logout(){if(!this.context.isLogin)return S(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),S(null)):e}async afterLogout(){this.context.isLogin=!1,this.context.loginUser=null,this.applyLoginStatus()}getLoginUser(){return null===this.context.loginUser?null:this.context.loginUser.userId}async createSingleChatFeed(e){return await this.httpClient.post("/chat/single",{receiver_id:e})}async deleteFeed(e){return await this.httpClient.post("/feed/delete",{feed_id_list:[e],delete_peer:!0})}async getFeedList(){return S({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return S(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const i=t.data,{chat_id:s,first_position:n,last_message_position:o}=i,{positions:r,nextPosition:a,hasMore:l}=(e=>{const t=[];if(e.direction===h.up){let i=e.startPosition??e.maxPosition;for(;t.length<e.limit&&i>=e.minPosition;)t.push(i),i--;const s=i>=e.minPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}{let i=e.startPosition??e.minPosition;for(;t.length<e.limit&&i<=e.maxPosition;)t.push(i),i++;const s=i<=e.maxPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}})({maxPosition:o,minPosition:n,startPosition:e.message_position,limit:e.limit,direction:e.direction??h.up});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[s]:r}},{needSign:!1});if(e.ok&&e.data[s]){return S({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return S({has_more:!1,list:[]})}createCustomMessage(e){if(null===this.context.loginUser)return b(d.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return b(d.SDK_ERROR,"not found feed");var i;return S({id:"",chat_id:t.chat_id,position:t.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:s.text,message_type_id:n.custom,send_at:"",reader_ids:[],hide_ids:[],operation:a.normal,operation_user_id:"0",content:(i={client_msg_id:e.client_msg_id,content:e.content},JSON.stringify({client_msg_id:i.client_msg_id,content:JSON.stringify(i.content)}))})}async sendMessageToFeed(e){if(e.message_type_id===n.custom){const t=T(e.content);return this.httpClient.post("/message/send_custom",{chat_id:e.chat_id,client_id:t.client_msg_id,content:null==t.content?void 0:JSON.stringify(t.content)})}return b(d.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?b(d.SDK_ERROR,"not found feed"):await this.httpClient.post("/message/read",{chat_id:t.chat_id,message_ids:e.message_ids})}async joinRoom(e){return await this.httpClient.post("/liveshow/join",{room_id:e})}async leaveRoom(e){return await this.httpClient.post("/liveshow/leave",{room_id:e})}async getRoomRecentMessageList(e){const t=await this.httpClient.get("/liveshow/get_recent_message",{room_id:e});return t.ok?S(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const N=new Map;const F={parseSystemMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:T};exports.ChatSDK=G,exports.create=function(e,t){let i=N.get(e);return void 0===i&&(i=new G(t),N.set(e,i)),i},exports.enums=E,exports.events=f,exports.interfaces=m,exports.utils=F;
1
+ "use strict";var e,t,i,s,n,o,r,a,l,c,d,h=require("js-cookie"),u=require("axios"),_=require("crypto-js");!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(e||(e={})),function(e){e[e.CREATE_FEED=0]="CREATE_FEED",e[e.UPDATE_FEED=1]="UPDATE_FEED",e[e.ADD_MESSAGE=2]="ADD_MESSAGE",e[e.UPDATE_MESSAGE=3]="UPDATE_MESSAGE",e[e.UPDATE_USER_DATA=4]="UPDATE_USER_DATA",e[e.USER_LOGIN=5]="USER_LOGIN",e[e.READ_MESSAGE=6]="READ_MESSAGE",e[e.PONG_MESSAGE=8]="PONG_MESSAGE",e[e.DELETE_MESSAGE=9]="DELETE_MESSAGE",e[e.UPDATE_GROUP=12]="UPDATE_GROUP",e[e.DELETE_GROUP=13]="DELETE_GROUP",e[e.UPDATE_LOGIN_USER=17]="UPDATE_LOGIN_USER",e[e.UPDATE_MESSAGE_REACTION=19]="UPDATE_MESSAGE_REACTION",e[e.ADD_GROUP_MEMBER=21]="ADD_GROUP_MEMBER",e[e.DEL_GROUP_MEMBER=22]="DEL_GROUP_MEMBER",e[e.ADD_CONTACTS=23]="ADD_CONTACTS",e[e.UPDATE_CONTACTS=24]="UPDATE_CONTACTS",e[e.DEL_CONTACTS=25]="DEL_CONTACTS",e[e.BLOCK_USER=26]="BLOCK_USER",e[e.DEVICE_CODE=27]="DEVICE_CODE",e[e.MSG_OPEN_CLOCK=28]="MSG_OPEN_CLOCK",e[e.DELETE_SECRET_CHAT=29]="DELETE_SECRET_CHAT",e[e.DELETE_FEED=30]="DELETE_FEED",e[e.FAVORITE_UPDATE=31]="FAVORITE_UPDATE",e[e.STICKERS_UPDATE=32]="STICKERS_UPDATE",e[e.CUSTOM_STICKERS_UPDATE=33]="CUSTOM_STICKERS_UPDATE",e[e.MANAGE_DEVICE_UPDATE=34]="MANAGE_DEVICE_UPDATE",e[e.MASS_MESSAGE_UPDATE=35]="MASS_MESSAGE_UPDATE",e[e.CHAT_WALLPAPER_DELETE=36]="CHAT_WALLPAPER_DELETE",e[e.CHAT_WALLPAPER_ADD=37]="CHAT_WALLPAPER_ADD",e[e.CONTACT_REQUEST=40]="CONTACT_REQUEST",e[e.USER_PREFERENCE_CHANGE=38]="USER_PREFERENCE_CHANGE",e[e.UPDATE_GROUP_PIN=41]="UPDATE_GROUP_PIN",e[e.RTC_CANCEL=46]="RTC_CANCEL",e[e.ADD_FEED_FOLDER=43]="ADD_FEED_FOLDER",e[e.UPDATE_FEED_FOLDER=44]="UPDATE_FEED_FOLDER",e[e.UPDATE_FOLDER_FEED_LIST=47]="UPDATE_FOLDER_FEED_LIST",e[e.DELETE_FEED_FOLDER=45]="DELETE_FEED_FOLDER",e[e.UPDATE_CHATTER=42]="UPDATE_CHATTER",e[e.PAPER_KEY=48]="PAPER_KEY",e[e.PAPER_KEY_LOG=49]="PAPER_KEY_LOG",e[e.USER_LOGIN_SCAN=50]="USER_LOGIN_SCAN",e[e.RTC_RINGING=51]="RTC_RINGING",e[e.ON_UPDATE_PRIVATE_SETTING=52]="ON_UPDATE_PRIVATE_SETTING",e[e.ON_DELETE_PRIVATE_SETTING=53]="ON_DELETE_PRIVATE_SETTING",e[e.ON_UPDATE_LOGIN_PRIVATE_SETTING=54]="ON_UPDATE_LOGIN_PRIVATE_SETTING",e[e.PUSH_LIVE_MESSAGE=56]="PUSH_LIVE_MESSAGE",e[e.BIG_PACKAGE_PUSH=126]="BIG_PACKAGE_PUSH",e[e.KICK_OUT_DEVICE=127]="KICK_OUT_DEVICE",e[e.CLEAR_HISTORY=128]="CLEAR_HISTORY",e[e.CLEAR_DATA=255]="CLEAR_DATA"}(t||(t={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(i||(i={})),function(e){e[e.normal=0]="normal",e[e.thread=1]="thread"}(s||(s={})),function(e){e[e.text=0]="text",e[e.system=1]="system"}(n||(n={})),function(e){e[e.text=0]="text",e[e.image=1]="image",e[e.card=2]="card",e[e.audio=3]="audio",e[e.video=4]="video",e[e.file=5]="file",e[e.mergeForward=6]="mergeForward",e[e.sticker=7]="sticker",e[e.richText=8]="richText",e[e.custom=9]="custom"}(o||(o={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(r||(r={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(a||(a={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(l||(l={})),function(e){e[e.SDK_ERROR=-1e4]="SDK_ERROR",e[e.NETWORK_ERROR=-9999]="NETWORK_ERROR",e[e.MAKE_SIGN_FAIL=-9998]="MAKE_SIGN_FAIL",e[e.REQUEST_SINGLETON_LOCK_FAIL=-9997]="REQUEST_SINGLETON_LOCK_FAIL",e[e.SUCCESS=0]="SUCCESS"}(c||(c={})),function(e){e[e.up=0]="up",e[e.down=1]="down"}(d||(d={}));var g=Object.freeze({__proto__:null,get Boolean(){return e},get ChatType(){return i},get FeedType(){return s},get GroupRole(){return r},get HttpClientResponseCode(){return c},get LogLevel(){return l},get MessageKind(){return n},get MessageOperation(){return a},get MessageType(){return o},get PushMessageType(){return t},get RequestDirection(){return d}});const E={SDK_READY:"sdkReady",SDK_NOT_READY:"sdkNotReady",FEED_LIST_UPDATED:"feedListUpdated",MESSAGE_RECEIVED:"messageReceived",MESSAGE_RECALLED:"messageRecalled",MESSAGE_RECEIPT_RECEIVED:"messageReceiptReceived",ROOM_MESSAGE_RECEIVED:"roomMessageReceived"};var p=Object.freeze({__proto__:null,CHAT_SDK_EVENT:E}),f=Object.freeze({__proto__:null});function m(e,t){return{ok:!1,code:e,msg:t}}function b(e){return{ok:!0,data:e}}const C=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},S=e=>{const t=C(e);if(null!==t){let e;return null!=t.content&&(e=C(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class T{constructor(e){Object.defineProperty(this,"all",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.all=e||new Map}on(e,t){const i=this.all.get(e);return i?i.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const i=this.all.get(e);i&&(t?i.splice(i.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let i=this.all.get(e);i&&i.slice().map(e=>{e(t)}),i=this.all.get("*"),i&&i.slice().map(i=>{i(e,t)})}once(e,t){if("*"===e){const i=(e,s)=>{t(e,s),this.off("*",i)};this.on(e,i)}else{const i=s=>{t(s),this.off(e,i)};this.on(e,i)}}}class A extends T{constructor(e){super(),Object.defineProperty(this,"url",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"destroyed",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pingTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pongTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"reConnectTimeout",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.url=e.url,this.logger=e.logger,this.ws=null,this.destroyed=!1,this.pingTimeout=null,this.pongTimeout=null,this.reConnectTimeout=null,this.reConnect=this.reConnect.bind(this),window.addEventListener("online",this.reConnect),this.connect()}disconnect(){this.ws&&(this.ws.onopen=null,this.ws.onerror=null,this.ws.onmessage=null,this.ws.onclose=null,this.ws.close(),this.ws=null),null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null),null!==this.reConnectTimeout&&(clearTimeout(this.reConnectTimeout),this.reConnectTimeout=null)}connect(){if(this.ws)return void this.logger.warn("ReConnectWebsocket try connect but already connected");const e=new WebSocket(this.url);this.ws=e,e.onopen=()=>{this.delaySendPing()},e.onerror=e=>{this.logger.info("ReConnectWebsocket error",e)},e.onmessage=e=>{try{const i=JSON.parse(e.data);if(i.type===t.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(i.id),i.type===t.BIG_PACKAGE_PUSH)for(const e of i.content.big_push)this.emit("message",e);else this.emit("message",i)}catch(e){this.logger.error("ReConnectWebsocket message parse failed",e)}},e.onclose=e=>{4001===e.code?this.kickOff():this.reConnect()}}reConnect(){this.disconnect(),this.destroyed||(this.reConnectTimeout=setTimeout(()=>{this.reConnectTimeout=null,this.connect()},5e3))}send(e){if(this.destroyed)return!1;if(!this.ws)return this.logger.warn("ReConnectWebsocket send before connect"),!1;try{return this.ws.readyState!==this.ws.OPEN?(this.logger.warn("ReConnectWebsocket send but not open",this.ws.readyState),!1):(this.ws.send(JSON.stringify(e)),!0)}catch(e){return this.logger.warn("ReConnectWebsocket send error",e),!1}}sendAck(e){this.send({type:1,ids:[e]})}destroy(){this.destroyed||(this.destroyed=!0,this.disconnect(),window.removeEventListener("online",this.reConnect))}delaySendPing(){null!==this.pingTimeout&&(clearTimeout(this.pingTimeout),this.pingTimeout=null),this.pingTimeout=setTimeout(()=>{this.pingTimeout=null;this.send({type:0})?this.waitPong():this.reConnect()},2e4)}waitPong(){this.pongTimeout=setTimeout(()=>{this.logger.info("ReConnectWebsocket pong timeout"),this.reConnect()},1e4)}kickOff(){this.destroy(),this.emit("kickoff")}}class v extends T{constructor(e){super(),Object.defineProperty(this,"host",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(null===this.context.loginUser)return void this.logger.warn("BusinessWebsocket try connect but not login");if(this.ws)return void this.logger.warn("BusinessWebsocket try connect but already connected");const e=`${this.host}/ws?token=${this.context.loginUser.sessionId}&platform=web`;this.ws=new A({url:e,logger:this.logger}),this.ws.on("message",e=>{this.emit("message",e)}),this.ws.on("kickoff",()=>{this.emit("kickoff")})}disconnect(){this.ws?(this.ws.destroy(),this.ws=null):this.logger.info("BusinessWebsocket already disconnected")}}class R{constructor(){Object.defineProperty(this,"syncCompleted",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"map",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"chatMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"threadMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"list",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"waitMap",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.syncCompleted=!1,this.map=new Map,this.chatMap=new Map,this.threadMap=new Map,this.waitMap=new Map,this.list=[]}getAll(){const e=[];for(const t of this.list){const i=this.map.get(t);i&&e.push(i)}return e}get(e){return this.map.get(e)??null}getByChat(e,t){let i;return i=t&&"0"!==t?this.threadMap.get(t):this.chatMap.get(e),void 0!==i?this.get(i):null}async waitFor(e){const t=this.get(e);if(t)return t;if(this.syncCompleted)return null;let i=this.waitMap.get(e);return i||(i=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,i)),await i.promise,this.get(e)}resolveWait(e){const t=this.waitMap.get(e);t&&(t.resolve(),this.waitMap.delete(e))}removeFromList(e){const t=this.list.indexOf(e);t>-1&&this.list.splice(t,1)}remove(e){const t=this.map.get(e);return!!t&&(this.map.delete(e),t.feed_type===s.thread?this.threadMap.delete(t.thread_id):this.chatMap.delete(t.chat_id),this.removeFromList(e),!0)}beforeSave(e){this.map.has(e.id)?this.removeFromList(e.id):e.feed_type===s.thread?this.threadMap.set(e.thread_id,e.id):this.chatMap.set(e.chat_id,e.id),this.map.set(e.id,e)}afterSave(e){this.resolveWait(e.id)}push(e){this.beforeSave(e),this.list.push(e.id),this.afterSave(e)}unshift(e){this.beforeSave(e),this.list.unshift(e.id),this.afterSave(e)}update(e){this.map.has(e.id)&&this.map.set(e.id,e)}markSyncComplete(){this.syncCompleted=!0;for(const[e,t]of this.waitMap)t.resolve();this.waitMap.clear()}isSyncCompleted(){return this.syncCompleted}reset(){this.syncCompleted=!1,this.map.clear(),this.chatMap.clear(),this.threadMap.clear(),this.waitMap.clear(),this.list=[]}}function w(e){return(new TextEncoder).encode(e).buffer}async function y(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=w(t),s=w(e),n=await crypto.subtle.importKey("raw",i,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,s);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return _.HmacSHA256(e,t).toString(_.enc.Hex)}(e,t)}const P=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=P(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=P(e[s]);return i}};function D(){return m(c.MAKE_SIGN_FAIL,"make sign fail")}class O{constructor(e){Object.defineProperty(this,"api",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.api=u.create({baseURL:e.host,headers:{"x-developer":e.developer}}),this.context=e.context,this.logger=e.logger}async request(e){try{const{needSign:t=!0,...i}=e;if(i.headers||(i.headers={}),i.headers.platform="web",t&&"POST"===e.method?.toUpperCase()&&i.data){if(null===this.context.loginUser)return this.logger.warn("HttpClient needs make sign but not login"),D();try{const e=await(async(e,t)=>{const i=await P(e);return await y(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),D()}}const s=await this.api(i),n=s.data;return n.code===c.SUCCESS?{ok:!0,data:n.data}:(this.logger.info("HttpClient server error",s),{ok:!1,code:n.code,msg:n.msg,msg_i18n:n.msg_i18n})}catch{return{ok:!1,code:c.NETWORK_ERROR,msg:"network error"}}}get(e,t,i){return this.request({url:e,method:"GET",params:t,...i})}post(e,t,i){return this.request({url:e,method:"POST",data:t,...i})}}function L(e){return`${e}`.padStart(2,"0")}class M{constructor(){Object.defineProperty(this,"level",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logHandler",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.level=l.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case l.error:return 3;case l.warning:return 2;case l.info:return 1;default:return 0}}createLogHandler(){return(e,...t)=>{const i=new Date,s=`TypeX >> [${`${i.getFullYear()}-${L(i.getMonth()+1)}-${L(i.getDate())} ${L(i.getHours())}:${L(i.getMinutes())}:${L(i.getSeconds())}.${i.getMilliseconds()}`}]`;switch(e){case l.error:console.error(s,"[ERR]",...t);break;case l.warning:console.warn(s,"[WARN]",...t);break;case l.info:console.info(s,"[INFO]",...t);break;default:console.log(s,...t)}}}log(e,...t){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,...t)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(...e){this.log(l.info,...e)}warn(...e){this.log(l.warning,...e)}error(...e){this.log(l.error,...e)}}class U{constructor(e){Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"emitter",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"handleKickoff",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(E.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}processCreateFeed(e){this.feedCache.unshift(e.content),this.emitFeedListUpdated()}processDeleteFeed(e){this.feedCache.remove(e.content.id)&&this.emitFeedListUpdated()}processAddMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,s=this.feedCache.getByChat(i.chat_id,i.thread_id);if(null===s)return;let o=!1;const r={};if(i.message_kind_id!==n.system&&i.sender_id!==t){o=!0;const e=new Set(s.unread_message_ids);e.add(i.id),r.unread_message_ids=[...e],r.badge=e.size}s.last_message_position<i.position&&(o=!0,r.last_message_id=i.id,r.last_message_position=i.position,r.last_message_sender_id=i.sender_id,r.last_message_send_at=i.send_at,r.last_message_kind_id=i.message_kind_id,r.last_message_type_id=i.message_type_id,r.last_message=i.content,r.last_message_operation=i.operation,r.last_message_operation_user_id=i.operation_user_id),o&&(this.feedCache.unshift({...s,...r}),this.emitFeedListUpdated()),this.emitter.emit(E.MESSAGE_RECEIVED,{feed_id:s.id,message:i})}processUpdateMessage(e){const t=e.content,i=this.feedCache.getByChat(t.chat_id,t.thread_id);if(null!==i&&null!=t.operation){let e=!1;const s={};if(t.operation===a.recall){if(null!=i.unread_message_ids&&i.unread_message_ids.includes(t.id)){e=!0;const n=new Set(i.unread_message_ids);n.delete(t.id),s.unread_message_ids=[...n],s.badge=s.unread_message_ids.length}i.last_message_id===t.id&&(e=!0,s.last_message=t.content??"{}",s.last_message_operation=t.operation,s.last_message_operation_user_id=t.operation_user_id??"0")}e&&(this.feedCache.unshift({...i,...s}),this.emitFeedListUpdated()),t.operation===a.recall&&this.emitter.emit(E.MESSAGE_RECALLED,{message_ids:[t.id]})}}processPushLiveMessage(e){this.emitter.emit(E.ROOM_MESSAGE_RECEIVED,{content:e.content})}processReadMessage(e){if(null===this.context.loginUser)return;const t=this.context.loginUser.userId,i=e.content,s=this.feedCache.getByChat(i.chat_id,i.thread_id);if(null===s)return;let n=!1;const o={};if(i.reader_ids.includes(t)&&i.message_ids.length>0){n=!0;const e=new Set(s.unread_message_ids);i.message_ids.forEach(t=>{e.delete(t)}),o.unread_message_ids=[...e],o.badge=e.size}n&&(this.feedCache.update({...s,...o}),this.emitFeedListUpdated()),this.emitter.emit(E.MESSAGE_RECEIPT_RECEIVED,{feed_id:s.id,message_ids:i.message_ids,reader_user_ids:i.reader_ids})}processKickOutDevice(){this.handleKickoff()}process(e){switch(this.logger.info("PushMessageProcessor process",e),e.type){case t.CREATE_FEED:this.processCreateFeed(e);break;case t.DELETE_FEED:this.processDeleteFeed(e);break;case t.ADD_MESSAGE:this.processAddMessage(e);break;case t.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case t.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case t.READ_MESSAGE:this.processReadMessage(e);break;case t.KICK_OUT_DEVICE:this.processKickOutDevice()}}}class I{constructor(){Object.defineProperty(this,"obtained",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"abortLockObtain",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.obtained=!1,this.abortLockObtain=null}async requestLock(){if(this.obtained)return!0;let e=()=>{};const t=new Promise(t=>{e=t}),i=new Promise(e=>{this.abortLockObtain=e});navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{t?(this.obtained=!0,e(!0),await i):e(!1)});return await t}releaseLock(){this.obtained=!1,null!==this.abortLockObtain&&(this.abortLockObtain(),this.abortLockObtain=null)}}class k{static set(e){localStorage.setItem(this.key,JSON.stringify(e))}static get(){try{const e=localStorage.getItem(this.key);if(!e)return null;return JSON.parse(e)}catch{return null}}static clear(){localStorage.removeItem(this.key)}}Object.defineProperty(k,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class x{constructor(){Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class G extends T{constructor(e){super(),Object.defineProperty(this,"context",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"version",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"singletonLock",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"logger",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"httpClient",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"feedCache",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"ws",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),Object.defineProperty(this,"pushMessageProcessor",{enumerable:!0,configurable:!0,writable:!0,value:void 0}),this.context={isLogin:!1,loginUser:null,isReady:!1,deviceId:null},this.version=new x,this.singletonLock=new I,this.logger=new M,this.httpClient=new O({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new R,this.ws=new v({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new U({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.afterLogout()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.afterLogout()})}async requestDeviceId(){if(this.context.deviceId)return!0;const e=await this.httpClient.post("/device_api/device_id",{platform:"web",hash_str:""},{needSign:!1});return!!e.ok&&(this.context.deviceId=e.data,this.saveContext(),!0)}saveContext(){const{context:e}=this;k.set({deviceId:e.deviceId})}loadContext(){const e=k.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.ws.connect(),this.loadFeedList(),this.context.isReady=!0,this.emit(E.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(E.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const i=await this.httpClient.get("/feed",{limit:500,last_refresh_at:t.refresh_at??void 0,last_feed_id:t.feed_id??void 0});if(!this.version.check(e))break;if(!i.ok)break;if(t.refresh_at=i.data.refresh_at,t.feed_id=i.data.last_feed_id,i.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!i.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(E.FEED_LIST_UPDATED,{list:this.feedCache.getAll(),is_sync_completed:!0}))}isReady(){return this.context.isReady}setLogLevel(e){this.logger.setLogLevel(e)}async login(e){if(this.context.isLogin)return b(null);if(!await this.singletonLock.requestLock())return this.logger.error("Another active TypeX SDK instance detected"),m(c.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),m(c.SDK_ERROR,"Get deviceId failed");const t=await this.httpClient.post("/user/session/login",{userCode:e.user_code,device_id:this.context.deviceId},{needSign:!1});if(!t.ok)return this.singletonLock.releaseLock(),t;const i=h.get("sessionid");return i?(this.context.isLogin=!0,this.context.loginUser={userId:t.data.id,secretKey:t.data.key,sessionId:i},this.applyLoginStatus(),b(null)):(this.singletonLock.releaseLock(),m(c.SDK_ERROR,"Get sessionId failed"))}async logout(){if(!this.context.isLogin)return b(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),b(null)):e}async afterLogout(){this.context.isLogin=!1,this.context.loginUser=null,this.applyLoginStatus()}getLoginUser(){return null===this.context.loginUser?null:this.context.loginUser.userId}async createSingleChatFeed(e){return await this.httpClient.post("/chat/single",{receiver_id:e})}async deleteFeed(e){return await this.httpClient.post("/feed/delete",{feed_id_list:[e],delete_peer:!0})}async getFeedList(){return b({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return b(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const i=t.data,{chat_id:s,first_position:n,last_message_position:o}=i,{positions:r,nextPosition:a,hasMore:l}=(e=>{const t=[];if(e.direction===d.up){let i=e.startPosition??e.maxPosition;for(;t.length<e.limit&&i>=e.minPosition;)t.push(i),i--;const s=i>=e.minPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}{let i=e.startPosition??e.minPosition;for(;t.length<e.limit&&i<=e.maxPosition;)t.push(i),i++;const s=i<=e.maxPosition;let n;return s&&(n=i),{positions:t,nextPosition:n,hasMore:s}}})({maxPosition:o,minPosition:n,startPosition:e.message_position,limit:e.limit,direction:e.direction??d.up});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[s]:r}},{needSign:!1});if(e.ok&&e.data[s]){return b({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return b({has_more:!1,list:[]})}createCustomMessage(e){if(null===this.context.loginUser)return m(c.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return m(c.SDK_ERROR,"not found feed");var i;return b({id:"",chat_id:t.chat_id,thread_id:t.thread_id,position:t.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:n.text,message_type_id:o.custom,send_at:(new Date).toISOString(),reader_ids:[],unreader_ids:[],hide_ids:[],operation:a.normal,operation_user_id:"0",content:(i={client_msg_id:e.client_msg_id,content:e.content},JSON.stringify({client_msg_id:i.client_msg_id,content:JSON.stringify(i.content)}))})}async sendMessageToFeed(e){if(e.message_type_id===o.custom){const t=S(e.content);return this.httpClient.post("/message/send_custom",{chat_id:e.chat_id,thread_id:e.thread_id,client_id:t.client_msg_id,content:null==t.content?void 0:JSON.stringify(t.content)})}return m(c.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?m(c.SDK_ERROR,"not found feed"):await this.httpClient.post("/message/read",{chat_id:t.chat_id,message_ids:e.message_ids})}async joinRoom(e){return await this.httpClient.post("/liveshow/join",{room_id:e})}async leaveRoom(e){return await this.httpClient.post("/liveshow/leave",{room_id:e})}async getRoomRecentMessageList(e){const t=await this.httpClient.get("/liveshow/get_recent_message",{room_id:e});return t.ok?b(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const N=new Map;const F={parseSystemMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=C(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:S};exports.ChatSDK=G,exports.create=function(e,t){let i=N.get(e);return void 0===i&&(i=new G(t),N.set(e,i)),i},exports.enums=g,exports.events=p,exports.interfaces=f,exports.utils=F;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@typexim/web-sdk",
3
- "version": "0.0.4-alpha.4",
3
+ "version": "0.0.4-alpha.6",
4
4
  "private": false,
5
5
  "repository": "git@github.com:secure-typex/typex-web-sdk.git",
6
6
  "license": "MIT",