@easemob-community/callkit-core 2.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +162 -0
- package/dist/index.cjs +2819 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.ts +1571 -0
- package/dist/index.iife.js +2822 -0
- package/dist/index.iife.js.map +1 -0
- package/dist/index.js +2819 -0
- package/dist/index.js.map +1 -0
- package/dist/index.umd.js +2823 -0
- package/dist/index.umd.js.map +1 -0
- package/package.json +54 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1571 @@
|
|
|
1
|
+
import { GroupParticipant as GroupParticipant_2 } from '..';
|
|
2
|
+
import { GroupSessionState as GroupSessionState_2 } from '..';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* 响铃消息扩展字段接口
|
|
6
|
+
*/
|
|
7
|
+
export declare interface AlertSignalingExt extends BaseSignalingExt {
|
|
8
|
+
action: "alert";
|
|
9
|
+
/** 被叫设备ID */
|
|
10
|
+
calleeDevId: string;
|
|
11
|
+
/** 主叫设备ID */
|
|
12
|
+
callerDevId: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export declare interface AnswerCallParams {
|
|
16
|
+
callId: string;
|
|
17
|
+
/** @deprecated 使用 result 替代 */
|
|
18
|
+
accept?: boolean;
|
|
19
|
+
result?: 'accept' | 'refuse' | 'busy';
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* 应答消息扩展字段接口
|
|
24
|
+
*/
|
|
25
|
+
export declare interface AnswerCallSignalingExt extends BaseSignalingExt {
|
|
26
|
+
action: "answerCall";
|
|
27
|
+
/** 应答结果 */
|
|
28
|
+
result: "accept" | "refuse" | "busy";
|
|
29
|
+
/** 主叫设备ID */
|
|
30
|
+
callerDevId: string;
|
|
31
|
+
/** 被叫设备ID */
|
|
32
|
+
calleeDevId: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
declare interface BaseEvent {
|
|
36
|
+
callId: string;
|
|
37
|
+
channel: string;
|
|
38
|
+
callType: CALL_TYPE;
|
|
39
|
+
callerUserId: string;
|
|
40
|
+
calleeUserId?: string;
|
|
41
|
+
groupId?: string;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* 基础信令消息扩展字段接口
|
|
46
|
+
*/
|
|
47
|
+
declare interface BaseSignalingExt {
|
|
48
|
+
/** 操作类型 */
|
|
49
|
+
action: string;
|
|
50
|
+
/** 通话ID */
|
|
51
|
+
callId: string;
|
|
52
|
+
/** 时间戳 */
|
|
53
|
+
ts: number;
|
|
54
|
+
/** 消息类型 */
|
|
55
|
+
msgType: string;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
export declare interface BuildCmdMessageParams {
|
|
59
|
+
action: CALLKIT_CMD_MSG_ACTION_TYPE;
|
|
60
|
+
callId: string;
|
|
61
|
+
callerDevId?: string;
|
|
62
|
+
calleeDevId?: string;
|
|
63
|
+
result?: CALLKIT_CMD_MSG_RESULT_TYPE;
|
|
64
|
+
status?: boolean;
|
|
65
|
+
ts?: number;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
/**
|
|
69
|
+
* MessageBuilder
|
|
70
|
+
* 由 ChatService 改造而来的纯函数集合。
|
|
71
|
+
*
|
|
72
|
+
* 关键变化:
|
|
73
|
+
* - 不再读取 callStateStore,所有数据由调用方显式传入
|
|
74
|
+
* - 不再查询用户/群组资料,由调用方传入
|
|
75
|
+
*/
|
|
76
|
+
export declare interface BuildInviteMessageParams {
|
|
77
|
+
callId: string;
|
|
78
|
+
callerUserId: string;
|
|
79
|
+
calleeUserId: string;
|
|
80
|
+
callerDevId: string;
|
|
81
|
+
channel: string;
|
|
82
|
+
callType: CALL_TYPE;
|
|
83
|
+
ts?: number;
|
|
84
|
+
invitedMembers?: string[];
|
|
85
|
+
callerInfo?: {
|
|
86
|
+
nickname?: string;
|
|
87
|
+
avatarURL?: string;
|
|
88
|
+
};
|
|
89
|
+
groupInfo?: {
|
|
90
|
+
groupId: string;
|
|
91
|
+
groupName?: string;
|
|
92
|
+
groupAvatar?: string;
|
|
93
|
+
};
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export declare type CALL_STATUS = 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7;
|
|
97
|
+
|
|
98
|
+
export declare const CALL_STATUS: {
|
|
99
|
+
readonly IDLE: 0;
|
|
100
|
+
readonly INVITING: 1;
|
|
101
|
+
readonly ALERTING: 2;
|
|
102
|
+
readonly CONFIRM_RING: 3;
|
|
103
|
+
readonly RECEIVED_CONFIRM_RING: 4;
|
|
104
|
+
readonly ANSWER_CALL: 5;
|
|
105
|
+
readonly CONFIRM_CALLEE: 6;
|
|
106
|
+
readonly IN_CALL: 7;
|
|
107
|
+
};
|
|
108
|
+
|
|
109
|
+
export declare type CALL_TYPE = 0 | 1 | 2 | 3;
|
|
110
|
+
|
|
111
|
+
export declare const CALL_TYPE: {
|
|
112
|
+
readonly AUDIO_1V1: 0;
|
|
113
|
+
readonly VIDEO_1V1: 1;
|
|
114
|
+
readonly VIDEO_MULTI: 2;
|
|
115
|
+
readonly AUDIO_MULTI: 3;
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
export declare interface CallAcceptedEvent {
|
|
119
|
+
type: 'callAccepted';
|
|
120
|
+
payload: BaseEvent & {
|
|
121
|
+
isCaller: boolean;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
export declare interface CallBusyEvent {
|
|
126
|
+
type: 'callBusy';
|
|
127
|
+
payload: BaseEvent;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
export declare interface CallCanceledEvent {
|
|
131
|
+
type: 'callCanceled';
|
|
132
|
+
payload: BaseEvent & {
|
|
133
|
+
isRemote: boolean;
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
export declare interface CallConnectedEvent {
|
|
138
|
+
type: 'callConnected';
|
|
139
|
+
payload: BaseEvent;
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export declare interface CallDurationUpdatedEvent {
|
|
143
|
+
type: 'callDurationUpdated';
|
|
144
|
+
payload: BaseEvent & {
|
|
145
|
+
duration: number;
|
|
146
|
+
};
|
|
147
|
+
}
|
|
148
|
+
|
|
149
|
+
export declare interface CallEndedEvent {
|
|
150
|
+
type: 'callEnded';
|
|
151
|
+
payload: BaseEvent & {
|
|
152
|
+
reason: 'hangup' | 'cancel' | 'refuse' | 'busy' | 'timeout' | 'remoteHangup' | 'remoteCancel';
|
|
153
|
+
duration?: number;
|
|
154
|
+
};
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
export declare interface CallErrorEvent {
|
|
158
|
+
type: 'callError';
|
|
159
|
+
payload: {
|
|
160
|
+
/** 错误类型 */
|
|
161
|
+
type: string;
|
|
162
|
+
/** 错误信息 */
|
|
163
|
+
error: string;
|
|
164
|
+
/** 关联通话 ID */
|
|
165
|
+
callId?: string;
|
|
166
|
+
/** 额外上下文 */
|
|
167
|
+
context?: Record<string, any>;
|
|
168
|
+
};
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
export declare interface CallInvitedEvent {
|
|
172
|
+
type: 'callInvited';
|
|
173
|
+
payload: BaseEvent & {
|
|
174
|
+
isCaller: boolean;
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
declare type CALLKIT_ACTION_MSG_TYPE = "rtcCallWithAgora";
|
|
179
|
+
|
|
180
|
+
export declare type CALLKIT_CMD_MSG_ACTION_TYPE = "confirmRing" | "alert" | "answerCall" | "leaveCall" | "confirmCallee" | "cancelCall";
|
|
181
|
+
|
|
182
|
+
export declare type CALLKIT_CMD_MSG_RESULT_TYPE = "accept" | "refuse" | "busy";
|
|
183
|
+
|
|
184
|
+
export declare const CALLKIT_CMD_MSG_RESULT_TYPE: {
|
|
185
|
+
readonly ACCEPT: "accept";
|
|
186
|
+
readonly REFUSE: "refuse";
|
|
187
|
+
readonly BUSY: "busy";
|
|
188
|
+
};
|
|
189
|
+
|
|
190
|
+
/**
|
|
191
|
+
* CallKitCore
|
|
192
|
+
* 框架无关的通话信令核心。
|
|
193
|
+
*
|
|
194
|
+
* 职责:
|
|
195
|
+
* 1. 管理单聊/群聊通话生命周期
|
|
196
|
+
* 2. 通过事件回调通知上层所有决策点
|
|
197
|
+
* 3. 不直接操作任何 RTC SDK,RTC 由上层通过适配器或事件自行处理
|
|
198
|
+
*/
|
|
199
|
+
export declare class CallKitCore {
|
|
200
|
+
private config;
|
|
201
|
+
private logger;
|
|
202
|
+
private singleCallState;
|
|
203
|
+
private groupCallSession;
|
|
204
|
+
private signalRouter;
|
|
205
|
+
private signalSender;
|
|
206
|
+
private singleCallHandler;
|
|
207
|
+
private groupCallHandler;
|
|
208
|
+
private imListener;
|
|
209
|
+
private destroyed;
|
|
210
|
+
private inviteTimer;
|
|
211
|
+
private pendingIncomingInvites;
|
|
212
|
+
private rtcAppId;
|
|
213
|
+
private rtcUid;
|
|
214
|
+
private inviteTimeoutMs;
|
|
215
|
+
private durationTimer;
|
|
216
|
+
private durationStartTime;
|
|
217
|
+
private durationCallInfo;
|
|
218
|
+
private get userId();
|
|
219
|
+
private get deviceId();
|
|
220
|
+
private eventBus;
|
|
221
|
+
constructor(config: CallKitCoreConfig);
|
|
222
|
+
/**
|
|
223
|
+
* 发起单聊通话
|
|
224
|
+
*/
|
|
225
|
+
inviteCall(params: InviteCallParams): Promise<void>;
|
|
226
|
+
/**
|
|
227
|
+
* 响应来电(接受/拒绝)
|
|
228
|
+
*/
|
|
229
|
+
answerCall(params: AnswerCallParams): Promise<void>;
|
|
230
|
+
/**
|
|
231
|
+
* 挂断/取消通话
|
|
232
|
+
*/
|
|
233
|
+
hangup(params?: HangupParams): Promise<void>;
|
|
234
|
+
/**
|
|
235
|
+
* 通话中邀请更多成员加入群聊通话
|
|
236
|
+
*/
|
|
237
|
+
inviteMoreParticipants(participantIds: string[]): Promise<void>;
|
|
238
|
+
/**
|
|
239
|
+
* 发起群聊通话
|
|
240
|
+
*/
|
|
241
|
+
inviteGroupCall(params: InviteGroupCallParams): Promise<void>;
|
|
242
|
+
/**
|
|
243
|
+
* 切换本地音频(静音/取消静音)
|
|
244
|
+
*/
|
|
245
|
+
toggleAudio(): void;
|
|
246
|
+
/**
|
|
247
|
+
* 切换本地视频(开启/关闭摄像头)
|
|
248
|
+
*/
|
|
249
|
+
toggleVideo(): void;
|
|
250
|
+
/**
|
|
251
|
+
* 获取 RTC token(并缓存 appId / RTCUId)
|
|
252
|
+
* - 环信真实 SDK:`{ data: { RTCToken, appId, RTCUId, expireIn } }`
|
|
253
|
+
* - 早期 / 精简 mock:`{ accessToken, appId }`
|
|
254
|
+
* 为了与旧版 lib/composables/useJoinChannel.ts 行为对齐,同步保存 rtcAppId、rtcUid供
|
|
255
|
+
* shouldJoinRtc 事件透传给上层 RtcAdapter(Agora 的 join 必须使用服务端返回的数值型 uid)。
|
|
256
|
+
*/
|
|
257
|
+
private fetchRtcToken;
|
|
258
|
+
/**
|
|
259
|
+
* 上层调用 RTC SDK 后,通过此方法反馈 RTC 事件给核心库
|
|
260
|
+
*/
|
|
261
|
+
reportRtcEvent(report: RtcReport): void;
|
|
262
|
+
getSingleCallState(): Readonly<SingleCallState>;
|
|
263
|
+
getGroupCallSession(): Readonly<GroupSessionState_2> | null;
|
|
264
|
+
/**
|
|
265
|
+
* 获取群聊通话的所有参与者(包含状态信息)
|
|
266
|
+
*/
|
|
267
|
+
getGroupCallParticipants(): Readonly<GroupParticipant_2>[];
|
|
268
|
+
/**
|
|
269
|
+
* 当前是否在通话中(IN_CALL 状态)
|
|
270
|
+
*/
|
|
271
|
+
isInCall(): boolean;
|
|
272
|
+
/**
|
|
273
|
+
* 当前是否处于可被接听的状态(被叫端弹窗显示区间)
|
|
274
|
+
*/
|
|
275
|
+
isWaitingCalleeAction(): boolean;
|
|
276
|
+
/**
|
|
277
|
+
* 当前是否处于活跃通话中(已进入 RTC 或即将进入)
|
|
278
|
+
*/
|
|
279
|
+
isInActiveCall(): boolean;
|
|
280
|
+
/**
|
|
281
|
+
* 当前是否可以接听(被叫端按钮可点击)
|
|
282
|
+
*/
|
|
283
|
+
canAccept(): boolean;
|
|
284
|
+
/**
|
|
285
|
+
* 当前是否可以拒绝(被叫端按钮可点击)
|
|
286
|
+
*/
|
|
287
|
+
canReject(): boolean;
|
|
288
|
+
/**
|
|
289
|
+
* 当前是否可以挂断(主叫/被叫端的挂断按钮可点击)
|
|
290
|
+
*/
|
|
291
|
+
canHangup(): boolean;
|
|
292
|
+
/**
|
|
293
|
+
* 当前是否在呼叫/响铃中(INVITING 或 ALERTING 状态)
|
|
294
|
+
*/
|
|
295
|
+
isCalling(): boolean;
|
|
296
|
+
/**
|
|
297
|
+
* 获取当前通话类型,无通话时返回 null
|
|
298
|
+
*/
|
|
299
|
+
getCurrentCallType(): CALL_TYPE | null;
|
|
300
|
+
/**
|
|
301
|
+
* 获取当前通话 ID,无通话时返回空字符串
|
|
302
|
+
*/
|
|
303
|
+
getCurrentCallId(): string;
|
|
304
|
+
/**
|
|
305
|
+
* 当前是否空闲
|
|
306
|
+
*/
|
|
307
|
+
isIdle(): boolean;
|
|
308
|
+
/**
|
|
309
|
+
* 订阅通话事件
|
|
310
|
+
* @returns 取消订阅函数
|
|
311
|
+
*/
|
|
312
|
+
onEvent(handler: (event: CallKitEvent) => void): () => void;
|
|
313
|
+
/**
|
|
314
|
+
* 订阅单次通话事件
|
|
315
|
+
*/
|
|
316
|
+
onceEvent(handler: (event: CallKitEvent) => void): () => void;
|
|
317
|
+
destroy(): Promise<void>;
|
|
318
|
+
private isSelfMessage;
|
|
319
|
+
private handleTextMessage;
|
|
320
|
+
private handleGroupCallInvite;
|
|
321
|
+
private handleSingleCallInvite;
|
|
322
|
+
/**
|
|
323
|
+
* 发送 alert CMD 信令给主叫方
|
|
324
|
+
*/
|
|
325
|
+
private sendAlertSignal;
|
|
326
|
+
private handleCmdMessage;
|
|
327
|
+
private processEvents;
|
|
328
|
+
/**
|
|
329
|
+
* 当配置了 rtcAdapter 时,自动处理 RTC 相关事件
|
|
330
|
+
*/
|
|
331
|
+
private handleRtcEvent;
|
|
332
|
+
private mapDomainEvents;
|
|
333
|
+
private emitEvent;
|
|
334
|
+
private emitError;
|
|
335
|
+
private startDurationTimer;
|
|
336
|
+
private stopDurationTimer;
|
|
337
|
+
private handleIMConnected;
|
|
338
|
+
private handleIMDisconnected;
|
|
339
|
+
/**
|
|
340
|
+
* 启动邀请超时定时器。
|
|
341
|
+
* 超时后调用状态机的 timeout() 并通过 processEvents 消费事件,
|
|
342
|
+
* 确保上层 UI 能收到 callTimeout + callEnded 事件。
|
|
343
|
+
*/
|
|
344
|
+
private startInviteTimeout;
|
|
345
|
+
private clearInviteTimeout;
|
|
346
|
+
}
|
|
347
|
+
|
|
348
|
+
export declare interface CallKitCoreConfig {
|
|
349
|
+
/** 环信 IM 客户端实例 */
|
|
350
|
+
imClient: EasemobConnection;
|
|
351
|
+
/** 当前用户资料 */
|
|
352
|
+
userProfile?: {
|
|
353
|
+
userId: string;
|
|
354
|
+
nickname?: string;
|
|
355
|
+
avatarURL?: string;
|
|
356
|
+
};
|
|
357
|
+
/** RTC 适配器(可选)。配置后 Core 会自动处理 RTC 指令事件 */
|
|
358
|
+
rtcAdapter?: RtcAdapter;
|
|
359
|
+
/** 全局事件回调(兼容旧接口,与 onUIEvent/onRtcEvent 可共存) */
|
|
360
|
+
onEvent?: (event: CallKitEvent) => void;
|
|
361
|
+
/** UI 层事件回调:显示弹窗、更新界面、处理通话生命周期 */
|
|
362
|
+
onUIEvent?: (event: UIEvent_2) => void;
|
|
363
|
+
/** RTC 指令事件回调:加入/离开频道、发布轨道、切换音视频。若已配置 rtcAdapter 可省略 */
|
|
364
|
+
onRtcEvent?: (event: RtcEvent) => void;
|
|
365
|
+
/** 邀请超时时间(毫秒),默认 30000 */
|
|
366
|
+
inviteTimeout?: number;
|
|
367
|
+
/** 自定义日志器(可选) */
|
|
368
|
+
logger?: Logger;
|
|
369
|
+
/** 消息创建工厂(可选)。用于兼容不同版本的 easemob-websdk 消息创建方式 */
|
|
370
|
+
createMessage?: (options: any) => any;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
export declare type CallKitEvent = UIEvent_2 | RtcEvent;
|
|
374
|
+
|
|
375
|
+
export declare interface CallRefusedEvent {
|
|
376
|
+
type: 'callRefused';
|
|
377
|
+
payload: BaseEvent & {
|
|
378
|
+
isRemote: boolean;
|
|
379
|
+
};
|
|
380
|
+
}
|
|
381
|
+
|
|
382
|
+
export declare interface CallStartedEvent {
|
|
383
|
+
type: 'callStarted';
|
|
384
|
+
payload: BaseEvent & {
|
|
385
|
+
isCaller: boolean;
|
|
386
|
+
startTime: number;
|
|
387
|
+
};
|
|
388
|
+
}
|
|
389
|
+
|
|
390
|
+
export declare interface CallTimeoutEvent {
|
|
391
|
+
type: 'callTimeout';
|
|
392
|
+
payload: BaseEvent;
|
|
393
|
+
}
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* 取消通话消息扩展字段接口
|
|
397
|
+
*/
|
|
398
|
+
export declare interface CancelCallSignalingExt extends BaseSignalingExt {
|
|
399
|
+
action: "cancelCall";
|
|
400
|
+
/** 主叫设备ID */
|
|
401
|
+
callerDevId: string;
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* 信令消息体(从 useListenerManager 提取,去框架依赖)
|
|
406
|
+
*/
|
|
407
|
+
export declare interface CmdMsgBody {
|
|
408
|
+
from?: string;
|
|
409
|
+
to?: string;
|
|
410
|
+
id?: string;
|
|
411
|
+
action?: string;
|
|
412
|
+
ext?: Partial<SignalingExt> & {
|
|
413
|
+
[key: string]: any;
|
|
414
|
+
};
|
|
415
|
+
[key: string]: any;
|
|
416
|
+
}
|
|
417
|
+
|
|
418
|
+
/**
|
|
419
|
+
* 确认被叫方消息扩展字段接口
|
|
420
|
+
*/
|
|
421
|
+
export declare interface ConfirmCalleeSignalingExt extends BaseSignalingExt {
|
|
422
|
+
action: "confirmCallee";
|
|
423
|
+
/** 确认结果 */
|
|
424
|
+
result: string;
|
|
425
|
+
/** 主叫设备ID */
|
|
426
|
+
callerDevId: string;
|
|
427
|
+
/** 被叫设备ID */
|
|
428
|
+
calleeDevId: string;
|
|
429
|
+
}
|
|
430
|
+
|
|
431
|
+
/**
|
|
432
|
+
* 确认响铃消息扩展字段接口
|
|
433
|
+
*/
|
|
434
|
+
export declare interface ConfirmRingSignalingExt extends BaseSignalingExt {
|
|
435
|
+
action: "confirmRing";
|
|
436
|
+
/** 确认状态 */
|
|
437
|
+
status: boolean;
|
|
438
|
+
/** 主叫设备ID */
|
|
439
|
+
callerDevId: string;
|
|
440
|
+
/** 被叫设备ID */
|
|
441
|
+
calleeDevId: string;
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
export declare type DomainEvent = {
|
|
445
|
+
type: 'STATUS_CHANGED';
|
|
446
|
+
from: CALL_STATUS;
|
|
447
|
+
to: CALL_STATUS;
|
|
448
|
+
callId: string;
|
|
449
|
+
} | {
|
|
450
|
+
type: 'CALL_INVITED';
|
|
451
|
+
callId: string;
|
|
452
|
+
isCaller: boolean;
|
|
453
|
+
channel: string;
|
|
454
|
+
callType: CALL_TYPE;
|
|
455
|
+
} | {
|
|
456
|
+
type: 'CALL_STARTED';
|
|
457
|
+
callId: string;
|
|
458
|
+
isCaller: boolean;
|
|
459
|
+
channel: string;
|
|
460
|
+
callType: CALL_TYPE;
|
|
461
|
+
} | {
|
|
462
|
+
type: 'CALL_ACCEPTED';
|
|
463
|
+
callId: string;
|
|
464
|
+
isCaller: boolean;
|
|
465
|
+
channel: string;
|
|
466
|
+
callType: CALL_TYPE;
|
|
467
|
+
} | {
|
|
468
|
+
type: 'CALL_CONNECTED';
|
|
469
|
+
callId: string;
|
|
470
|
+
channel: string;
|
|
471
|
+
callType: CALL_TYPE;
|
|
472
|
+
} | {
|
|
473
|
+
type: 'CALL_ENDED';
|
|
474
|
+
callId: string;
|
|
475
|
+
reason: string;
|
|
476
|
+
duration: number;
|
|
477
|
+
} | {
|
|
478
|
+
type: 'CALL_TIMEOUT';
|
|
479
|
+
callId: string;
|
|
480
|
+
} | {
|
|
481
|
+
type: 'CALL_REFUSED';
|
|
482
|
+
callId: string;
|
|
483
|
+
isRemote: boolean;
|
|
484
|
+
} | {
|
|
485
|
+
type: 'CALL_BUSY';
|
|
486
|
+
callId: string;
|
|
487
|
+
} | {
|
|
488
|
+
type: 'CALL_CANCELED';
|
|
489
|
+
callId: string;
|
|
490
|
+
isRemote: boolean;
|
|
491
|
+
} | {
|
|
492
|
+
type: 'SHOULD_JOIN_RTC';
|
|
493
|
+
callId: string;
|
|
494
|
+
channel: string;
|
|
495
|
+
token: string;
|
|
496
|
+
role: 'caller' | 'callee';
|
|
497
|
+
callType: CALL_TYPE;
|
|
498
|
+
} | {
|
|
499
|
+
type: 'GROUP_CALL_INIT';
|
|
500
|
+
callId: string;
|
|
501
|
+
groupId: string;
|
|
502
|
+
groupName: string;
|
|
503
|
+
channel: string;
|
|
504
|
+
callType: 'audio' | 'video';
|
|
505
|
+
callerUserId: string;
|
|
506
|
+
invitedMembers: string[];
|
|
507
|
+
} | {
|
|
508
|
+
type: 'PARTICIPANT_STATE_CHANGED';
|
|
509
|
+
callId: string;
|
|
510
|
+
userId: string;
|
|
511
|
+
state: 'invited' | 'accepted' | 'joinedRtc' | 'left';
|
|
512
|
+
groupId?: string;
|
|
513
|
+
} | {
|
|
514
|
+
type: 'PARTICIPANT_JOINED';
|
|
515
|
+
callId: string;
|
|
516
|
+
userId: string;
|
|
517
|
+
channel: string;
|
|
518
|
+
callType: CALL_TYPE;
|
|
519
|
+
groupId?: string;
|
|
520
|
+
} | {
|
|
521
|
+
type: 'PARTICIPANT_LEFT';
|
|
522
|
+
callId: string;
|
|
523
|
+
userId: string;
|
|
524
|
+
channel: string;
|
|
525
|
+
callType: CALL_TYPE;
|
|
526
|
+
reason: string;
|
|
527
|
+
groupId?: string;
|
|
528
|
+
} | {
|
|
529
|
+
type: 'LOCAL_AUDIO_CHANGED';
|
|
530
|
+
callId: string;
|
|
531
|
+
enabled: boolean;
|
|
532
|
+
} | {
|
|
533
|
+
type: 'LOCAL_VIDEO_CHANGED';
|
|
534
|
+
callId: string;
|
|
535
|
+
enabled: boolean;
|
|
536
|
+
};
|
|
537
|
+
|
|
538
|
+
export declare interface EasemobConnection {
|
|
539
|
+
user: string;
|
|
540
|
+
context: {
|
|
541
|
+
userId: string;
|
|
542
|
+
jid: {
|
|
543
|
+
clientResource: string;
|
|
544
|
+
};
|
|
545
|
+
};
|
|
546
|
+
token: string;
|
|
547
|
+
send: (msg: any) => Promise<any>;
|
|
548
|
+
addEventHandler: (id: string, handlers: Record<string, (...args: any[]) => void>) => void;
|
|
549
|
+
removeEventHandler: (id: string) => void;
|
|
550
|
+
/**
|
|
551
|
+
* 获取 Agora RTC Token。
|
|
552
|
+
* 环信真实 SDK 返回结构为 `{ data: { RTCToken, appId, RTCUId, expireIn } }`,
|
|
553
|
+
* 为了兼容早期代码与精简 mock,额外允许顶层 `accessToken`/`appId` 字段。
|
|
554
|
+
*/
|
|
555
|
+
getRTCToken: (channel: string) => Promise<{
|
|
556
|
+
data?: {
|
|
557
|
+
RTCToken?: string;
|
|
558
|
+
appId?: string;
|
|
559
|
+
RTCUId?: number;
|
|
560
|
+
expireIn?: number;
|
|
561
|
+
};
|
|
562
|
+
accessToken?: string;
|
|
563
|
+
appId?: string;
|
|
564
|
+
}>;
|
|
565
|
+
getUserIdByRTCUIds: (uids: (number | string)[]) => Promise<{
|
|
566
|
+
data: Record<string, string>;
|
|
567
|
+
}>;
|
|
568
|
+
}
|
|
569
|
+
|
|
570
|
+
/**
|
|
571
|
+
* 轻量级事件总线
|
|
572
|
+
* 不依赖外部库,内部使用 Map + Set 实现。
|
|
573
|
+
*/
|
|
574
|
+
export declare class EventBus<TEvents extends Record<string, any>> {
|
|
575
|
+
private listeners;
|
|
576
|
+
private logger;
|
|
577
|
+
constructor(logger?: Logger);
|
|
578
|
+
on<K extends keyof TEvents>(event: K, handler: (payload: TEvents[K]) => void): () => void;
|
|
579
|
+
once<K extends keyof TEvents>(event: K, handler: (payload: TEvents[K]) => void): () => void;
|
|
580
|
+
off<K extends keyof TEvents>(event: K, handler: (payload: TEvents[K]) => void): void;
|
|
581
|
+
emit<K extends keyof TEvents>(event: K, payload: TEvents[K]): void;
|
|
582
|
+
clear(event?: keyof TEvents): void;
|
|
583
|
+
listenerCount(event: keyof TEvents): number;
|
|
584
|
+
}
|
|
585
|
+
|
|
586
|
+
/**
|
|
587
|
+
* 格式化通话时间
|
|
588
|
+
* @param seconds 秒数
|
|
589
|
+
* @returns 格式化的时间字符串 (HH:MM:SS 或 MM:SS)
|
|
590
|
+
*/
|
|
591
|
+
export declare const formatCallDuration: (seconds: number) => string;
|
|
592
|
+
|
|
593
|
+
/**
|
|
594
|
+
* 生成随机channel字符串
|
|
595
|
+
* @param length 字符串长度,默认8位
|
|
596
|
+
* @returns 随机字符串
|
|
597
|
+
*/
|
|
598
|
+
export declare const generateRandomChannel: (length?: number) => string;
|
|
599
|
+
|
|
600
|
+
export declare function getLogger(): Logger;
|
|
601
|
+
|
|
602
|
+
export declare interface GroupCallAcceptedEvent {
|
|
603
|
+
type: 'groupCallAccepted';
|
|
604
|
+
payload: BaseEvent & {
|
|
605
|
+
isCaller: boolean;
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
|
|
609
|
+
export declare interface GroupCallBusyEvent {
|
|
610
|
+
type: 'groupCallBusy';
|
|
611
|
+
payload: BaseEvent;
|
|
612
|
+
}
|
|
613
|
+
|
|
614
|
+
export declare interface GroupCallCanceledEvent {
|
|
615
|
+
type: 'groupCallCanceled';
|
|
616
|
+
payload: BaseEvent & {
|
|
617
|
+
isRemote: boolean;
|
|
618
|
+
};
|
|
619
|
+
}
|
|
620
|
+
|
|
621
|
+
export declare interface GroupCallConnectedEvent {
|
|
622
|
+
type: 'groupCallConnected';
|
|
623
|
+
payload: BaseEvent;
|
|
624
|
+
}
|
|
625
|
+
|
|
626
|
+
export declare interface GroupCallEndedEvent {
|
|
627
|
+
type: 'groupCallEnded';
|
|
628
|
+
payload: BaseEvent & {
|
|
629
|
+
reason: 'hangup' | 'cancel' | 'refuse' | 'busy' | 'timeout' | 'remoteHangup' | 'remoteCancel';
|
|
630
|
+
duration?: number;
|
|
631
|
+
};
|
|
632
|
+
}
|
|
633
|
+
|
|
634
|
+
export declare interface GroupCallInitEvent {
|
|
635
|
+
type: 'groupCallInit';
|
|
636
|
+
payload: {
|
|
637
|
+
callId: string;
|
|
638
|
+
groupId: string;
|
|
639
|
+
groupName: string;
|
|
640
|
+
channel: string;
|
|
641
|
+
callType: 'audio' | 'video';
|
|
642
|
+
callerUserId: string;
|
|
643
|
+
invitedMembers: string[];
|
|
644
|
+
};
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
export declare interface GroupCallInvitedEvent {
|
|
648
|
+
type: 'groupCallInvited';
|
|
649
|
+
payload: BaseEvent & {
|
|
650
|
+
isCaller: boolean;
|
|
651
|
+
};
|
|
652
|
+
}
|
|
653
|
+
|
|
654
|
+
export declare interface GroupCallRefusedEvent {
|
|
655
|
+
type: 'groupCallRefused';
|
|
656
|
+
payload: BaseEvent & {
|
|
657
|
+
isRemote: boolean;
|
|
658
|
+
};
|
|
659
|
+
}
|
|
660
|
+
|
|
661
|
+
/**
|
|
662
|
+
* 群聊会话管理
|
|
663
|
+
*
|
|
664
|
+
* 职责:
|
|
665
|
+
* 1. 管理群聊通话的会话元数据
|
|
666
|
+
* 2. 维护参与者集合及其状态流转
|
|
667
|
+
* 3. 不执行副作用,只维护内存状态
|
|
668
|
+
*/
|
|
669
|
+
export declare class GroupCallSession {
|
|
670
|
+
private session;
|
|
671
|
+
private participants;
|
|
672
|
+
private logger;
|
|
673
|
+
constructor(logger?: Logger);
|
|
674
|
+
/**
|
|
675
|
+
* 初始化会话
|
|
676
|
+
*/
|
|
677
|
+
init(params: {
|
|
678
|
+
sessionId: string;
|
|
679
|
+
groupId: string;
|
|
680
|
+
groupName: string;
|
|
681
|
+
callType: 'audio' | 'video';
|
|
682
|
+
callerUserId: string;
|
|
683
|
+
}): void;
|
|
684
|
+
/**
|
|
685
|
+
* 添加参与者
|
|
686
|
+
*/
|
|
687
|
+
addParticipant(info: GroupParticipant): void;
|
|
688
|
+
/**
|
|
689
|
+
* 移除参与者
|
|
690
|
+
*/
|
|
691
|
+
removeParticipant(userId: string): boolean;
|
|
692
|
+
/**
|
|
693
|
+
* 标记参与者状态
|
|
694
|
+
*/
|
|
695
|
+
setParticipantState(userId: string, state: GroupParticipant['state']): boolean;
|
|
696
|
+
/**
|
|
697
|
+
* 标记已接受
|
|
698
|
+
*/
|
|
699
|
+
markAccepted(userId: string): boolean;
|
|
700
|
+
/**
|
|
701
|
+
* 标记已加入 RTC
|
|
702
|
+
*/
|
|
703
|
+
markJoinedRtc(userId: string): boolean;
|
|
704
|
+
/**
|
|
705
|
+
* 标记已离开 RTC
|
|
706
|
+
*/
|
|
707
|
+
markLeftRtc(userId: string): boolean;
|
|
708
|
+
/**
|
|
709
|
+
* 标记音频静音状态
|
|
710
|
+
*/
|
|
711
|
+
markAudioMuted(userId: string, muted: boolean): boolean;
|
|
712
|
+
/**
|
|
713
|
+
* 标记视频开关状态
|
|
714
|
+
*/
|
|
715
|
+
markVideoOn(userId: string, on: boolean): boolean;
|
|
716
|
+
/**
|
|
717
|
+
* 获取参与者
|
|
718
|
+
*/
|
|
719
|
+
getParticipant(userId: string): Readonly<GroupParticipant> | undefined;
|
|
720
|
+
/**
|
|
721
|
+
* 获取所有参与者
|
|
722
|
+
*/
|
|
723
|
+
getAllParticipants(): Readonly<GroupParticipant>[];
|
|
724
|
+
/**
|
|
725
|
+
* 获取当前在线参与者(未离开)
|
|
726
|
+
*/
|
|
727
|
+
getActiveParticipants(): Readonly<GroupParticipant>[];
|
|
728
|
+
/**
|
|
729
|
+
* 获取会话快照
|
|
730
|
+
*/
|
|
731
|
+
getSnapshot(): Readonly<GroupSessionState> | null;
|
|
732
|
+
/**
|
|
733
|
+
* 结束会话
|
|
734
|
+
*/
|
|
735
|
+
end(): void;
|
|
736
|
+
/**
|
|
737
|
+
* 销毁会话
|
|
738
|
+
*/
|
|
739
|
+
destroy(): void;
|
|
740
|
+
}
|
|
741
|
+
|
|
742
|
+
/**
|
|
743
|
+
* GroupCallSignalHandler
|
|
744
|
+
* 群聊域信令处理器
|
|
745
|
+
*
|
|
746
|
+
* 改造后:
|
|
747
|
+
* - 不读写 GroupCallStore → 注入 GroupCallSession
|
|
748
|
+
* - 不直接调用 CallService → 返回 DomainEvent[]
|
|
749
|
+
* - 不直接 emit callKitEventBus → 返回 DomainEvent[]
|
|
750
|
+
* - 保留 SingleCallStateMachine 用于 callId / 状态校验(与原架构一致)
|
|
751
|
+
*/
|
|
752
|
+
export declare class GroupCallSignalHandler implements SignalHandler {
|
|
753
|
+
private session;
|
|
754
|
+
private stateMachine;
|
|
755
|
+
private sender;
|
|
756
|
+
private getUserId;
|
|
757
|
+
private logger;
|
|
758
|
+
constructor(session: GroupCallSession, stateMachine: SingleCallStateMachine, sender: SignalSender, userIdProvider: (() => string) | string, logger?: Logger);
|
|
759
|
+
private get userId();
|
|
760
|
+
/**
|
|
761
|
+
* 处理 invite 文本消息中的群聊初始化
|
|
762
|
+
* 由 IMListener 在收到 invite 文本消息时直接调用(不走 SignalRouter)
|
|
763
|
+
*/
|
|
764
|
+
handleInviteTextMessage(message: CmdMsgBody): DomainEvent[];
|
|
765
|
+
handle(message: CmdMsgBody): DomainEvent[];
|
|
766
|
+
private handleAnswerCall;
|
|
767
|
+
private sendConfirmCallee;
|
|
768
|
+
private handleCancelCall;
|
|
769
|
+
private handleLeaveCall;
|
|
770
|
+
}
|
|
771
|
+
|
|
772
|
+
export declare interface GroupCallStartedEvent {
|
|
773
|
+
type: 'groupCallStarted';
|
|
774
|
+
payload: BaseEvent & {
|
|
775
|
+
isCaller: boolean;
|
|
776
|
+
startTime: number;
|
|
777
|
+
};
|
|
778
|
+
}
|
|
779
|
+
|
|
780
|
+
export declare interface GroupCallTimeoutEvent {
|
|
781
|
+
type: 'groupCallTimeout';
|
|
782
|
+
payload: BaseEvent;
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
/**
|
|
786
|
+
* 群聊参与者
|
|
787
|
+
*/
|
|
788
|
+
export declare interface GroupParticipant {
|
|
789
|
+
userId: string;
|
|
790
|
+
nickname: string;
|
|
791
|
+
avatarUrl?: string;
|
|
792
|
+
state: 'invited' | 'accepted' | 'joinedRtc' | 'left';
|
|
793
|
+
isLocal: boolean;
|
|
794
|
+
isMuted: boolean;
|
|
795
|
+
isCameraOn: boolean;
|
|
796
|
+
isSpeaking: boolean;
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
/**
|
|
800
|
+
* 群聊会话状态
|
|
801
|
+
*/
|
|
802
|
+
export declare interface GroupSessionState {
|
|
803
|
+
sessionId: string;
|
|
804
|
+
groupId: string;
|
|
805
|
+
groupName: string;
|
|
806
|
+
callType: 'audio' | 'video';
|
|
807
|
+
status: 'inviting' | 'inCall' | 'ended';
|
|
808
|
+
callerUserId: string;
|
|
809
|
+
startTime: number;
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
export declare type HANGUP_REASON = "hangup" | "cancel" | "remoteCancel" | "refuse" | "remoteRefuse" | "busy" | "noResponse" | "remoteNoResponse" | "handleOnOtherDevice" | "abnormalEnd";
|
|
813
|
+
|
|
814
|
+
export declare const HANGUP_REASON: {
|
|
815
|
+
readonly HANGUP: "hangup";
|
|
816
|
+
readonly CANCEL: "cancel";
|
|
817
|
+
readonly REMOTE_CANCEL: "remoteCancel";
|
|
818
|
+
readonly REFUSE: "refuse";
|
|
819
|
+
readonly REMOTE_REFUSE: "remoteRefuse";
|
|
820
|
+
readonly BUSY: "busy";
|
|
821
|
+
readonly NO_RESPONSE: "noResponse";
|
|
822
|
+
readonly REMOTE_NO_RESPONSE: "remoteNoResponse";
|
|
823
|
+
readonly HANDLE_ON_OTHER_DEVICE: "handleOnOtherDevice";
|
|
824
|
+
readonly ABNORMAL_END: "abnormalEnd";
|
|
825
|
+
};
|
|
826
|
+
|
|
827
|
+
export declare interface HangupParams {
|
|
828
|
+
callId?: string;
|
|
829
|
+
reason?: 'normal' | 'cancel' | 'timeout';
|
|
830
|
+
}
|
|
831
|
+
|
|
832
|
+
/**
|
|
833
|
+
* IMListener
|
|
834
|
+
* 环信 IM SDK 消息监听器薄壳。
|
|
835
|
+
*
|
|
836
|
+
* 职责:
|
|
837
|
+
* 1. 挂载 onTextMessage / onCmdMessage 监听
|
|
838
|
+
* 2. 收到后通过回调交给 CallKitCore 处理(不处理任何业务逻辑)
|
|
839
|
+
*/
|
|
840
|
+
export declare class IMListener {
|
|
841
|
+
private imClient;
|
|
842
|
+
private callbacks;
|
|
843
|
+
private logger;
|
|
844
|
+
private mounted;
|
|
845
|
+
private handlerId;
|
|
846
|
+
constructor(imClient: EasemobConnection, callbacks: IMListenerCallbacks, logger?: Logger);
|
|
847
|
+
mount(): void;
|
|
848
|
+
unmount(): void;
|
|
849
|
+
}
|
|
850
|
+
|
|
851
|
+
export declare interface IMListenerCallbacks {
|
|
852
|
+
onTextMessage?: (msg: any) => void | Promise<void>;
|
|
853
|
+
onCmdMessage?: (msg: any) => void | Promise<void>;
|
|
854
|
+
onConnected?: () => void;
|
|
855
|
+
onDisconnected?: () => void;
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
/**
|
|
859
|
+
* IM 抽象接口
|
|
860
|
+
*
|
|
861
|
+
* 核心库通过此接口与环信 IM SDK 交互,不直接 import easemob-websdk。
|
|
862
|
+
* 由于环信 Web/小程序/UniApp API 一致,此接口可直接映射到环信 SDK。
|
|
863
|
+
*/
|
|
864
|
+
export declare interface IMMessage {
|
|
865
|
+
from?: string;
|
|
866
|
+
to?: string;
|
|
867
|
+
id?: string;
|
|
868
|
+
type: 'txt' | 'cmd';
|
|
869
|
+
body?: any;
|
|
870
|
+
ext?: Record<string, any>;
|
|
871
|
+
[key: string]: any;
|
|
872
|
+
}
|
|
873
|
+
|
|
874
|
+
export declare interface IMProvider {
|
|
875
|
+
/** 发送消息 */
|
|
876
|
+
sendMessage(msg: IMMessage): Promise<any>;
|
|
877
|
+
/** 获取当前登录用户 ID */
|
|
878
|
+
getCurrentUserId(): string;
|
|
879
|
+
/** 获取当前设备 ID */
|
|
880
|
+
getCurrentDeviceId(): string;
|
|
881
|
+
/** 获取 RTC Token 和 AppId(环信 SDK 特有方法) */
|
|
882
|
+
getRtcToken(channel: string): Promise<{
|
|
883
|
+
token: string;
|
|
884
|
+
appId: string;
|
|
885
|
+
}>;
|
|
886
|
+
/** UID → UserId 映射查询(环信 SDK 特有方法) */
|
|
887
|
+
getUserIdByRtcUids(uids: (string | number)[]): Promise<Record<string, string>>;
|
|
888
|
+
/** 挂载消息监听 */
|
|
889
|
+
onTextMessage(handler: (msg: IMMessage) => void): () => void;
|
|
890
|
+
/** 挂载 CMD 消息监听 */
|
|
891
|
+
onCmdMessage(handler: (msg: IMMessage) => void): () => void;
|
|
892
|
+
}
|
|
893
|
+
|
|
894
|
+
export declare interface IncomingCallEvent {
|
|
895
|
+
type: 'incomingCall';
|
|
896
|
+
payload: {
|
|
897
|
+
callId: string;
|
|
898
|
+
callType: CALL_TYPE;
|
|
899
|
+
callerUserId: string;
|
|
900
|
+
callerDevId: string;
|
|
901
|
+
channel: string;
|
|
902
|
+
calleeUserId: string;
|
|
903
|
+
token?: string;
|
|
904
|
+
groupId?: string;
|
|
905
|
+
groupName?: string;
|
|
906
|
+
invitedMembers?: string[];
|
|
907
|
+
callerInfo?: {
|
|
908
|
+
nickname?: string;
|
|
909
|
+
avatarURL?: string;
|
|
910
|
+
};
|
|
911
|
+
};
|
|
912
|
+
}
|
|
913
|
+
|
|
914
|
+
export declare interface InviteCallParams {
|
|
915
|
+
calleeUserId: string;
|
|
916
|
+
callType: CALL_TYPE;
|
|
917
|
+
ext?: Record<string, any>;
|
|
918
|
+
/**
|
|
919
|
+
* 当前用户(主叫方)资料。
|
|
920
|
+
* 优先级高于 CallKitCoreConfig.userProfile,用于让每次邀请都携带最新的昵称/头像。
|
|
921
|
+
*/
|
|
922
|
+
callerInfo?: {
|
|
923
|
+
nickname?: string;
|
|
924
|
+
avatarURL?: string;
|
|
925
|
+
};
|
|
926
|
+
}
|
|
927
|
+
|
|
928
|
+
export declare interface InviteGroupCallParams {
|
|
929
|
+
groupId: string;
|
|
930
|
+
participantIds: string[];
|
|
931
|
+
callType: CALL_TYPE;
|
|
932
|
+
ext?: Record<string, any>;
|
|
933
|
+
/**
|
|
934
|
+
* 当前用户(主叫方)资料。
|
|
935
|
+
* 优先级高于 CallKitCoreConfig.userProfile,用于让每次邀请都携带最新的昵称/头像。
|
|
936
|
+
*/
|
|
937
|
+
callerInfo?: {
|
|
938
|
+
nickname?: string;
|
|
939
|
+
avatarURL?: string;
|
|
940
|
+
};
|
|
941
|
+
}
|
|
942
|
+
|
|
943
|
+
/**
|
|
944
|
+
* 邀请消息扩展字段接口
|
|
945
|
+
*/
|
|
946
|
+
export declare interface InviteSignalingExt extends BaseSignalingExt {
|
|
947
|
+
action: "invite";
|
|
948
|
+
/** RTC频道名称 */
|
|
949
|
+
channelName: string;
|
|
950
|
+
/** 通话类型 */
|
|
951
|
+
type: number;
|
|
952
|
+
/** 主叫设备ID */
|
|
953
|
+
callerDevId: string;
|
|
954
|
+
/** 主叫IM用户名 */
|
|
955
|
+
callerIMName: string;
|
|
956
|
+
/** 被叫IM用户名 */
|
|
957
|
+
calleeIMName: string;
|
|
958
|
+
/** 聊天类型 */
|
|
959
|
+
chatType: number;
|
|
960
|
+
/** 推送扩展字段 */
|
|
961
|
+
em_push_ext: {
|
|
962
|
+
type: string;
|
|
963
|
+
custom: {
|
|
964
|
+
action: string;
|
|
965
|
+
channelName: string;
|
|
966
|
+
type: number;
|
|
967
|
+
callerDevId: string;
|
|
968
|
+
callId: string;
|
|
969
|
+
ts: number;
|
|
970
|
+
msgType: string;
|
|
971
|
+
callerIMName: string;
|
|
972
|
+
calleeIMName: string;
|
|
973
|
+
callerNickname: string;
|
|
974
|
+
chatType: number;
|
|
975
|
+
ext?: Record<string, any>;
|
|
976
|
+
};
|
|
977
|
+
};
|
|
978
|
+
/** APNS推送扩展字段 */
|
|
979
|
+
em_apns_ext: {
|
|
980
|
+
em_push_type: string;
|
|
981
|
+
};
|
|
982
|
+
/** 自定义扩展字段 */
|
|
983
|
+
ext?: Record<string, any>;
|
|
984
|
+
/** 被邀请成员列表(群组通话时使用) */
|
|
985
|
+
invitedMembers?: string[];
|
|
986
|
+
/** 用户信息(发送方 caller 资料) */
|
|
987
|
+
ease_chat_uikit_user_info?: {
|
|
988
|
+
nickname: string;
|
|
989
|
+
avatarURL: string;
|
|
990
|
+
};
|
|
991
|
+
/** 群组通话信息 */
|
|
992
|
+
callkitGroupInfo?: {
|
|
993
|
+
groupId: string;
|
|
994
|
+
groupName?: string;
|
|
995
|
+
groupAvatar?: string;
|
|
996
|
+
};
|
|
997
|
+
/**
|
|
998
|
+
* 兼容新版 iOS EaseCallUIKit:ext 最外层携带 groupId
|
|
999
|
+
*/
|
|
1000
|
+
groupId?: string;
|
|
1001
|
+
/**
|
|
1002
|
+
* 兼容新版 iOS EaseCallUIKit:ext 最外层携带 receiverList
|
|
1003
|
+
*/
|
|
1004
|
+
receiverList?: string[];
|
|
1005
|
+
}
|
|
1006
|
+
|
|
1007
|
+
/**
|
|
1008
|
+
* CMD 消息过期检查(与 lib 对齐,默认 60s)
|
|
1009
|
+
* @param messageTime 消息时间戳(毫秒)
|
|
1010
|
+
* @returns 是否已过期
|
|
1011
|
+
*/
|
|
1012
|
+
export declare const isCmdMessageExpired: (messageTime: number) => boolean;
|
|
1013
|
+
|
|
1014
|
+
/**
|
|
1015
|
+
* 检查消息是否已过期
|
|
1016
|
+
* 与 lib/composables/useListenerManager.ts 中的 isMessageExpired 对齐
|
|
1017
|
+
* @param messageTime 消息时间戳(毫秒)
|
|
1018
|
+
* @param toleranceMs 容忍时间(毫秒),默认 40000(30s invite超时 + 10s 容差)
|
|
1019
|
+
* @returns 是否已过期
|
|
1020
|
+
*/
|
|
1021
|
+
export declare const isMessageExpired: (messageTime: number, toleranceMs?: number) => boolean;
|
|
1022
|
+
|
|
1023
|
+
export declare function isRtcEvent(event: CallKitEvent): event is RtcEvent;
|
|
1024
|
+
|
|
1025
|
+
export declare function isUIEvent(event: CallKitEvent): event is UIEvent_2;
|
|
1026
|
+
|
|
1027
|
+
/**
|
|
1028
|
+
* RTC 抽象接口
|
|
1029
|
+
*
|
|
1030
|
+
* 核心库不直接调用任何 RTC SDK,只通过此接口定义期望的 RTC 能力。
|
|
1031
|
+
* 上层(Vue3/UniApp/React)自行实现此接口,接入对应的 RTC SDK。
|
|
1032
|
+
*/
|
|
1033
|
+
export declare interface JoinRtcParams {
|
|
1034
|
+
channel: string;
|
|
1035
|
+
token: string;
|
|
1036
|
+
uid: string | number;
|
|
1037
|
+
appId?: string;
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
/**
|
|
1041
|
+
* 挂断通话消息扩展字段接口
|
|
1042
|
+
*/
|
|
1043
|
+
export declare interface LeaveCallSignalingExt extends BaseSignalingExt {
|
|
1044
|
+
action: "leaveCall";
|
|
1045
|
+
}
|
|
1046
|
+
|
|
1047
|
+
export declare interface LocalAudioChangedEvent {
|
|
1048
|
+
type: 'localAudioChanged';
|
|
1049
|
+
payload: {
|
|
1050
|
+
enabled: boolean;
|
|
1051
|
+
};
|
|
1052
|
+
}
|
|
1053
|
+
|
|
1054
|
+
export declare interface LocalVideoChangedEvent {
|
|
1055
|
+
type: 'localVideoChanged';
|
|
1056
|
+
payload: {
|
|
1057
|
+
enabled: boolean;
|
|
1058
|
+
};
|
|
1059
|
+
}
|
|
1060
|
+
|
|
1061
|
+
/**
|
|
1062
|
+
* 轻量级日志接口
|
|
1063
|
+
* 核心库不依赖外部日志库(如 dexie),通过接口允许上层注入自定义 logger。
|
|
1064
|
+
*/
|
|
1065
|
+
export declare interface Logger {
|
|
1066
|
+
error(message: string, ...args: any[]): void;
|
|
1067
|
+
warn(message: string, ...args: any[]): void;
|
|
1068
|
+
info(message: string, ...args: any[]): void;
|
|
1069
|
+
debug(message: string, ...args: any[]): void;
|
|
1070
|
+
verbose(message: string, ...args: any[]): void;
|
|
1071
|
+
signal?(direction: 'send' | 'recv', action: string, meta?: Record<string, any>): void;
|
|
1072
|
+
stateChange?(from: any, to: any, meta?: Record<string, any>): void;
|
|
1073
|
+
rtc?(event: string, meta?: Record<string, any>): void;
|
|
1074
|
+
event?(event: string, meta?: Record<string, any>): void;
|
|
1075
|
+
}
|
|
1076
|
+
|
|
1077
|
+
export declare class MessageBuilder {
|
|
1078
|
+
/**
|
|
1079
|
+
* 构建 invite 文本消息的 ext
|
|
1080
|
+
*/
|
|
1081
|
+
static buildInviteExt(params: BuildInviteMessageParams): InviteSignalingExt;
|
|
1082
|
+
/**
|
|
1083
|
+
* 构建 CMD 信令消息的 ext
|
|
1084
|
+
*/
|
|
1085
|
+
static buildCmdExt(params: BuildCmdMessageParams): SignalingExt;
|
|
1086
|
+
}
|
|
1087
|
+
|
|
1088
|
+
export declare interface ParticipantJoinedEvent {
|
|
1089
|
+
type: 'participantJoined';
|
|
1090
|
+
payload: BaseEvent & {
|
|
1091
|
+
userId: string;
|
|
1092
|
+
groupId?: string;
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
|
|
1096
|
+
export declare interface ParticipantLeftEvent {
|
|
1097
|
+
type: 'participantLeft';
|
|
1098
|
+
payload: BaseEvent & {
|
|
1099
|
+
userId: string;
|
|
1100
|
+
reason: string;
|
|
1101
|
+
groupId?: string;
|
|
1102
|
+
};
|
|
1103
|
+
}
|
|
1104
|
+
|
|
1105
|
+
export declare interface ParticipantStateChangedEvent {
|
|
1106
|
+
type: 'participantStateChanged';
|
|
1107
|
+
payload: {
|
|
1108
|
+
callId: string;
|
|
1109
|
+
userId: string;
|
|
1110
|
+
state: 'invited' | 'accepted' | 'joinedRtc' | 'left';
|
|
1111
|
+
groupId?: string;
|
|
1112
|
+
};
|
|
1113
|
+
}
|
|
1114
|
+
|
|
1115
|
+
export declare interface RtcAdapter {
|
|
1116
|
+
/**
|
|
1117
|
+
* 加入 RTC 频道
|
|
1118
|
+
*/
|
|
1119
|
+
joinChannel(params: JoinRtcParams): Promise<void>;
|
|
1120
|
+
/**
|
|
1121
|
+
* 离开 RTC 频道
|
|
1122
|
+
*/
|
|
1123
|
+
leaveChannel(): Promise<void>;
|
|
1124
|
+
/**
|
|
1125
|
+
* 创建并发布本地轨道
|
|
1126
|
+
* @param types 要发布的轨道类型
|
|
1127
|
+
*/
|
|
1128
|
+
publishLocalTracks(types: ('audio' | 'video')[]): Promise<void>;
|
|
1129
|
+
/**
|
|
1130
|
+
* 取消发布本地轨道
|
|
1131
|
+
*/
|
|
1132
|
+
unpublishLocalTracks(types: ('audio' | 'video')[]): Promise<void>;
|
|
1133
|
+
/**
|
|
1134
|
+
* 订阅远程用户
|
|
1135
|
+
*/
|
|
1136
|
+
subscribeRemoteUser(userId: string, mediaType: 'audio' | 'video'): Promise<void>;
|
|
1137
|
+
/**
|
|
1138
|
+
* 取消订阅远程用户
|
|
1139
|
+
*/
|
|
1140
|
+
unsubscribeRemoteUser(userId: string, mediaType: 'audio' | 'video'): Promise<void>;
|
|
1141
|
+
/**
|
|
1142
|
+
* 静音/取消静音
|
|
1143
|
+
*/
|
|
1144
|
+
setAudioEnabled(enabled: boolean): Promise<void>;
|
|
1145
|
+
/**
|
|
1146
|
+
* 开启/关闭摄像头
|
|
1147
|
+
*/
|
|
1148
|
+
setVideoEnabled(enabled: boolean): Promise<void>;
|
|
1149
|
+
/**
|
|
1150
|
+
* 切换摄像头设备
|
|
1151
|
+
*/
|
|
1152
|
+
switchCamera?(deviceId: string): Promise<void>;
|
|
1153
|
+
/**
|
|
1154
|
+
* 切换麦克风设备
|
|
1155
|
+
*/
|
|
1156
|
+
switchMicrophone?(deviceId: string): Promise<void>;
|
|
1157
|
+
/**
|
|
1158
|
+
* 切换音频输出设备(移动端:扬声器/听筒)
|
|
1159
|
+
*/
|
|
1160
|
+
switchAudioOutput?(device: 'speaker' | 'earpiece'): Promise<void>;
|
|
1161
|
+
}
|
|
1162
|
+
|
|
1163
|
+
export declare type RtcEvent = ShouldJoinRtcEvent | ShouldLeaveRtcEvent | ShouldPublishTracksEvent | LocalAudioChangedEvent | LocalVideoChangedEvent;
|
|
1164
|
+
|
|
1165
|
+
export declare interface RtcReport {
|
|
1166
|
+
type: 'rtcJoined' | 'rtcLeft' | 'userJoined' | 'userLeft' | 'userPublished' | 'userUnpublished' | 'userAudioMuted' | 'userAudioUnmuted' | 'userVideoMuted' | 'userVideoUnmuted' | 'networkQuality' | 'speaking' | 'stoppedSpeaking' | 'error';
|
|
1167
|
+
payload: {
|
|
1168
|
+
userId?: string;
|
|
1169
|
+
uid?: string | number;
|
|
1170
|
+
mediaType?: 'audio' | 'video';
|
|
1171
|
+
track?: any;
|
|
1172
|
+
/** 网络质量:0=未知, 1=优, 2=良, 3=一般, 4=差, 5=极差, 6=断开 */
|
|
1173
|
+
quality?: number;
|
|
1174
|
+
/** 说话音量 0-100 */
|
|
1175
|
+
volume?: number;
|
|
1176
|
+
/** 错误信息 */
|
|
1177
|
+
error?: string;
|
|
1178
|
+
/** 错误码 */
|
|
1179
|
+
errorCode?: number;
|
|
1180
|
+
};
|
|
1181
|
+
}
|
|
1182
|
+
|
|
1183
|
+
declare interface RtcReportEvent {
|
|
1184
|
+
type: 'rtcReport';
|
|
1185
|
+
payload: {
|
|
1186
|
+
type: string;
|
|
1187
|
+
payload: Record<string, any>;
|
|
1188
|
+
};
|
|
1189
|
+
}
|
|
1190
|
+
|
|
1191
|
+
export declare function setLogger(logger: Logger): void;
|
|
1192
|
+
|
|
1193
|
+
export declare interface ShouldJoinRtcEvent {
|
|
1194
|
+
type: 'shouldJoinRtc';
|
|
1195
|
+
payload: BaseEvent & {
|
|
1196
|
+
token: string;
|
|
1197
|
+
uid: number | string;
|
|
1198
|
+
/** Agora App ID(来自 IM 服务端 getRTCToken 返回),为空时上层使用初始化时传入的 appId */
|
|
1199
|
+
appId?: string;
|
|
1200
|
+
role: 'caller' | 'callee';
|
|
1201
|
+
};
|
|
1202
|
+
}
|
|
1203
|
+
|
|
1204
|
+
export declare interface ShouldLeaveRtcEvent {
|
|
1205
|
+
type: 'shouldLeaveRtc';
|
|
1206
|
+
payload: BaseEvent & {
|
|
1207
|
+
reason: string;
|
|
1208
|
+
};
|
|
1209
|
+
}
|
|
1210
|
+
|
|
1211
|
+
export declare interface ShouldPublishTracksEvent {
|
|
1212
|
+
type: 'shouldPublishTracks';
|
|
1213
|
+
payload: BaseEvent & {
|
|
1214
|
+
trackTypes: ('audio' | 'video')[];
|
|
1215
|
+
};
|
|
1216
|
+
}
|
|
1217
|
+
|
|
1218
|
+
export declare interface SignalHandler {
|
|
1219
|
+
handle(message: CmdMsgBody): DomainEvent[];
|
|
1220
|
+
}
|
|
1221
|
+
|
|
1222
|
+
/**
|
|
1223
|
+
* 所有信令消息扩展字段的联合类型
|
|
1224
|
+
*/
|
|
1225
|
+
export declare type SignalingExt = AlertSignalingExt | ConfirmRingSignalingExt | AnswerCallSignalingExt | ConfirmCalleeSignalingExt | CancelCallSignalingExt | LeaveCallSignalingExt;
|
|
1226
|
+
|
|
1227
|
+
export declare interface SignalMessageInviteExt {
|
|
1228
|
+
action: "invite";
|
|
1229
|
+
callId: string;
|
|
1230
|
+
calleeIMName: string;
|
|
1231
|
+
callerDevId: string;
|
|
1232
|
+
callerIMName: string;
|
|
1233
|
+
channelName: string;
|
|
1234
|
+
chatType: CALL_TYPE;
|
|
1235
|
+
type: CALL_TYPE;
|
|
1236
|
+
ts: number;
|
|
1237
|
+
msgType: CALLKIT_ACTION_MSG_TYPE;
|
|
1238
|
+
em_push_ext: {
|
|
1239
|
+
type: "call";
|
|
1240
|
+
custom: {
|
|
1241
|
+
action: "invite";
|
|
1242
|
+
channelName: string;
|
|
1243
|
+
type: CALL_TYPE;
|
|
1244
|
+
callerDevId: string;
|
|
1245
|
+
callId: string;
|
|
1246
|
+
ts: number;
|
|
1247
|
+
msgType: CALLKIT_ACTION_MSG_TYPE;
|
|
1248
|
+
callerIMName: string;
|
|
1249
|
+
calleeIMName: string;
|
|
1250
|
+
callerNickname: string;
|
|
1251
|
+
chatType: CALL_TYPE;
|
|
1252
|
+
};
|
|
1253
|
+
};
|
|
1254
|
+
em_apns_ext: {
|
|
1255
|
+
em_push_type: "voip";
|
|
1256
|
+
};
|
|
1257
|
+
ease_chat_uikit_user_info?: {
|
|
1258
|
+
nickname: string;
|
|
1259
|
+
avatarURL: string;
|
|
1260
|
+
};
|
|
1261
|
+
callkitGroupInfo?: {
|
|
1262
|
+
groupId: string;
|
|
1263
|
+
groupName?: string;
|
|
1264
|
+
groupAvatar?: string;
|
|
1265
|
+
};
|
|
1266
|
+
}
|
|
1267
|
+
|
|
1268
|
+
/**
|
|
1269
|
+
* SignalRouter
|
|
1270
|
+
* 信令消息中央路由器
|
|
1271
|
+
* 职责:根据 action 将消息分发给已注册的 Handler
|
|
1272
|
+
*/
|
|
1273
|
+
export declare class SignalRouter {
|
|
1274
|
+
private handlers;
|
|
1275
|
+
private logger;
|
|
1276
|
+
constructor(logger?: Logger);
|
|
1277
|
+
register(action: string, handler: SignalHandler): void;
|
|
1278
|
+
dispatch(message: CmdMsgBody): DomainEvent[];
|
|
1279
|
+
}
|
|
1280
|
+
|
|
1281
|
+
/**
|
|
1282
|
+
* SignalSender
|
|
1283
|
+
* 信令发送器,封装环信 IM SDK 的消息发送。
|
|
1284
|
+
*
|
|
1285
|
+
* 由 useSignalManager 改造而来,从 Vue Composable 退化为普通类。
|
|
1286
|
+
*/
|
|
1287
|
+
export declare class SignalSender {
|
|
1288
|
+
private imClient;
|
|
1289
|
+
private logger;
|
|
1290
|
+
private createMessageFn?;
|
|
1291
|
+
constructor(imClient: EasemobConnection, logger?: Logger, createMessageFn?: (options: any) => any);
|
|
1292
|
+
/**
|
|
1293
|
+
* 发送 invite 文本消息
|
|
1294
|
+
*/
|
|
1295
|
+
sendInviteMessage(targetId: string | string[], chatType: 'singleChat' | 'groupChat', message: string, ext: SignalingExt | Record<string, any>, groupId?: string): Promise<any>;
|
|
1296
|
+
/**
|
|
1297
|
+
* 发送 CMD 信令消息
|
|
1298
|
+
*/
|
|
1299
|
+
sendCmdMessage(targetId: string, chatType: 'singleChat' | 'groupChat', ext: SignalingExt | Record<string, any>, options?: {
|
|
1300
|
+
deliverOnlineOnly?: boolean;
|
|
1301
|
+
receiverList?: string[];
|
|
1302
|
+
}): Promise<any>;
|
|
1303
|
+
/**
|
|
1304
|
+
* 兼容 full 版与 miniCore 版的消息创建
|
|
1305
|
+
* full 版: ChatSDK.message.create(options)
|
|
1306
|
+
* miniCore 版: client.Message.create(options)
|
|
1307
|
+
*/
|
|
1308
|
+
private createMessage;
|
|
1309
|
+
}
|
|
1310
|
+
|
|
1311
|
+
export declare interface SingleCallAcceptedEvent {
|
|
1312
|
+
type: 'singleCallAccepted';
|
|
1313
|
+
payload: BaseEvent & {
|
|
1314
|
+
isCaller: boolean;
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
|
|
1318
|
+
export declare interface SingleCallBusyEvent {
|
|
1319
|
+
type: 'singleCallBusy';
|
|
1320
|
+
payload: BaseEvent;
|
|
1321
|
+
}
|
|
1322
|
+
|
|
1323
|
+
export declare interface SingleCallCanceledEvent {
|
|
1324
|
+
type: 'singleCallCanceled';
|
|
1325
|
+
payload: BaseEvent & {
|
|
1326
|
+
isRemote: boolean;
|
|
1327
|
+
};
|
|
1328
|
+
}
|
|
1329
|
+
|
|
1330
|
+
export declare interface SingleCallConnectedEvent {
|
|
1331
|
+
type: 'singleCallConnected';
|
|
1332
|
+
payload: BaseEvent;
|
|
1333
|
+
}
|
|
1334
|
+
|
|
1335
|
+
export declare interface SingleCallEndedEvent {
|
|
1336
|
+
type: 'singleCallEnded';
|
|
1337
|
+
payload: BaseEvent & {
|
|
1338
|
+
reason: 'hangup' | 'cancel' | 'refuse' | 'busy' | 'timeout' | 'remoteHangup' | 'remoteCancel';
|
|
1339
|
+
duration?: number;
|
|
1340
|
+
};
|
|
1341
|
+
}
|
|
1342
|
+
|
|
1343
|
+
export declare interface SingleCallInvitedEvent {
|
|
1344
|
+
type: 'singleCallInvited';
|
|
1345
|
+
payload: BaseEvent & {
|
|
1346
|
+
isCaller: boolean;
|
|
1347
|
+
};
|
|
1348
|
+
}
|
|
1349
|
+
|
|
1350
|
+
export declare interface SingleCallRefusedEvent {
|
|
1351
|
+
type: 'singleCallRefused';
|
|
1352
|
+
payload: BaseEvent & {
|
|
1353
|
+
isRemote: boolean;
|
|
1354
|
+
};
|
|
1355
|
+
}
|
|
1356
|
+
|
|
1357
|
+
/**
|
|
1358
|
+
* SingleCallSignalHandler
|
|
1359
|
+
* 单聊域信令处理器
|
|
1360
|
+
*
|
|
1361
|
+
* 改造后:
|
|
1362
|
+
* - 不读写 Pinia Store → 注入 SingleCallStateMachine
|
|
1363
|
+
* - 不直接 join RTC → 通过 StateMachine 返回 SHOULD_JOIN_RTC 事件
|
|
1364
|
+
* - 不直接调用 CallService.hangup() → 返回 CALL_ENDED 事件
|
|
1365
|
+
* - 不直接 emit callKitEventBus → 返回 DomainEvent[]
|
|
1366
|
+
* - 保留直接发送响应信令(confirmRing / confirmCallee)→ 注入 SignalSender
|
|
1367
|
+
*/
|
|
1368
|
+
export declare class SingleCallSignalHandler implements SignalHandler {
|
|
1369
|
+
private stateMachine;
|
|
1370
|
+
private sender;
|
|
1371
|
+
private getDeviceId;
|
|
1372
|
+
private logger;
|
|
1373
|
+
constructor(stateMachine: SingleCallStateMachine, sender: SignalSender, deviceIdProvider: (() => string) | string, logger?: Logger);
|
|
1374
|
+
private get deviceId();
|
|
1375
|
+
handle(message: CmdMsgBody): DomainEvent[];
|
|
1376
|
+
private handleAlert;
|
|
1377
|
+
private buildConfirmRingPayload;
|
|
1378
|
+
private handleConfirmRing;
|
|
1379
|
+
private handleAnswerCall;
|
|
1380
|
+
private handleCancelCall;
|
|
1381
|
+
private handleLeaveCall;
|
|
1382
|
+
private handleConfirmCallee;
|
|
1383
|
+
private sendConfirmCallee;
|
|
1384
|
+
}
|
|
1385
|
+
|
|
1386
|
+
export declare interface SingleCallStartedEvent {
|
|
1387
|
+
type: 'singleCallStarted';
|
|
1388
|
+
payload: BaseEvent & {
|
|
1389
|
+
isCaller: boolean;
|
|
1390
|
+
startTime: number;
|
|
1391
|
+
};
|
|
1392
|
+
}
|
|
1393
|
+
|
|
1394
|
+
export declare interface SingleCallState {
|
|
1395
|
+
status: CALL_STATUS;
|
|
1396
|
+
callId: string;
|
|
1397
|
+
channel: string;
|
|
1398
|
+
token: string;
|
|
1399
|
+
type: CALL_TYPE;
|
|
1400
|
+
callerDevId: string;
|
|
1401
|
+
calleeDevId: string;
|
|
1402
|
+
callerUserId: string;
|
|
1403
|
+
calleeUserId: string;
|
|
1404
|
+
inviteTimeout: number;
|
|
1405
|
+
inviteTimeoutTimer: ReturnType<typeof setTimeout> | null;
|
|
1406
|
+
startTime: number | null;
|
|
1407
|
+
audioEnabled: boolean;
|
|
1408
|
+
videoEnabled: boolean;
|
|
1409
|
+
}
|
|
1410
|
+
|
|
1411
|
+
/**
|
|
1412
|
+
* 单聊通话状态机
|
|
1413
|
+
*
|
|
1414
|
+
* 职责:
|
|
1415
|
+
* 1. 管理 IDLE → INVITING → ALERTING → RECEIVED_CONFIRM_RING → IN_CALL 的状态流转
|
|
1416
|
+
* 2. 校验 callId、deviceId、多端冲突(由 Handler 调用前预校验,状态机二次兜底)
|
|
1417
|
+
* 3. 管理邀请超时定时器
|
|
1418
|
+
* 4. 计算通话时长
|
|
1419
|
+
*
|
|
1420
|
+
* 不执行任何副作用(不发消息、不 join RTC),只返回领域事件。
|
|
1421
|
+
*
|
|
1422
|
+
* 状态流转规则从现有 lib/store/callState.ts + lib/signaling/SingleCallSignalHandler.ts 提取。
|
|
1423
|
+
*/
|
|
1424
|
+
export declare class SingleCallStateMachine {
|
|
1425
|
+
private state;
|
|
1426
|
+
private logger;
|
|
1427
|
+
constructor(logger?: Logger);
|
|
1428
|
+
getState(): Readonly<SingleCallState>;
|
|
1429
|
+
isIdle(): boolean;
|
|
1430
|
+
isInCall(): boolean;
|
|
1431
|
+
/**
|
|
1432
|
+
* 当前是否处于可被接听的状态(被叫端弹窗显示区间)
|
|
1433
|
+
*/
|
|
1434
|
+
isWaitingCalleeAction(): boolean;
|
|
1435
|
+
/**
|
|
1436
|
+
* 当前是否处于活跃通话中(已进入 RTC 或即将进入)
|
|
1437
|
+
*/
|
|
1438
|
+
isInActiveCall(): boolean;
|
|
1439
|
+
/**
|
|
1440
|
+
* 当前是否可以接听(被叫端按钮可点击)
|
|
1441
|
+
*/
|
|
1442
|
+
canAccept(): boolean;
|
|
1443
|
+
/**
|
|
1444
|
+
* 当前是否可以拒绝(被叫端按钮可点击)
|
|
1445
|
+
*/
|
|
1446
|
+
canReject(): boolean;
|
|
1447
|
+
/**
|
|
1448
|
+
* 当前是否可以挂断(主叫/被叫端的挂断按钮可点击)
|
|
1449
|
+
*/
|
|
1450
|
+
canHangup(): boolean;
|
|
1451
|
+
/**
|
|
1452
|
+
* 当前是否处于呼叫/响铃中(主叫等待对方接听)
|
|
1453
|
+
*/
|
|
1454
|
+
isCalling(): boolean;
|
|
1455
|
+
isCallIdMatch(incomingCallId: string): boolean;
|
|
1456
|
+
getDuration(): number;
|
|
1457
|
+
/**
|
|
1458
|
+
* 主叫方发起邀请
|
|
1459
|
+
*/
|
|
1460
|
+
initInvite(params: {
|
|
1461
|
+
calleeUserId: string;
|
|
1462
|
+
callType: CALL_TYPE;
|
|
1463
|
+
callerDevId: string;
|
|
1464
|
+
callerUserId: string;
|
|
1465
|
+
callId: string;
|
|
1466
|
+
channel: string;
|
|
1467
|
+
token: string;
|
|
1468
|
+
timeout?: number;
|
|
1469
|
+
}): TransitionResult;
|
|
1470
|
+
/**
|
|
1471
|
+
* 被叫方收到 invite,初始化响铃状态
|
|
1472
|
+
*/
|
|
1473
|
+
initIncoming(params: {
|
|
1474
|
+
callId: string;
|
|
1475
|
+
channel: string;
|
|
1476
|
+
token: string;
|
|
1477
|
+
callType: CALL_TYPE;
|
|
1478
|
+
callerDevId: string;
|
|
1479
|
+
callerUserId: string;
|
|
1480
|
+
calleeDevId: string;
|
|
1481
|
+
calleeUserId: string;
|
|
1482
|
+
}): TransitionResult;
|
|
1483
|
+
/**
|
|
1484
|
+
* 主叫方收到 alert(被叫已响铃)
|
|
1485
|
+
*
|
|
1486
|
+
* 与 lib 对齐:收到 alert 后保持 INVITING 状态不变(lib 的 handleAlertSignalMessage
|
|
1487
|
+
* 不修改 callState.status),只记录 calleeDevId 和发送 confirmRing。
|
|
1488
|
+
* 状态直到收到 confirmRing 后才变为 RECEIVED_CONFIRM_RING。
|
|
1489
|
+
*/
|
|
1490
|
+
receiveAlert(calleeDevId: string): TransitionResult;
|
|
1491
|
+
/**
|
|
1492
|
+
* 被叫方收到 confirmRing
|
|
1493
|
+
*/
|
|
1494
|
+
receiveConfirmRing(status: boolean): TransitionResult;
|
|
1495
|
+
/**
|
|
1496
|
+
* 收到 answerCall 信令
|
|
1497
|
+
*/
|
|
1498
|
+
receiveAnswer(result: 'accept' | 'refuse' | 'busy', fromCaller?: boolean): TransitionResult;
|
|
1499
|
+
/**
|
|
1500
|
+
* 收到 cancelCall 信令
|
|
1501
|
+
*
|
|
1502
|
+
* 注:callId 校验和多端容错由 Handler 负责,状态机只处理匹配后的状态流转。
|
|
1503
|
+
*/
|
|
1504
|
+
receiveCancel(): TransitionResult;
|
|
1505
|
+
/**
|
|
1506
|
+
* 收到 leaveCall 信令
|
|
1507
|
+
*
|
|
1508
|
+
* 注:callId 校验和多端容错由 Handler 负责,状态机只处理匹配后的状态流转。
|
|
1509
|
+
*/
|
|
1510
|
+
receiveLeave(): TransitionResult;
|
|
1511
|
+
/**
|
|
1512
|
+
* 收到 confirmCallee 信令(被叫方)
|
|
1513
|
+
*/
|
|
1514
|
+
receiveConfirmCallee(): TransitionResult;
|
|
1515
|
+
/**
|
|
1516
|
+
* 本地挂断/取消
|
|
1517
|
+
*/
|
|
1518
|
+
hangup(reason?: string): TransitionResult;
|
|
1519
|
+
/**
|
|
1520
|
+
* 邀请超时
|
|
1521
|
+
*/
|
|
1522
|
+
timeout(): TransitionResult;
|
|
1523
|
+
/**
|
|
1524
|
+
* 强制重置状态机
|
|
1525
|
+
*/
|
|
1526
|
+
reset(): void;
|
|
1527
|
+
/**
|
|
1528
|
+
* 启动超时定时器。
|
|
1529
|
+
* 超时后自动调用 onTimeout 回调(由 CallKitCore 注册),确保事件不会被丢弃。
|
|
1530
|
+
*/
|
|
1531
|
+
startTimeout(onTimeout?: (result: TransitionResult) => void): void;
|
|
1532
|
+
private clearTimeout;
|
|
1533
|
+
/**
|
|
1534
|
+
* 核心重置:保留 callerDevId / callerUserId,其余清空
|
|
1535
|
+
* 与现有 callStateStore.resetCallState() 行为一致
|
|
1536
|
+
*/
|
|
1537
|
+
private resetCore;
|
|
1538
|
+
/**
|
|
1539
|
+
* 切换本地音频状态
|
|
1540
|
+
*/
|
|
1541
|
+
toggleAudio(): TransitionResult;
|
|
1542
|
+
/**
|
|
1543
|
+
* 切换本地视频状态
|
|
1544
|
+
*/
|
|
1545
|
+
toggleVideo(): TransitionResult;
|
|
1546
|
+
}
|
|
1547
|
+
|
|
1548
|
+
export declare interface SingleCallTimeoutEvent {
|
|
1549
|
+
type: 'singleCallTimeout';
|
|
1550
|
+
payload: BaseEvent;
|
|
1551
|
+
}
|
|
1552
|
+
|
|
1553
|
+
export declare interface StatusChangedEvent {
|
|
1554
|
+
type: 'statusChanged';
|
|
1555
|
+
payload: BaseEvent & {
|
|
1556
|
+
from: string;
|
|
1557
|
+
to: string;
|
|
1558
|
+
};
|
|
1559
|
+
}
|
|
1560
|
+
|
|
1561
|
+
export declare interface TransitionResult {
|
|
1562
|
+
ok: boolean;
|
|
1563
|
+
events: DomainEvent[];
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
declare type UIEvent_2 = IncomingCallEvent | CallInvitedEvent | CallStartedEvent | CallAcceptedEvent | CallConnectedEvent | CallEndedEvent | CallTimeoutEvent | StatusChangedEvent | CallRefusedEvent | CallBusyEvent | CallCanceledEvent | GroupCallInitEvent | ParticipantStateChangedEvent | ParticipantJoinedEvent | ParticipantLeftEvent | RtcReportEvent | CallDurationUpdatedEvent | CallErrorEvent | SingleCallInvitedEvent | SingleCallStartedEvent | SingleCallAcceptedEvent | SingleCallConnectedEvent | SingleCallEndedEvent | SingleCallTimeoutEvent | SingleCallRefusedEvent | SingleCallBusyEvent | SingleCallCanceledEvent | GroupCallInvitedEvent | GroupCallStartedEvent | GroupCallAcceptedEvent | GroupCallConnectedEvent | GroupCallEndedEvent | GroupCallTimeoutEvent | GroupCallRefusedEvent | GroupCallBusyEvent | GroupCallCanceledEvent;
|
|
1567
|
+
export { UIEvent_2 as UIEvent }
|
|
1568
|
+
|
|
1569
|
+
export declare const VERSION = "1.1.0";
|
|
1570
|
+
|
|
1571
|
+
export { }
|