@typexim/web-sdk 0.0.4-alpha.1 → 0.0.4-alpha.10
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 +42 -1
- package/dist/types/enums/business.d.ts +18 -22
- package/dist/types/enums/sdk.d.ts +17 -0
- package/dist/types/events.d.ts +44 -5
- package/dist/types/index.d.ts +7 -1
- package/dist/types/interfaces/business.d.ts +43 -11
- package/dist/types/interfaces/pushMessage.d.ts +17 -5
- package/dist/types/interfaces/sdk/api.d.ts +12 -4
- package/dist/types/interfaces/sdk/common.d.ts +21 -10
- package/dist/types/modules/ChatSDK.d.ts +9 -10
- package/dist/types/modules/FeedCache.d.ts +6 -2
- package/dist/types/modules/Logger.d.ts +3 -3
- package/dist/types/modules/PushMessageProcessor.d.ts +1 -0
- package/dist/types/modules/SingletonLock.d.ts +4 -3
- package/dist/types/utils/date.d.ts +1 -0
- package/dist/types/utils/http.d.ts +2 -2
- package/dist/types/utils/message.d.ts +8 -2
- package/dist/web-sdk.esm.js +1 -1
- package/dist/web-sdk.js +1 -1
- package/package.json +2 -4
- package/rollup.config.js +2 -1
- package/tsconfig.json +2 -2
package/README.md
CHANGED
|
@@ -1,5 +1,41 @@
|
|
|
1
1
|
# TypeX WEB SDK
|
|
2
2
|
|
|
3
|
+
## 调用方式
|
|
4
|
+
|
|
5
|
+
```javascript
|
|
6
|
+
import { create, enums, events } from '@typexim/web-sdk';
|
|
7
|
+
|
|
8
|
+
const chat = create('sdk', {
|
|
9
|
+
httpHost: 'https://coco.typex.im',
|
|
10
|
+
websocketHost: 'wss://w.typexim.com'
|
|
11
|
+
})
|
|
12
|
+
|
|
13
|
+
chat.setLogLevel(enums.LogLevel.info);
|
|
14
|
+
|
|
15
|
+
chat.login({
|
|
16
|
+
user_code: 'xxxx'
|
|
17
|
+
});
|
|
18
|
+
chat.once(
|
|
19
|
+
events.CHAT_SDK_EVENT.SDK_READY,
|
|
20
|
+
async () => {
|
|
21
|
+
chat.on(
|
|
22
|
+
events.CHAT_SDK_EVENT.FEED_LIST_UPDATED
|
|
23
|
+
({ is_sync_completed, list }) => {
|
|
24
|
+
console.log('feed列表', list);
|
|
25
|
+
}
|
|
26
|
+
);
|
|
27
|
+
|
|
28
|
+
const result = await chat.getFeedList();
|
|
29
|
+
if (result.ok) {
|
|
30
|
+
console.log('feed列表', result.data.list);
|
|
31
|
+
} else {
|
|
32
|
+
console.log(result.code);
|
|
33
|
+
console.log(result.msg);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
);
|
|
37
|
+
```
|
|
38
|
+
|
|
3
39
|
## API清单
|
|
4
40
|
|
|
5
41
|
### 事件
|
|
@@ -12,10 +48,11 @@
|
|
|
12
48
|
1. SDK_READY
|
|
13
49
|
2. SDK_NOT_READY
|
|
14
50
|
3. MESSAGE_RECEIVED
|
|
15
|
-
4.
|
|
51
|
+
4. MESSAGE_RECALLED
|
|
16
52
|
5. MESSAGE_RECEIPT_RECEIVED
|
|
17
53
|
6. FEED_LIST_UPDATED
|
|
18
54
|
7. ROOM_MESSAGE_RECEIVED
|
|
55
|
+
8. SYSTEM_NOTICE_RECEIVED
|
|
19
56
|
|
|
20
57
|
### 初始化
|
|
21
58
|
|
|
@@ -58,3 +95,7 @@
|
|
|
58
95
|
|
|
59
96
|
1. getRoomRecentMessageList(最近50条)
|
|
60
97
|
2. sendMessageToRoom
|
|
98
|
+
|
|
99
|
+
## 注意事项
|
|
100
|
+
|
|
101
|
+
1. 同个浏览器只有最先调用login成功的窗口可以正常使用,其他窗口要使用就得先在已登录的窗口调用logout或者关闭窗口
|
|
@@ -2,14 +2,6 @@ export declare enum Boolean {
|
|
|
2
2
|
yes = 1,
|
|
3
3
|
no = 0
|
|
4
4
|
}
|
|
5
|
-
export declare enum ApiResponseCode {
|
|
6
|
-
SDK_ERROR = -10000,
|
|
7
|
-
NETWORK_ERROR = -9999,
|
|
8
|
-
MAKE_SIGN_FAIL = -9998,
|
|
9
|
-
REQUEST_SINGLETON_LOCK_FAIL = -9997,
|
|
10
|
-
PARAMS_INVALID = -9996,
|
|
11
|
-
SUCCESS = 0
|
|
12
|
-
}
|
|
13
5
|
export declare enum PushMessageType {
|
|
14
6
|
CREATE_FEED = 0,
|
|
15
7
|
UPDATE_FEED = 1,
|
|
@@ -58,6 +50,7 @@ export declare enum PushMessageType {
|
|
|
58
50
|
ON_DELETE_PRIVATE_SETTING = 53,
|
|
59
51
|
ON_UPDATE_LOGIN_PRIVATE_SETTING = 54,
|
|
60
52
|
PUSH_LIVE_MESSAGE = 56,
|
|
53
|
+
PUSH_SYSTEM_NOTICE = 58,
|
|
61
54
|
BIG_PACKAGE_PUSH = 126,
|
|
62
55
|
KICK_OUT_DEVICE = 127,
|
|
63
56
|
CLEAR_HISTORY = 128,
|
|
@@ -73,6 +66,16 @@ export declare enum ChatType {
|
|
|
73
66
|
*/
|
|
74
67
|
groupChat = 2
|
|
75
68
|
}
|
|
69
|
+
export declare enum FeedType {
|
|
70
|
+
/**
|
|
71
|
+
* 常规
|
|
72
|
+
*/
|
|
73
|
+
normal = 0,
|
|
74
|
+
/**
|
|
75
|
+
* 消息串
|
|
76
|
+
*/
|
|
77
|
+
thread = 1
|
|
78
|
+
}
|
|
76
79
|
export declare enum MessageKind {
|
|
77
80
|
text = 0,//普通
|
|
78
81
|
system = 1
|
|
@@ -89,11 +92,6 @@ export declare enum MessageType {
|
|
|
89
92
|
richText = 8,//富文本消息
|
|
90
93
|
custom = 9
|
|
91
94
|
}
|
|
92
|
-
export declare enum MessageSendStatus {
|
|
93
|
-
success = 0,
|
|
94
|
-
sending = 1,
|
|
95
|
-
failed = 2
|
|
96
|
-
}
|
|
97
95
|
/** 群成员角色 */
|
|
98
96
|
export declare enum GroupRole {
|
|
99
97
|
Owner = 1,
|
|
@@ -102,14 +100,12 @@ export declare enum GroupRole {
|
|
|
102
100
|
Bot = 4
|
|
103
101
|
}
|
|
104
102
|
export declare enum MessageOperation {
|
|
105
|
-
|
|
103
|
+
/**
|
|
104
|
+
* 正常
|
|
105
|
+
*/
|
|
106
|
+
normal = 0,
|
|
107
|
+
/**
|
|
108
|
+
* 撤回
|
|
109
|
+
*/
|
|
106
110
|
recall = 1
|
|
107
111
|
}
|
|
108
|
-
export declare enum GroupType {
|
|
109
|
-
/** 加密群聊 */
|
|
110
|
-
private = 1,
|
|
111
|
-
/** 超级群聊 */
|
|
112
|
-
public = 0,
|
|
113
|
-
/** 匿名群聊,新增群聊类型 */
|
|
114
|
-
anonymous = 2
|
|
115
|
-
}
|
|
@@ -3,3 +3,20 @@ export declare enum LogLevel {
|
|
|
3
3
|
warning = "WARNING",
|
|
4
4
|
info = "INFO"
|
|
5
5
|
}
|
|
6
|
+
export declare enum HttpClientResponseCode {
|
|
7
|
+
SDK_ERROR = -10000,
|
|
8
|
+
NETWORK_ERROR = -9999,
|
|
9
|
+
MAKE_SIGN_FAIL = -9998,
|
|
10
|
+
REQUEST_SINGLETON_LOCK_FAIL = -9997,
|
|
11
|
+
SUCCESS = 0
|
|
12
|
+
}
|
|
13
|
+
export declare enum RequestDirection {
|
|
14
|
+
/**
|
|
15
|
+
* 向上请求数据
|
|
16
|
+
*/
|
|
17
|
+
up = 0,
|
|
18
|
+
/**
|
|
19
|
+
* 向下请求数据
|
|
20
|
+
*/
|
|
21
|
+
down = 1
|
|
22
|
+
}
|
package/dist/types/events.d.ts
CHANGED
|
@@ -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
|
|
22
|
+
readonly MESSAGE_RECALLED: "messageRecalled";
|
|
23
23
|
/**
|
|
24
24
|
* sdk收到message已读回执
|
|
25
25
|
*/
|
|
@@ -28,16 +28,40 @@ export declare const CHAT_SDK_EVENT: {
|
|
|
28
28
|
* sdk收到直播间message
|
|
29
29
|
*/
|
|
30
30
|
readonly ROOM_MESSAGE_RECEIVED: "roomMessageReceived";
|
|
31
|
+
/**
|
|
32
|
+
* sdk收到系统在线通知(通过OpenAPI的/open/message/notice接口触发)
|
|
33
|
+
*/
|
|
34
|
+
readonly SYSTEM_NOTICE_RECEIVED: "systemNoticeReceived";
|
|
31
35
|
};
|
|
32
36
|
export type CHAT_SDK_EVENT_MAP = {
|
|
33
37
|
[CHAT_SDK_EVENT.SDK_READY]: void;
|
|
34
38
|
[CHAT_SDK_EVENT.SDK_NOT_READY]: void;
|
|
35
39
|
[CHAT_SDK_EVENT.FEED_LIST_UPDATED]: {
|
|
40
|
+
/**
|
|
41
|
+
* feed同步是否完成
|
|
42
|
+
*/
|
|
36
43
|
is_sync_completed: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* feed列表
|
|
46
|
+
*/
|
|
37
47
|
list: Feed[];
|
|
38
48
|
};
|
|
39
|
-
[CHAT_SDK_EVENT.MESSAGE_RECEIVED]:
|
|
40
|
-
|
|
49
|
+
[CHAT_SDK_EVENT.MESSAGE_RECEIVED]: {
|
|
50
|
+
/**
|
|
51
|
+
* 收到的消息所属的feed_id
|
|
52
|
+
*/
|
|
53
|
+
feed_id: string;
|
|
54
|
+
/**
|
|
55
|
+
* 收到的消息
|
|
56
|
+
*/
|
|
57
|
+
message: Message;
|
|
58
|
+
};
|
|
59
|
+
[CHAT_SDK_EVENT.MESSAGE_RECALLED]: {
|
|
60
|
+
/**
|
|
61
|
+
* 撤回的消息id列表
|
|
62
|
+
*/
|
|
63
|
+
message_ids: string[];
|
|
64
|
+
};
|
|
41
65
|
[CHAT_SDK_EVENT.MESSAGE_RECEIPT_RECEIVED]: {
|
|
42
66
|
/**
|
|
43
67
|
* feed id
|
|
@@ -52,5 +76,20 @@ export type CHAT_SDK_EVENT_MAP = {
|
|
|
52
76
|
*/
|
|
53
77
|
reader_user_ids: string[];
|
|
54
78
|
};
|
|
55
|
-
[CHAT_SDK_EVENT.ROOM_MESSAGE_RECEIVED]:
|
|
79
|
+
[CHAT_SDK_EVENT.ROOM_MESSAGE_RECEIVED]: {
|
|
80
|
+
/**
|
|
81
|
+
* 直播间id
|
|
82
|
+
*/
|
|
83
|
+
room_id: string;
|
|
84
|
+
/**
|
|
85
|
+
* 消息内容
|
|
86
|
+
*/
|
|
87
|
+
content: string;
|
|
88
|
+
};
|
|
89
|
+
[CHAT_SDK_EVENT.SYSTEM_NOTICE_RECEIVED]: {
|
|
90
|
+
/**
|
|
91
|
+
* 收到的消息
|
|
92
|
+
*/
|
|
93
|
+
content: string;
|
|
94
|
+
};
|
|
56
95
|
};
|
package/dist/types/index.d.ts
CHANGED
|
@@ -3,7 +3,13 @@ import * as events from './events';
|
|
|
3
3
|
import * as interfaces from './interfaces';
|
|
4
4
|
import { ChatSDKConfig } from './interfaces/sdk';
|
|
5
5
|
import ChatSDK from './modules/ChatSDK';
|
|
6
|
-
|
|
6
|
+
/**
|
|
7
|
+
* 创建一个ChatSDK实例,对于同一个instanceId只会返回同一份实例
|
|
8
|
+
* @param instanceId ChatSDK实例唯一id
|
|
9
|
+
* @param config ChatSDK配置
|
|
10
|
+
* @returns
|
|
11
|
+
*/
|
|
12
|
+
export declare function create(instanceId: string, config: ChatSDKConfig): ChatSDK;
|
|
7
13
|
export declare const utils: {
|
|
8
14
|
parseSystemMessageContent: (str: string) => {
|
|
9
15
|
text?: string;
|
|
@@ -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
|
-
*
|
|
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
|
-
*
|
|
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
|
-
*
|
|
52
|
+
* 会话成员的user_id列表
|
|
45
53
|
*/
|
|
46
54
|
chat_member: string[];
|
|
47
55
|
/**
|
|
@@ -68,18 +76,22 @@ export type Feed = {
|
|
|
68
76
|
* 首条消息的position
|
|
69
77
|
*/
|
|
70
78
|
first_position: number;
|
|
79
|
+
/**
|
|
80
|
+
* 最后一条消息的id
|
|
81
|
+
*/
|
|
82
|
+
last_message_id: string;
|
|
71
83
|
/**
|
|
72
84
|
* 最后一条消息的position
|
|
73
85
|
*/
|
|
74
86
|
last_message_position: number;
|
|
75
87
|
/**
|
|
76
|
-
*
|
|
88
|
+
* 最后一条消息的发送者id
|
|
77
89
|
*/
|
|
78
|
-
|
|
90
|
+
last_message_sender_id: string;
|
|
79
91
|
/**
|
|
80
|
-
*
|
|
92
|
+
* 最后一条消息的发送时间
|
|
81
93
|
*/
|
|
82
|
-
|
|
94
|
+
last_message_send_at: string;
|
|
83
95
|
/**
|
|
84
96
|
* 最后一条消息的来源类别
|
|
85
97
|
*/
|
|
@@ -88,6 +100,18 @@ export type Feed = {
|
|
|
88
100
|
* 最后一条消息的消息类别
|
|
89
101
|
*/
|
|
90
102
|
last_message_type_id: MessageType;
|
|
103
|
+
/**
|
|
104
|
+
* 最后一条消息的内容(content)
|
|
105
|
+
*/
|
|
106
|
+
last_message: string;
|
|
107
|
+
/**
|
|
108
|
+
* 最后一条消息的操作状态
|
|
109
|
+
*/
|
|
110
|
+
last_message_operation: MessageOperation;
|
|
111
|
+
/**
|
|
112
|
+
* 最后一条消息的操作人id
|
|
113
|
+
*/
|
|
114
|
+
last_message_operation_user_id: string;
|
|
91
115
|
};
|
|
92
116
|
export type Message = {
|
|
93
117
|
/**
|
|
@@ -95,15 +119,19 @@ export type Message = {
|
|
|
95
119
|
*/
|
|
96
120
|
id: string;
|
|
97
121
|
/**
|
|
98
|
-
* chat id
|
|
122
|
+
* chat id,feed和在这个feed发起的消息串chat_id相同
|
|
99
123
|
*/
|
|
100
124
|
chat_id: string;
|
|
125
|
+
/**
|
|
126
|
+
* 消息串id
|
|
127
|
+
*/
|
|
128
|
+
thread_id: string;
|
|
101
129
|
/**
|
|
102
130
|
* 消息位置
|
|
103
131
|
*/
|
|
104
132
|
position: number;
|
|
105
133
|
/**
|
|
106
|
-
* 发送者
|
|
134
|
+
* 发送者id
|
|
107
135
|
*/
|
|
108
136
|
sender_id: string;
|
|
109
137
|
/**
|
|
@@ -126,6 +154,10 @@ export type Message = {
|
|
|
126
154
|
* 已读信息的用户id
|
|
127
155
|
*/
|
|
128
156
|
reader_ids: string[];
|
|
157
|
+
/**
|
|
158
|
+
* 未读信息的用户id
|
|
159
|
+
*/
|
|
160
|
+
unreader_ids: string[];
|
|
129
161
|
/**
|
|
130
162
|
* 存放对某些隐藏消息的用户的Id
|
|
131
163
|
*/
|
|
@@ -14,20 +14,32 @@ 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, Message
|
|
18
|
-
export type PushMessageUserLogin = PushMessageBase<PushMessageType.USER_LOGIN>;
|
|
17
|
+
export type PushMessageUpdateMessage = PushMessageBase<PushMessageType.UPDATE_MESSAGE, Partial<Message> & Pick<Message, 'id' | 'chat_id' | 'thread_id'>>;
|
|
19
18
|
export type PushMessageDeleteFeed = PushMessageBase<PushMessageType.DELETE_FEED, {
|
|
20
19
|
/**
|
|
21
20
|
* feed id
|
|
22
21
|
*/
|
|
23
22
|
id: string;
|
|
24
23
|
}>;
|
|
25
|
-
|
|
24
|
+
/**
|
|
25
|
+
* 直播间消息推送,调用/liveshow/send_message触发
|
|
26
|
+
*/
|
|
27
|
+
export type PushMessagePushLiveMessage = PushMessageBase<PushMessageType.PUSH_LIVE_MESSAGE, {
|
|
28
|
+
/**
|
|
29
|
+
* 直播间id
|
|
30
|
+
*/
|
|
31
|
+
room_id: string;
|
|
32
|
+
/**
|
|
33
|
+
*
|
|
34
|
+
*/
|
|
35
|
+
message: string;
|
|
36
|
+
}>;
|
|
26
37
|
export type PushMessageReadMessage = PushMessageBase<PushMessageType.READ_MESSAGE, {
|
|
27
38
|
chat_id: string;
|
|
28
39
|
message_ids: string[];
|
|
29
40
|
reader_ids: string[];
|
|
30
|
-
|
|
41
|
+
thread_id: string;
|
|
31
42
|
}>;
|
|
32
|
-
export type
|
|
43
|
+
export type PushMessagePushSystemNotice = PushMessageBase<PushMessageType.PUSH_SYSTEM_NOTICE, string>;
|
|
44
|
+
export type SpecialPushMessage = PushMessagePong | PushMessageBigPackage | PushMessageCreateFeed | PushMessageUpdateFeeds | PushMessageAddMessage | PushMessageUpdateMessage | PushMessageDeleteFeed | PushMessagePushLiveMessage | PushMessageReadMessage | PushMessagePushSystemNotice;
|
|
33
45
|
export type PushMessage = PushMessageBase<Exclude<PushMessageType, SpecialPushMessage['type']>> | SpecialPushMessage;
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { RequestDirection } from '../../enums';
|
|
1
2
|
import { Feed, Message } from '../business';
|
|
2
3
|
import { HttpClientResponse } from './common';
|
|
3
4
|
export type SDKLoginReq = {
|
|
@@ -20,9 +21,16 @@ export type SDKGetFeedMessageListReq = {
|
|
|
20
21
|
*/
|
|
21
22
|
feed_id: string;
|
|
22
23
|
/**
|
|
23
|
-
* 上一次分页查询返回的
|
|
24
|
+
* 上一次分页查询返回的next_message_position
|
|
25
|
+
*/
|
|
26
|
+
message_position?: number;
|
|
27
|
+
/**
|
|
28
|
+
* 消息拉取方向,向上拉更旧,向下拉更新,默认为RequestDirection.up
|
|
29
|
+
*/
|
|
30
|
+
direction?: RequestDirection;
|
|
31
|
+
/**
|
|
32
|
+
* 需要拉取的消息数量
|
|
24
33
|
*/
|
|
25
|
-
last_message_position?: number;
|
|
26
34
|
limit: number;
|
|
27
35
|
};
|
|
28
36
|
export type SDKGetFeedMessageListRespData = {
|
|
@@ -35,9 +43,9 @@ export type SDKGetFeedMessageListRespData = {
|
|
|
35
43
|
*/
|
|
36
44
|
list: Message[];
|
|
37
45
|
/**
|
|
38
|
-
*
|
|
46
|
+
* 下一页查询时需要携带
|
|
39
47
|
*/
|
|
40
|
-
|
|
48
|
+
next_message_position?: number;
|
|
41
49
|
};
|
|
42
50
|
export type SDKGetFeedMessageListResp = HttpClientResponse<SDKGetFeedMessageListRespData>;
|
|
43
51
|
export type SDKCreateCustomMessageReq<T = any> = {
|
|
@@ -12,31 +12,42 @@ export type ChatSDKConfig = {
|
|
|
12
12
|
*/
|
|
13
13
|
developer?: string;
|
|
14
14
|
};
|
|
15
|
-
type
|
|
15
|
+
export type ChatSDKContext = {
|
|
16
16
|
isReady: boolean;
|
|
17
17
|
deviceId: string | null;
|
|
18
|
-
|
|
19
|
-
type ChatSDKContextLogin = ChatSDKContextBase & {
|
|
20
|
-
isLogin: true;
|
|
18
|
+
isLogin: boolean;
|
|
21
19
|
loginUser: {
|
|
22
20
|
userId: string;
|
|
23
21
|
secretKey: string;
|
|
24
22
|
sessionId: string;
|
|
25
|
-
};
|
|
26
|
-
};
|
|
27
|
-
type ChatSDKContextNotLogin = ChatSDKContextBase & {
|
|
28
|
-
isLogin: false;
|
|
23
|
+
} | null;
|
|
29
24
|
};
|
|
30
|
-
export type ChatSDKContext = ChatSDKContextLogin | ChatSDKContextNotLogin;
|
|
31
25
|
export type HttpClientResponseOk<T = unknown> = {
|
|
26
|
+
/**
|
|
27
|
+
* 调用成功
|
|
28
|
+
*/
|
|
32
29
|
ok: true;
|
|
30
|
+
/**
|
|
31
|
+
* 响应数据
|
|
32
|
+
*/
|
|
33
33
|
data: T;
|
|
34
34
|
};
|
|
35
35
|
export type HttpClientResponseFail = {
|
|
36
|
+
/**
|
|
37
|
+
* 调用失败
|
|
38
|
+
*/
|
|
36
39
|
ok: false;
|
|
40
|
+
/**
|
|
41
|
+
* 调用失败code
|
|
42
|
+
*/
|
|
37
43
|
code: number;
|
|
44
|
+
/**
|
|
45
|
+
* 调用失败说明
|
|
46
|
+
*/
|
|
38
47
|
msg: string;
|
|
48
|
+
/**
|
|
49
|
+
* 调用失败说明(国际化)
|
|
50
|
+
*/
|
|
39
51
|
msg_i18n?: Record<string, string>;
|
|
40
52
|
};
|
|
41
53
|
export type HttpClientResponse<T = unknown> = HttpClientResponseOk<T> | HttpClientResponseFail;
|
|
42
|
-
export {};
|
|
@@ -30,22 +30,21 @@ export default class ChatSDK extends Base<CHAT_SDK_EVENT_MAP> {
|
|
|
30
30
|
*/
|
|
31
31
|
setLogLevel(level: LogLevel): void;
|
|
32
32
|
/**
|
|
33
|
-
*
|
|
34
|
-
*
|
|
35
|
-
* @
|
|
36
|
-
* @returns {Promise<HttpClientResponse>} 成功返回 ok,失败返回错误信息
|
|
33
|
+
* 使用user_code登录,建立会话并连接WebSocket,成功后会触发事件:SDK_READY
|
|
34
|
+
* @param req
|
|
35
|
+
* @returns
|
|
37
36
|
*/
|
|
38
37
|
login(req: SDKLoginReq): Promise<HttpClientResponse>;
|
|
39
38
|
/**
|
|
40
|
-
* 退出当前登录用户并断开
|
|
41
|
-
*
|
|
42
|
-
* @returns
|
|
39
|
+
* 退出当前登录用户并断开WebSocket,成功后会触发事件:SDK_NOT_READY
|
|
40
|
+
* 注意,登出后user_code便会失效
|
|
41
|
+
* @returns
|
|
43
42
|
*/
|
|
44
43
|
logout(): Promise<HttpClientResponse>;
|
|
45
|
-
private
|
|
44
|
+
private afterLogout;
|
|
46
45
|
/**
|
|
47
|
-
* 获取当前登录用户的
|
|
48
|
-
* @returns
|
|
46
|
+
* 获取当前登录用户的user_id
|
|
47
|
+
* @returns
|
|
49
48
|
*/
|
|
50
49
|
getLoginUser(): string | null;
|
|
51
50
|
/**
|
|
@@ -1,17 +1,21 @@
|
|
|
1
1
|
import { Feed } from '../interfaces';
|
|
2
2
|
export default class FeedCache {
|
|
3
|
-
private
|
|
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
|
-
|
|
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(
|
|
11
|
-
warn(
|
|
12
|
-
error(
|
|
10
|
+
info(...args: any[]): void;
|
|
11
|
+
warn(...args: any[]): void;
|
|
12
|
+
error(...args: any[]): void;
|
|
13
13
|
}
|
|
@@ -22,6 +22,7 @@ export default class PushMessageProcessor {
|
|
|
22
22
|
private processAddMessage;
|
|
23
23
|
private processUpdateMessage;
|
|
24
24
|
private processPushLiveMessage;
|
|
25
|
+
private processPushSystemNotice;
|
|
25
26
|
private processReadMessage;
|
|
26
27
|
private processKickOutDevice;
|
|
27
28
|
process(pushMessage: PushMessage): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare function getCurrentISOString(): string;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { HttpClientResponseCode } from '../enums';
|
|
2
2
|
import { HttpClientResponseFail, HttpClientResponseOk } from '../interfaces/sdk';
|
|
3
|
-
export declare function createErrorResponse(code:
|
|
3
|
+
export declare function createErrorResponse(code: Exclude<HttpClientResponseCode, HttpClientResponseCode.SUCCESS>, msg: string): HttpClientResponseFail;
|
|
4
4
|
export declare function createOkResponse<T = unknown>(data: T): HttpClientResponseOk<T>;
|
|
@@ -1,9 +1,15 @@
|
|
|
1
|
+
import { RequestDirection } from '../enums';
|
|
1
2
|
export declare const makePositions: (config: {
|
|
2
3
|
maxPosition: number;
|
|
3
4
|
minPosition: number;
|
|
4
|
-
|
|
5
|
+
startPosition?: number;
|
|
6
|
+
direction: RequestDirection;
|
|
5
7
|
limit: number;
|
|
6
|
-
}) =>
|
|
8
|
+
}) => {
|
|
9
|
+
positions: number[];
|
|
10
|
+
nextPosition?: number;
|
|
11
|
+
hasMore: boolean;
|
|
12
|
+
};
|
|
7
13
|
export declare const stringifyCustomMessageContent: (payload: {
|
|
8
14
|
client_msg_id?: string;
|
|
9
15
|
content: any;
|
package/dist/web-sdk.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import e from"js-cookie";import t from"axios";import s from"crypto-js";var i,n,o,r,a,c,h,d,l,_,E;!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(i||(i={})),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.PARAMS_INVALID=-9996]="PARAMS_INVALID",e[e.SUCCESS=0]="SUCCESS"}(n||(n={})),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"}(o||(o={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(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"}(c||(c={})),function(e){e[e.success=0]="success",e[e.sending=1]="sending",e[e.failed=2]="failed"}(h||(h={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(d||(d={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(l||(l={})),function(e){e[e.private=1]="private",e[e.public=0]="public",e[e.anonymous=2]="anonymous"}(_||(_={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(E||(E={}));var g=Object.freeze({__proto__:null,get ApiResponseCode(){return n},get Boolean(){return i},get ChatType(){return r},get GroupRole(){return d},get GroupType(){return _},get LogLevel(){return E},get MessageKind(){return a},get MessageOperation(){return l},get MessageSendStatus(){return h},get MessageType(){return c},get PushMessageType(){return o}});const u={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 p=Object.freeze({__proto__:null,CHAT_SDK_EVENT:u}),m=Object.freeze({__proto__:null});function S(e,t){return{ok:!1,code:e,msg:t}}function f(e){return{ok:!0,data:e}}const T=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},A=e=>{const t=T(e);if(null!==t){let e;return null!=t.content&&(e=T(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class C{all;constructor(e){this.all=e||new Map}on(e,t){const s=this.all.get(e);return s?s.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const s=this.all.get(e);s&&(t?s.splice(s.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let s=this.all.get(e);s&&s.slice().map(e=>{e(t)}),s=this.all.get("*"),s&&s.slice().map(s=>{s(e,t)})}once(e,t){if("*"===e){const s=(e,i)=>{t(e,i),this.off("*",s)};this.on(e,s)}else{const s=i=>{t(i),this.off(e,s)};this.on(e,s)}}}class R extends C{url;logger;ws;destroyed;pingTimeout;pongTimeout;reConnectTimeout;constructor(e){super(),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===o.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(t.id),t.type===o.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 D extends C{host;context;logger;ws;constructor(e){super(),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(!this.context.isLogin)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 R({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 y{_isSyncCompleted;map;chatMap;list;waitMap;constructor(){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 s=this.map.get(t);s&&e.push(s)}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 s=this.waitMap.get(e);return s||(s=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,s)),await s.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 w(e){return(new TextEncoder).encode(e).buffer}async function L(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const s=w(t),i=w(e),n=await crypto.subtle.importKey("raw",s,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,i);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return s.HmacSHA256(e,t).toString(s.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 s of e)t+=P(s);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let s="";for(const i of t)s+=P(e[i]);return s}};function O(){return S(n.MAKE_SIGN_FAIL,"make sign fail")}class I{api;context;logger;constructor(e){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,...s}=e;if(s.headers||(s.headers={}),s.headers.platform="web",t&&"POST"===e.method?.toUpperCase()&&s.data){if(!this.context.isLogin)return this.logger.warn("HttpClient needs make sign but not login"),O();try{const e=await(async(e,t)=>{const s=await P(e);return await L(s,t)})(s.data,this.context.loginUser.secretKey);s.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),O()}}const i=await this.api(s),o=i.data;return o.code===n.SUCCESS?{ok:!0,data:o.data}:(this.logger.info("HttpClient server error",i),{ok:!1,code:o.code,msg:o.msg,msg_i18n:o.msg_i18n})}catch{return{ok:!1,code:n.NETWORK_ERROR,msg:"network error"}}}get(e,t,s){return this.request({url:e,method:"GET",params:t,...s})}post(e,t,s){return this.request({url:e,method:"POST",data:t,...s})}}class U{level;logHandler;constructor(){this.level=E.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case E.error:return 3;case E.warning:return 2;case E.info:return 1;default:return 0}}createLogHandler(){return(e,t,...s)=>{const i=`[tlog] ${(new Date).toISOString().split("T")[0]}`,n=t?`${i} ${t}`:i;switch(e){case E.error:console.error(n,...s);break;case E.warning:console.warn(n,...s);break;case E.info:console.info(n,...s);break;default:console.log(n,...s)}}}log(e,t,...s){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,t,...s)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(e,...t){this.log(E.info,e,...t)}warn(e,...t){this.log(E.warning,e,...t)}error(e,...t){this.log(E.error,e,...t)}}class M{context;logger;emitter;feedCache;handleKickoff;constructor(e){this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(u.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(!this.context.isLogin)return;const t=this.context.loginUser.userId,s=e.content,i=this.feedCache.getByChatId(s.chat_id);if(null!==i){let e=!1;const n={};if(s.message_kind_id!==a.system&&s.sender_id!==t){e=!0;const t=new Set(i.unread_message_ids);t.add(s.id),n.unread_message_ids=[...t],n.badge=t.size}i.last_message_position<s.position&&(e=!0,n.last_message_position=s.position,n.last_message_send_at=s.send_at,n.last_message=s.content,n.last_message_kind_id=s.message_kind_id,n.last_message_type_id=s.message_type_id),e&&(this.feedCache.unshift({...i,...n}),this.emitFeedListUpdated()),this.emitter.emit(u.MESSAGE_RECEIVED,s)}}processUpdateMessage(e){this.emitter.emit(u.MESSAGE_UPDATED,e.content)}processPushLiveMessage(e){this.emitter.emit(u.ROOM_MESSAGE_RECEIVED,e.content)}processReadMessage(e){if(!this.context.isLogin)return;const t=this.context.loginUser.userId,s=this.feedCache.getByChatId(e.content.chat_id);if(null!==s){let i=!1;const n={};if(e.content.reader_ids.includes(t)&&e.content.message_ids.length>0){i=!0;const t=new Set(s.unread_message_ids);e.content.message_ids.forEach(e=>{t.delete(e)}),n.unread_message_ids=[...t],n.badge=t.size}i&&(this.feedCache.update({...s,...n}),this.emitFeedListUpdated()),this.emitter.emit(u.MESSAGE_RECEIPT_RECEIVED,{feed_id:s.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 o.CREATE_FEED:this.processCreateFeed(e);break;case o.DELETE_FEED:this.processDeleteFeed(e);break;case o.ADD_MESSAGE:this.processAddMessage(e);break;case o.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case o.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case o.READ_MESSAGE:this.processReadMessage(e);break;case o.KICK_OUT_DEVICE:this.processKickOutDevice()}}}var v=e=>new Promise(t=>setTimeout(t,e));class k{destroyed;promise;constructor(){this.destroyed=!1;let e=()=>{};const t=new Promise(t=>{e=t});this.promise=t,navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{if(t)for(e(!0);!this.destroyed;)await v(1e4);else e(!1)})}async request(){return await this.promise}}class G{static key="__typex_sdk_data__";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)}}class N{version;constructor(){this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class x extends C{context;version;singletonLock;logger;httpClient;feedCache;ws;pushMessageProcessor;constructor(e){super(),this.context={isLogin:!1,isReady:!1,deviceId:null},this.version=new N,this.singletonLock=new k,this.logger=new U,this.httpClient=new I({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new y,this.ws=new D({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new M({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.handleKickoff()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.handleKickoff()})}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;G.set({deviceId:e.deviceId})}loadContext(){const e=G.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.loadFeedList(),this.ws.connect(),this.context.isReady=!0,this.emit(u.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.context.isReady=!1,this.emit(u.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const s=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(!s.ok)break;if(t.refresh_at=s.data.refresh_at,t.feed_id=s.data.last_feed_id,s.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!s.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(u.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(!await this.singletonLock.request())return this.logger.error("Another active TypeX SDK instance detected"),S(n.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),S(n.SDK_ERROR,"Login params invalid");const s=await this.httpClient.post("/user/session/login",{userCode:t.user_code,device_id:this.context.deviceId},{needSign:!1});return s.ok?(this.context.isLogin=!0,this.context.isLogin&&(this.context.loginUser={userId:s.data.id,secretKey:s.data.key,sessionId:e.get("sessionid")??""}),this.applyLoginStatus(),f(null)):s}async logout(){const e=await this.httpClient.get("/user/logout");return e.ok?(this.context.isLogin=!1,this.applyLoginStatus(),f(null)):e}async handleKickoff(){this.context.isLogin=!1,this.applyLoginStatus()}getLoginUser(){return this.context.isLogin?this.context.loginUser.userId:null}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 f({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return f(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const s=t.data,{chat_id:i,first_position:n,last_message_position:o}=s,r=(e=>{const t=[];let s=e.lastPosition??e.maxPosition;for(;t.length<e.limit&&s>=e.minPosition;)t.push(s),s--;return t})({maxPosition:o,minPosition:n,lastPosition:e.last_message_position,limit:e.limit});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[i]:r}},{needSign:!1});if(e.ok&&e.data[i]){const t=e.data[i].reverse();return f({has_more:r[0]===n,list:t,last_message_position:t[0]?.position})}}}return f({has_more:!1,list:[]})}createCustomMessage(e){if(!this.context.isLogin)return S(n.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return S(n.SDK_ERROR,"not found feed");var s;return f({id:"",chat_id:t.chat_id,position:t.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:a.text,message_type_id:c.custom,send_at:"",reader_ids:[],hide_ids:[],operation:l.normal,operation_user_id:"0",content:(s={client_msg_id:e.client_msg_id,content:e.content},JSON.stringify({client_msg_id:s.client_msg_id,content:JSON.stringify(s.content)}))})}async sendMessageToFeed(e){if(e.message_type_id===c.custom){const t=A(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 S(n.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?S(n.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?f(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}function F(e){return new x(e)}const K={parseSystemMessageContent:e=>{const t=T(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=T(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:A};export{x as ChatSDK,F as create,g as enums,p as events,m as interfaces,K as utils};
|
|
1
|
+
import e from"axios";import t from"crypto-js";var i,s,n,o,r,a,l,c,d,h,u;!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(i||(i={})),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.PUSH_SYSTEM_NOTICE=58]="PUSH_SYSTEM_NOTICE",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"}(s||(s={})),function(e){e[e.singleChat=1]="singleChat",e[e.groupChat=2]="groupChat"}(n||(n={})),function(e){e[e.normal=0]="normal",e[e.thread=1]="thread"}(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.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(l||(l={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(c||(c={})),function(e){e.error="ERROR",e.warning="WARNING",e.info="INFO"}(d||(d={})),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"}(h||(h={})),function(e){e[e.up=0]="up",e[e.down=1]="down"}(u||(u={}));var _=Object.freeze({__proto__:null,get Boolean(){return i},get ChatType(){return n},get FeedType(){return o},get GroupRole(){return l},get HttpClientResponseCode(){return h},get LogLevel(){return d},get MessageKind(){return r},get MessageOperation(){return c},get MessageType(){return a},get PushMessageType(){return s},get RequestDirection(){return u}});const g={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",SYSTEM_NOTICE_RECEIVED:"systemNoticeReceived"};var E=Object.freeze({__proto__:null,CHAT_SDK_EVENT:g}),m=Object.freeze({__proto__:null});function p(e,t){return{ok:!1,code:e,msg:t}}function f(e){return{ok:!0,data:e}}const b=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},S=e=>{const t=b(e);if(null!==t){let e;return null!=t.content&&(e=b(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class C{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 T extends C{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===s.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(t.id),t.type===s.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 A extends C{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 T({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===o.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===o.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 y(e){return(new TextEncoder).encode(e).buffer}async function R(e,i){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=y(t),s=y(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,i):function(e,i){return t.HmacSHA256(e,i).toString(t.enc.Hex)}(e,i)}const w=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=w(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=w(e[s]);return i}};function P(){return p(h.MAKE_SIGN_FAIL,"make sign fail")}class O{constructor(t){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=e.create({baseURL:t.host,headers:{"x-developer":t.developer}}),this.context=t.context,this.logger=t.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"),P();try{const e=await(async(e,t)=>{const i=await w(e);return await R(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),P()}}const s=await this.api(i),n=s.data;return n.code===h.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:h.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 D(e){return`${e}`.padStart(2,"0")}class L{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=d.error,this.logHandler=this.createLogHandler()}getPriority(e){switch(e){case d.error:return 3;case d.warning:return 2;case d.info:return 1;default:return 0}}createLogHandler(){return(e,...t)=>{const i=new Date,s=`TypeX >> [${`${i.getFullYear()}-${D(i.getMonth()+1)}-${D(i.getDate())} ${D(i.getHours())}:${D(i.getMinutes())}:${D(i.getSeconds())}.${i.getMilliseconds()}`}]`;switch(e){case d.error:console.error(s,"[ERR]",...t);break;case d.warning:console.warn(s,"[WARN]",...t);break;case d.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(d.info,...e)}warn(...e){this.log(d.warning,...e)}error(...e){this.log(d.error,...e)}}class M{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(g.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!==r.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(g.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===c.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===c.recall&&this.emitter.emit(g.MESSAGE_RECALLED,{message_ids:[t.id]})}}processPushLiveMessage(e){this.emitter.emit(g.ROOM_MESSAGE_RECEIVED,{room_id:e.content.room_id,content:e.content.message})}processPushSystemNotice(e){this.emitter.emit(g.SYSTEM_NOTICE_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(g.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 s.CREATE_FEED:this.processCreateFeed(e);break;case s.DELETE_FEED:this.processDeleteFeed(e);break;case s.ADD_MESSAGE:this.processAddMessage(e);break;case s.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case s.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case s.PUSH_SYSTEM_NOTICE:this.processPushSystemNotice(e);break;case s.READ_MESSAGE:this.processReadMessage(e);break;case s.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 U{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(U,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class k{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 N extends C{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 k,this.singletonLock=new I,this.logger=new L,this.httpClient=new O({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new v,this.ws=new A({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new M({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;U.set({deviceId:e.deviceId})}loadContext(){const e=U.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(g.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(g.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(g.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 f(null);if(!await this.singletonLock.requestLock())return this.logger.error("Another active TypeX SDK instance detected"),p(h.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),p(h.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});return t.ok?(this.context.isLogin=!0,this.context.loginUser={userId:t.data.id,secretKey:t.data.key,sessionId:e.user_code},this.applyLoginStatus(),f(null)):(this.singletonLock.releaseLock(),t)}async logout(){if(!this.context.isLogin)return f(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),f(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 f({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return f(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===u.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??u.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 f({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return f({has_more:!1,list:[]})}createCustomMessage(e){if(null===this.context.loginUser)return p(h.SDK_ERROR,"not login");const t=this.feedCache.get(e.feed_id);if(null===t)return p(h.SDK_ERROR,"not found feed");var i;return f({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:r.text,message_type_id:a.custom,send_at:(new Date).toISOString(),reader_ids:[],unreader_ids:[],hide_ids:[],operation:c.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=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 p(h.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const t=this.feedCache.get(e.feed_id);return null===t?p(h.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?f(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const G=new Map;function x(e,t){let i=G.get(e);return void 0===i&&(i=new N(t),G.set(e,i)),i}const F={parseSystemMessageContent:e=>{const t=b(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=b(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:S};export{N as ChatSDK,x as create,_ as enums,E as events,m as interfaces,F as utils};
|
package/dist/web-sdk.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var e,t,s,i,n,o,r,a,c,h,l,d=require("js-cookie"),_=require("axios"),E=require("crypto-js");!function(e){e[e.yes=1]="yes",e[e.no=0]="no"}(e||(e={})),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.PARAMS_INVALID=-9996]="PARAMS_INVALID",e[e.SUCCESS=0]="SUCCESS"}(t||(t={})),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"}(s||(s={})),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"}(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.success=0]="success",e[e.sending=1]="sending",e[e.failed=2]="failed"}(r||(r={})),function(e){e[e.Owner=1]="Owner",e[e.Admin=2]="Admin",e[e.Common=3]="Common",e[e.Bot=4]="Bot"}(a||(a={})),function(e){e[e.normal=0]="normal",e[e.recall=1]="recall"}(c||(c={})),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"}(l||(l={}));var g=Object.freeze({__proto__:null,get ApiResponseCode(){return t},get Boolean(){return e},get ChatType(){return i},get GroupRole(){return a},get GroupType(){return h},get LogLevel(){return l},get MessageKind(){return n},get MessageOperation(){return c},get MessageSendStatus(){return r},get MessageType(){return o},get PushMessageType(){return s}});const u={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 p=Object.freeze({__proto__:null,CHAT_SDK_EVENT:u}),m=Object.freeze({__proto__:null});function S(e,t){return{ok:!1,code:e,msg:t}}function T(e){return{ok:!0,data:e}}const A=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},f=e=>{const t=A(e);if(null!==t){let e;return null!=t.content&&(e=A(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class C{all;constructor(e){this.all=e||new Map}on(e,t){const s=this.all.get(e);return s?s.push(t):this.all.set(e,[t]),()=>{this.off(e,t)}}off(e,t){const s=this.all.get(e);s&&(t?s.splice(s.indexOf(t)>>>0,1):this.all.set(e,[]))}emit(e,t){let s=this.all.get(e);s&&s.slice().map(e=>{e(t)}),s=this.all.get("*"),s&&s.slice().map(s=>{s(e,t)})}once(e,t){if("*"===e){const s=(e,i)=>{t(e,i),this.off("*",s)};this.on(e,s)}else{const s=i=>{t(i),this.off(e,s)};this.on(e,s)}}}class R extends C{url;logger;ws;destroyed;pingTimeout;pongTimeout;reConnectTimeout;constructor(e){super(),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===s.PONG_MESSAGE?null!==this.pongTimeout&&(clearTimeout(this.pongTimeout),this.pongTimeout=null,this.delaySendPing()):this.sendAck(t.id),t.type===s.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 D extends C{host;context;logger;ws;constructor(e){super(),this.host=e.host,this.context=e.context,this.logger=e.logger,this.ws=null}connect(){if(!this.context.isLogin)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 R({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 y{_isSyncCompleted;map;chatMap;list;waitMap;constructor(){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 s=this.map.get(t);s&&e.push(s)}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 s=this.waitMap.get(e);return s||(s=(()=>{let e=()=>{};return{promise:new Promise(t=>{e=t}),resolve:e}})(),this.waitMap.set(e,s)),await s.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 w(e){return(new TextEncoder).encode(e).buffer}async function L(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const s=w(t),i=w(e),n=await crypto.subtle.importKey("raw",s,{name:"HMAC",hash:{name:"SHA-256"}},!1,["sign"]),o=await crypto.subtle.sign("HMAC",n,i);return Array.from(new Uint8Array(o)).map(e=>e.toString(16).padStart(2,"0")).join("")}(e,t):function(e,t){return E.HmacSHA256(e,t).toString(E.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 s of e)t+=P(s);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let s="";for(const i of t)s+=P(e[i]);return s}};function O(){return S(t.MAKE_SIGN_FAIL,"make sign fail")}class I{api;context;logger;constructor(e){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:s=!0,...i}=e;if(i.headers||(i.headers={}),i.headers.platform="web",s&&"POST"===e.method?.toUpperCase()&&i.data){if(!this.context.isLogin)return this.logger.warn("HttpClient needs make sign but not login"),O();try{const e=await(async(e,t)=>{const s=await P(e);return await L(s,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),O()}}const n=await this.api(i),o=n.data;return o.code===t.SUCCESS?{ok:!0,data:o.data}:(this.logger.info("HttpClient server error",n),{ok:!1,code:o.code,msg:o.msg,msg_i18n:o.msg_i18n})}catch{return{ok:!1,code:t.NETWORK_ERROR,msg:"network error"}}}get(e,t,s){return this.request({url:e,method:"GET",params:t,...s})}post(e,t,s){return this.request({url:e,method:"POST",data:t,...s})}}class U{level;logHandler;constructor(){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,...s)=>{const i=`[tlog] ${(new Date).toISOString().split("T")[0]}`,n=t?`${i} ${t}`:i;switch(e){case l.error:console.error(n,...s);break;case l.warning:console.warn(n,...s);break;case l.info:console.info(n,...s);break;default:console.log(n,...s)}}}log(e,t,...s){this.getPriority(e)>=this.getPriority(this.level)&&this.logHandler(e,t,...s)}setLogLevel(e){this.level=e,this.logHandler=this.createLogHandler()}info(e,...t){this.log(l.info,e,...t)}warn(e,...t){this.log(l.warning,e,...t)}error(e,...t){this.log(l.error,e,...t)}}class M{context;logger;emitter;feedCache;handleKickoff;constructor(e){this.context=e.context,this.logger=e.logger,this.emitter=e.emitter,this.feedCache=e.feedCache,this.handleKickoff=e.onKickoff}emitFeedListUpdated(){this.emitter.emit(u.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(!this.context.isLogin)return;const t=this.context.loginUser.userId,s=e.content,i=this.feedCache.getByChatId(s.chat_id);if(null!==i){let e=!1;const o={};if(s.message_kind_id!==n.system&&s.sender_id!==t){e=!0;const t=new Set(i.unread_message_ids);t.add(s.id),o.unread_message_ids=[...t],o.badge=t.size}i.last_message_position<s.position&&(e=!0,o.last_message_position=s.position,o.last_message_send_at=s.send_at,o.last_message=s.content,o.last_message_kind_id=s.message_kind_id,o.last_message_type_id=s.message_type_id),e&&(this.feedCache.unshift({...i,...o}),this.emitFeedListUpdated()),this.emitter.emit(u.MESSAGE_RECEIVED,s)}}processUpdateMessage(e){this.emitter.emit(u.MESSAGE_UPDATED,e.content)}processPushLiveMessage(e){this.emitter.emit(u.ROOM_MESSAGE_RECEIVED,e.content)}processReadMessage(e){if(!this.context.isLogin)return;const t=this.context.loginUser.userId,s=this.feedCache.getByChatId(e.content.chat_id);if(null!==s){let i=!1;const n={};if(e.content.reader_ids.includes(t)&&e.content.message_ids.length>0){i=!0;const t=new Set(s.unread_message_ids);e.content.message_ids.forEach(e=>{t.delete(e)}),n.unread_message_ids=[...t],n.badge=t.size}i&&(this.feedCache.update({...s,...n}),this.emitFeedListUpdated()),this.emitter.emit(u.MESSAGE_RECEIPT_RECEIVED,{feed_id:s.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 s.CREATE_FEED:this.processCreateFeed(e);break;case s.DELETE_FEED:this.processDeleteFeed(e);break;case s.ADD_MESSAGE:this.processAddMessage(e);break;case s.UPDATE_MESSAGE:this.processUpdateMessage(e);break;case s.PUSH_LIVE_MESSAGE:this.processPushLiveMessage(e);break;case s.READ_MESSAGE:this.processReadMessage(e);break;case s.KICK_OUT_DEVICE:this.processKickOutDevice()}}}var v=e=>new Promise(t=>setTimeout(t,e));class k{destroyed;promise;constructor(){this.destroyed=!1;let e=()=>{};const t=new Promise(t=>{e=t});this.promise=t,navigator.locks.request("typex-sdk",{ifAvailable:!0},async t=>{if(t)for(e(!0);!this.destroyed;)await v(1e4);else e(!1)})}async request(){return await this.promise}}class G{static key="__typex_sdk_data__";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)}}class x{version;constructor(){this.version=0}increment(){this.version++}get(){return this.version}check(e){return e===this.version}}class N extends C{context;version;singletonLock;logger;httpClient;feedCache;ws;pushMessageProcessor;constructor(e){super(),this.context={isLogin:!1,isReady:!1,deviceId:null},this.version=new x,this.singletonLock=new k,this.logger=new U,this.httpClient=new I({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new y,this.ws=new D({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new M({context:this.context,logger:this.logger,emitter:this,feedCache:this.feedCache,onKickoff:()=>{this.handleKickoff()}}),this.init()}init(){this.loadContext(),this.ws.on("message",e=>{this.pushMessageProcessor.process(e)}),this.ws.on("kickoff",()=>{this.handleKickoff()})}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;G.set({deviceId:e.deviceId})}loadContext(){const e=G.get();e&&e.deviceId&&(this.context.deviceId=e.deviceId)}applyLoginStatus(){this.version.increment(),this.saveContext(),this.context.isLogin?(this.loadFeedList(),this.ws.connect(),this.context.isReady=!0,this.emit(u.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.context.isReady=!1,this.emit(u.SDK_NOT_READY))}async loadFeedList(){const e=this.version.get(),t={refresh_at:null,feed_id:null};for(;;){const s=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(!s.ok)break;if(t.refresh_at=s.data.refresh_at,t.feed_id=s.data.last_feed_id,s.data.feed_list.forEach(e=>{this.feedCache.push(e)}),!s.data.has_more)break}this.version.check(e)&&(this.feedCache.markSyncComplete(),this.emit(u.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(!await this.singletonLock.request())return this.logger.error("Another active TypeX SDK instance detected"),S(t.REQUEST_SINGLETON_LOCK_FAIL,"Another active TypeX SDK instance detected");if(await this.requestDeviceId(),!this.context.deviceId)return this.logger.error("Get deviceId failed"),S(t.SDK_ERROR,"Login params invalid");const s=await this.httpClient.post("/user/session/login",{userCode:e.user_code,device_id:this.context.deviceId},{needSign:!1});return s.ok?(this.context.isLogin=!0,this.context.isLogin&&(this.context.loginUser={userId:s.data.id,secretKey:s.data.key,sessionId:d.get("sessionid")??""}),this.applyLoginStatus(),T(null)):s}async logout(){const e=await this.httpClient.get("/user/logout");return e.ok?(this.context.isLogin=!1,this.applyLoginStatus(),T(null)):e}async handleKickoff(){this.context.isLogin=!1,this.applyLoginStatus()}getLoginUser(){return this.context.isLogin?this.context.loginUser.userId:null}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 T({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return T(await this.feedCache.waitFor(e))}async getFeedMessageList(e){const t=await this.getFeedDetail(e.feed_id);if(t.ok&&t.data){const s=t.data,{chat_id:i,first_position:n,last_message_position:o}=s,r=(e=>{const t=[];let s=e.lastPosition??e.maxPosition;for(;t.length<e.limit&&s>=e.minPosition;)t.push(s),s--;return t})({maxPosition:o,minPosition:n,lastPosition:e.last_message_position,limit:e.limit});if(r.length>0){const e=await this.httpClient.post("/message/get_by_position",{chat_position:{[i]:r}},{needSign:!1});if(e.ok&&e.data[i]){const t=e.data[i].reverse();return T({has_more:r[0]===n,list:t,last_message_position:t[0]?.position})}}}return T({has_more:!1,list:[]})}createCustomMessage(e){if(!this.context.isLogin)return S(t.SDK_ERROR,"not login");const s=this.feedCache.get(e.feed_id);if(null===s)return S(t.SDK_ERROR,"not found feed");var i;return T({id:"",chat_id:s.chat_id,position:s.last_message_position,sender_id:this.context.loginUser.userId,message_kind_id:n.text,message_type_id:o.custom,send_at:"",reader_ids:[],hide_ids:[],operation:c.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=f(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 S(t.SDK_ERROR,"not support")}async sendMessageReadReceipt(e){const s=this.feedCache.get(e.feed_id);return null===s?S(t.SDK_ERROR,"not found feed"):await this.httpClient.post("/message/read",{chat_id:s.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?T(t.data):t}async sendMessageToRoom(e){return await this.httpClient.post("/liveshow/send_message",{room_id:e.room_id,content:e.content})}}const F={parseSystemMessageContent:e=>{const t=A(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=A(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:f};exports.ChatSDK=N,exports.create=function(e){return new N(e)},exports.enums=g,exports.events=p,exports.interfaces=m,exports.utils=F;
|
|
1
|
+
"use strict";var e,t,i,s,n,o,r,a,l,c,d,h=require("axios"),u=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.PUSH_SYSTEM_NOTICE=58]="PUSH_SYSTEM_NOTICE",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 _=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 g={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",SYSTEM_NOTICE_RECEIVED:"systemNoticeReceived"};var E=Object.freeze({__proto__:null,CHAT_SDK_EVENT:g}),p=Object.freeze({__proto__:null});function m(e,t){return{ok:!1,code:e,msg:t}}function f(e){return{ok:!0,data:e}}const b=e=>{try{return null==e||"string"!=typeof e||0===e.length?null:JSON.parse(e)}catch{return null}},S=e=>{const t=b(e);if(null!==t){let e;return null!=t.content&&(e=b(t.content)??void 0),{client_msg_id:t.client_msg_id,content:e}}return{}};class C{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 T extends C{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 A extends C{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 T({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===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 y(e){return(new TextEncoder).encode(e).buffer}async function R(e,t){return window.crypto&&window.crypto.subtle?await async function(e,t){const i=y(t),s=y(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 u.HmacSHA256(e,t).toString(u.enc.Hex)}(e,t)}const w=e=>{if(null==e)return"";if("object"!=typeof e||Array.isArray(e)){if(Array.isArray(e)){let t="";for(const i of e)t+=w(i);return t}return"string"==typeof e?e:String(e)}{const t=Object.keys(e).sort();let i="";for(const s of t)i+=w(e[s]);return i}};function P(){return m(c.MAKE_SIGN_FAIL,"make sign fail")}class D{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=h.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"),P();try{const e=await(async(e,t)=>{const i=await w(e);return await R(i,t)})(i.data,this.context.loginUser.secretKey);i.headers.sign=e}catch(e){return this.logger.error("HttpClient make sign error",e),P()}}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 O(e){return`${e}`.padStart(2,"0")}class L{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()}-${O(i.getMonth()+1)}-${O(i.getDate())} ${O(i.getHours())}:${O(i.getMinutes())}:${O(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 M{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(g.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(g.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(g.MESSAGE_RECALLED,{message_ids:[t.id]})}}processPushLiveMessage(e){this.emitter.emit(g.ROOM_MESSAGE_RECEIVED,{room_id:e.content.room_id,content:e.content.message})}processPushSystemNotice(e){this.emitter.emit(g.SYSTEM_NOTICE_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(g.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.PUSH_SYSTEM_NOTICE:this.processPushSystemNotice(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 U{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(U,"key",{enumerable:!0,configurable:!0,writable:!0,value:"__typex_sdk_data__"});class k{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 C{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 k,this.singletonLock=new I,this.logger=new L,this.httpClient=new D({host:e.httpHost,context:this.context,logger:this.logger,developer:e.developer}),this.feedCache=new v,this.ws=new A({host:e.websocketHost,context:this.context,logger:this.logger}),this.pushMessageProcessor=new M({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;U.set({deviceId:e.deviceId})}loadContext(){const e=U.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(g.SDK_READY)):(this.ws.disconnect(),this.feedCache.reset(),this.singletonLock.releaseLock(),this.context.isReady=!1,this.emit(g.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(g.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 f(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});return t.ok?(this.context.isLogin=!0,this.context.loginUser={userId:t.data.id,secretKey:t.data.key,sessionId:e.user_code},this.applyLoginStatus(),f(null)):(this.singletonLock.releaseLock(),t)}async logout(){if(!this.context.isLogin)return f(null);const e=await this.httpClient.get("/user/logout");return e.ok?(this.afterLogout(),f(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 f({list:this.feedCache.getAll(),is_sync_completed:this.feedCache.isSyncCompleted()})}async getFeedDetail(e){return f(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 f({has_more:l,list:e.data[s].reverse(),next_message_position:a})}}}return f({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 f({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?f(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 G={parseSystemMessageContent:e=>{const t=b(e);return null!==t?{text:t.text,text_i18n:t.text_i18n}:{}},parseTextMessageContent:e=>{const t=b(e);return null!==t?{text:t.text,client_msg_id:t.client_msg_id}:{}},parseCustomMessageContent:S};exports.ChatSDK=x,exports.create=function(e,t){let i=N.get(e);return void 0===i&&(i=new x(t),N.set(e,i)),i},exports.enums=_,exports.events=E,exports.interfaces=p,exports.utils=G;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@typexim/web-sdk",
|
|
3
|
-
"version": "0.0.4-alpha.
|
|
3
|
+
"version": "0.0.4-alpha.10",
|
|
4
4
|
"private": false,
|
|
5
5
|
"repository": "git@github.com:secure-typex/typex-web-sdk.git",
|
|
6
6
|
"license": "MIT",
|
|
@@ -26,14 +26,12 @@
|
|
|
26
26
|
},
|
|
27
27
|
"dependencies": {
|
|
28
28
|
"axios": "1.11.0",
|
|
29
|
-
"crypto-js": "4.2.0"
|
|
30
|
-
"js-cookie": "3.0.5"
|
|
29
|
+
"crypto-js": "4.2.0"
|
|
31
30
|
},
|
|
32
31
|
"devDependencies": {
|
|
33
32
|
"@rollup/plugin-terser": "0.4.4",
|
|
34
33
|
"@rollup/plugin-typescript": "12.1.4",
|
|
35
34
|
"@types/crypto-js": "4.2.2",
|
|
36
|
-
"@types/js-cookie": "3.0.6",
|
|
37
35
|
"cross-env": "10.0.0",
|
|
38
36
|
"rollup": "4.50.1",
|
|
39
37
|
"rollup-plugin-delete": "3.0.1"
|
package/rollup.config.js
CHANGED
|
@@ -23,6 +23,7 @@ function createConfig() {
|
|
|
23
23
|
plugins: [
|
|
24
24
|
del({
|
|
25
25
|
targets: 'dist',
|
|
26
|
+
runOnce: true,
|
|
26
27
|
}),
|
|
27
28
|
typescript({
|
|
28
29
|
tsconfig: './tsconfig.json',
|
|
@@ -32,7 +33,7 @@ function createConfig() {
|
|
|
32
33
|
}),
|
|
33
34
|
IS_BUILD && terser(),
|
|
34
35
|
].filter(Boolean),
|
|
35
|
-
external: ['
|
|
36
|
+
external: ['axios', 'crypto-js'],
|
|
36
37
|
};
|
|
37
38
|
}
|
|
38
39
|
|