@coze/realtime-api 1.2.1-beta.9 → 1.3.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.
@@ -0,0 +1,250 @@
1
+ import * as __WEBPACK_EXTERNAL_MODULE__coze_api__ from "@coze/api";
2
+ // WTN服务基础URL
3
+ const WTN_BASE_URL = 'https://wtn.volcvideo.com';
4
+ /**
5
+ * WebRTC资源状态
6
+ */ var live_ResourceStatus = /*#__PURE__*/ function(ResourceStatus) {
7
+ ResourceStatus["IDLE"] = "idle";
8
+ ResourceStatus["CONNECTING"] = "connecting";
9
+ ResourceStatus["CONNECTED"] = "connected";
10
+ ResourceStatus["FAILED"] = "failed";
11
+ ResourceStatus["CLOSING"] = "closing";
12
+ ResourceStatus["CLOSED"] = "closed";
13
+ return ResourceStatus;
14
+ }({});
15
+ /**
16
+ * 同声传译客户端
17
+ */ class WebLiveClient {
18
+ /**
19
+ * 获取当前连接状态
20
+ */ getStatus() {
21
+ return this.status;
22
+ }
23
+ /**
24
+ * 添加状态变化监听器
25
+ * @param callback 状态变化回调函数
26
+ */ onStatusChange(callback) {
27
+ this.statusListeners.push(callback);
28
+ }
29
+ /**
30
+ * 移除状态变化监听器
31
+ * @param callback 要移除的回调函数
32
+ */ offStatusChange(callback) {
33
+ this.removeStatusListener(callback);
34
+ }
35
+ /**
36
+ * 移除状态变化监听器
37
+ * @param callback 要移除的回调函数
38
+ */ removeStatusListener(callback) {
39
+ const index = this.statusListeners.indexOf(callback);
40
+ if (-1 !== index) this.statusListeners.splice(index, 1);
41
+ }
42
+ /**
43
+ * 订阅音频资源
44
+ * @param appId 应用ID
45
+ * @param streamId 流ID
46
+ * @param clientId 客户端ID
47
+ */ async subscribe(appId, streamId) {
48
+ let clientId = arguments.length > 2 && void 0 !== arguments[2] ? arguments[2] : '';
49
+ try {
50
+ var _pc_localDescription;
51
+ // 先清理现有连接
52
+ if (this.peerConnection) {
53
+ this.peerConnection.close();
54
+ this.peerConnection = null;
55
+ }
56
+ this.setStatus("connecting");
57
+ // 1. 创建RTCPeerConnection
58
+ const rtcConfig = {};
59
+ const pc = new RTCPeerConnection(rtcConfig);
60
+ pc.ontrack = (event)=>{
61
+ // 音频流
62
+ this.player.onloadeddata = ()=>{
63
+ this.player.play();
64
+ };
65
+ this.player.srcObject = event.streams[0];
66
+ };
67
+ this.peerConnection = pc;
68
+ this.setupPeerConnectionListeners();
69
+ pc.addTransceiver('audio', {
70
+ direction: 'recvonly'
71
+ });
72
+ // 2. 创建Offer (SDP)
73
+ const offer = await pc.createOffer();
74
+ // 设置本地描述
75
+ await pc.setLocalDescription(offer);
76
+ // 等待ICE收集完成再继续
77
+ await this.waitForIceGathering(pc);
78
+ if (!(null === (_pc_localDescription = pc.localDescription) || void 0 === _pc_localDescription ? void 0 : _pc_localDescription.sdp)) throw new Error('Failed to create SDP offer');
79
+ // 3. 发送Offer到WTN服务订阅资源
80
+ let subscribeUrl = `${WTN_BASE_URL}/sub/${appId}/${streamId}?MuteVideo=true`;
81
+ if (clientId) subscribeUrl += `&clientid=${clientId}`;
82
+ const response = await fetch(subscribeUrl, {
83
+ method: 'POST',
84
+ headers: {
85
+ 'Content-Type': 'application/sdp'
86
+ },
87
+ body: offer.sdp
88
+ });
89
+ if (!response.ok) throw new Error(`HTTP error! status: ${response.status}`);
90
+ // 4. 保存资源URL (用于销毁资源)
91
+ this.resourceUrl = response.headers.get('location') || '';
92
+ // 5. 设置远程SDP (Answer)
93
+ // 直接获取文本响应,因为服务器返回的是application/sdp格式而非json
94
+ const answerSdp = await response.text();
95
+ const answer = new RTCSessionDescription({
96
+ type: 'answer',
97
+ sdp: answerSdp
98
+ });
99
+ await this.peerConnection.setRemoteDescription(answer);
100
+ // 7. 返回结果
101
+ return {
102
+ status: this.status,
103
+ peerConnection: this.peerConnection
104
+ };
105
+ } catch (error) {
106
+ this.status = "failed";
107
+ console.error('Failed to subscribe WebRTC stream:', error);
108
+ return Promise.reject(error);
109
+ }
110
+ }
111
+ /**
112
+ * 销毁订阅资源
113
+ */ async unsubscribe() {
114
+ try {
115
+ // 销毁订阅资源
116
+ if (!this.resourceUrl) throw new Error('No valid subscription resource URL to unsubscribe');
117
+ this.setStatus("closing");
118
+ const response = await fetch(this.resourceUrl, {
119
+ method: 'DELETE'
120
+ });
121
+ if (!response.ok) throw new Error(`Failed to unsubscribe: ${response.status} ${response.statusText}`);
122
+ // 关闭RTC连接
123
+ if (this.peerConnection) {
124
+ this.peerConnection.close();
125
+ this.peerConnection = null;
126
+ }
127
+ this.resourceUrl = '';
128
+ this.status = "closed";
129
+ return true;
130
+ } catch (error) {
131
+ console.error('Error unsubscribing resource:', error);
132
+ this.status = "failed";
133
+ return Promise.reject(error);
134
+ }
135
+ }
136
+ /**
137
+ * 静音/取消静音
138
+ * @param muted 是否静音
139
+ */ setMuted(muted) {
140
+ this.player.muted = muted;
141
+ }
142
+ /**
143
+ * 关闭并清理资源
144
+ */ close() {
145
+ // 关闭PeerConnection
146
+ this.closePeerConnection();
147
+ // Clean up audio element
148
+ if (this.player) {
149
+ this.player.pause();
150
+ this.player.srcObject = null;
151
+ this.player.remove();
152
+ }
153
+ // 重置状态
154
+ this.resourceUrl = '';
155
+ this.setStatus("idle");
156
+ }
157
+ /**
158
+ * 等待ICE收集完成
159
+ * @param pc RTCPeerConnection实例
160
+ */ waitForIceGathering(pc) {
161
+ return new Promise((resolve)=>{
162
+ // 如果已经收集完成,直接返回
163
+ if ('complete' === pc.iceGatheringState) {
164
+ resolve();
165
+ return;
166
+ }
167
+ // 设置收集完成时的回调
168
+ const checkState = ()=>{
169
+ if ('complete' === pc.iceGatheringState) {
170
+ pc.removeEventListener('icegatheringstatechange', checkState);
171
+ resolve();
172
+ }
173
+ };
174
+ // 监听收集状态变化
175
+ pc.addEventListener('icegatheringstatechange', checkState);
176
+ // 添加超时处理,防止永远等待
177
+ setTimeout(()=>resolve(), 5000);
178
+ });
179
+ }
180
+ setupPeerConnectionListeners() {
181
+ if (!this.peerConnection) return;
182
+ this.peerConnection.oniceconnectionstatechange = ()=>{
183
+ var _this_peerConnection, _this_peerConnection1;
184
+ console.log('ICE connection state changed:', null === (_this_peerConnection = this.peerConnection) || void 0 === _this_peerConnection ? void 0 : _this_peerConnection.iceConnectionState);
185
+ switch(null === (_this_peerConnection1 = this.peerConnection) || void 0 === _this_peerConnection1 ? void 0 : _this_peerConnection1.iceConnectionState){
186
+ case 'connected':
187
+ case 'completed':
188
+ this.setStatus("connected");
189
+ break;
190
+ case 'failed':
191
+ case 'disconnected':
192
+ this.setStatus("failed");
193
+ break;
194
+ case 'closed':
195
+ this.setStatus("closed");
196
+ break;
197
+ default:
198
+ var _this_peerConnection2;
199
+ console.log('ICE connection state changed:', null === (_this_peerConnection2 = this.peerConnection) || void 0 === _this_peerConnection2 ? void 0 : _this_peerConnection2.iceConnectionState);
200
+ break;
201
+ }
202
+ };
203
+ this.peerConnection.onicecandidate = (event)=>{
204
+ if (event.candidate) console.log('New ICE candidate:', event.candidate);
205
+ };
206
+ }
207
+ /**
208
+ * 关闭PeerConnection
209
+ */ closePeerConnection() {
210
+ if (this.peerConnection) {
211
+ this.peerConnection.close();
212
+ this.peerConnection = null;
213
+ }
214
+ }
215
+ /**
216
+ * 设置状态并触发监听回调
217
+ * @param newStatus 新状态
218
+ * @private 私有方法,仅内部使用
219
+ */ setStatus(newStatus) {
220
+ const oldStatus = this.status;
221
+ if (oldStatus !== newStatus) {
222
+ this.status = newStatus;
223
+ // 触发所有监听器
224
+ for (const listener of this.statusListeners)try {
225
+ listener(newStatus);
226
+ } catch (error) {
227
+ console.error('Error in status listener:', error);
228
+ }
229
+ }
230
+ }
231
+ constructor(liveId){
232
+ this.peerConnection = null;
233
+ this.resourceUrl = '';
234
+ this.status = "idle";
235
+ this.statusListeners = [];
236
+ /**
237
+ * 获取直播信息
238
+ */ this.getLiveData = async ()=>{
239
+ const api = new __WEBPACK_EXTERNAL_MODULE__coze_api__.CozeAPI({
240
+ baseURL: __WEBPACK_EXTERNAL_MODULE__coze_api__.COZE_CN_BASE_URL,
241
+ token: ''
242
+ });
243
+ return await api.audio.live.retrieve(this.liveId);
244
+ };
245
+ this.setupPeerConnectionListeners();
246
+ this.player = document.createElement('audio');
247
+ this.liveId = liveId;
248
+ }
249
+ }
250
+ export { live_ResourceStatus as ResourceStatus, WebLiveClient };
@@ -148,6 +148,66 @@ declare enum EventNames {
148
148
  * en: Session updated
149
149
  * zh: 会话更新
150
150
  */
151
- SESSION_UPDATED = "server.session.updated"
151
+ SESSION_UPDATED = "server.session.updated",
152
+ /**
153
+ * en: Conversation created
154
+ * zh: 会话创建
155
+ */
156
+ CONVERSATION_CREATED = "server.conversation.created",
157
+ /**
158
+ * en: Conversation chat created
159
+ * zh: 会话对话创建
160
+ */
161
+ CONVERSATION_CHAT_CREATED = "server.conversation.chat.created",
162
+ /**
163
+ * en: Conversation chat in progress
164
+ * zh: 对话正在处理中
165
+ */
166
+ CONVERSATION_CHAT_IN_PROGRESS = "server.conversation.chat.in_progress",
167
+ /**
168
+ * en: Conversation message delta received
169
+ * zh: 文本消息增量返回
170
+ */
171
+ CONVERSATION_MESSAGE_DELTA = "server.conversation.message.delta",
172
+ /**
173
+ * en: Conversation message completed
174
+ * zh: 文本消息完成
175
+ */
176
+ CONVERSATION_MESSAGE_COMPLETED = "server.conversation.message.completed",
177
+ /**
178
+ * en: Conversation chat completed
179
+ * zh: 对话完成
180
+ */
181
+ CONVERSATION_CHAT_COMPLETED = "server.conversation.chat.completed",
182
+ /**
183
+ * en: Conversation chat requires action
184
+ * zh: 对话需要插件
185
+ */
186
+ CONVERSATION_CHAT_REQUIRES_ACTION = "server.conversation.chat.requires_action",
187
+ /**
188
+ * en: Conversation chat failed
189
+ * zh: 对话失败
190
+ */
191
+ CONVERSATION_CHAT_FAILED = "server.conversation.chat.failed",
192
+ /**
193
+ * en: Session pre answer updated
194
+ * zh: 安抚配置更新成功
195
+ */
196
+ SESSION_PRE_ANSWER_UPDATED = "server.session.pre_answer.updated",
197
+ /**
198
+ * en: Conversation audio transcript delta
199
+ * zh: 用户语音识别字幕
200
+ */
201
+ CONVERSATION_AUDIO_TRANSCRIPT_DELTA = "server.conversation.audio_transcript.delta",
202
+ /**
203
+ * en: Mode updated
204
+ * zh: 更新房间模式成功
205
+ */
206
+ MODE_UPDATED = "server.mode.updated",
207
+ /**
208
+ * en: Live created
209
+ * zh: 直播创建
210
+ */
211
+ LIVE_CREATED = "server.live.created"
152
212
  }
153
213
  export default EventNames;
@@ -1,5 +1,5 @@
1
1
  import { type ScreenConfig, type AudioPropertiesConfig, type IRTCEngine } from '@volcengine/rtc';
2
- import { type CreateRoomData, type GetToken, type RoomMode } from '@coze/api';
2
+ import { RoomMode, type CreateRoomData, type GetToken, type TranslateConfig } from '@coze/api';
3
3
  import * as RealtimeUtils from './utils';
4
4
  import EventNames from './event-names';
5
5
  import { RealtimeEventHandler } from './event-handler';
@@ -32,6 +32,7 @@ export interface RealtimeClientConfig {
32
32
  isAutoSubscribeAudio?: boolean /** optional, Whether to automatically subscribe to bot reply audio streams, defaults to true */;
33
33
  prologueContent?: string /** optional, Prologue content */;
34
34
  roomMode?: RoomMode /** optional, Room mode */;
35
+ translateConfig?: TranslateConfig /** optional, Translation configuration */;
35
36
  }
36
37
  declare class RealtimeClient extends RealtimeEventHandler {
37
38
  _config: RealtimeClientConfig;
@@ -0,0 +1,86 @@
1
+ /**
2
+ * WebRTC资源状态
3
+ */
4
+ export declare enum ResourceStatus {
5
+ IDLE = "idle",// 初始状态
6
+ CONNECTING = "connecting",// 连接中
7
+ CONNECTED = "connected",// 已连接
8
+ FAILED = "failed",// 连接失败
9
+ CLOSING = "closing",// 关闭中
10
+ CLOSED = "closed"
11
+ }
12
+ export type StatusChangeCallback = (status: ResourceStatus) => void;
13
+ /**
14
+ * 同声传译客户端
15
+ */
16
+ export declare class WebLiveClient {
17
+ private peerConnection;
18
+ private resourceUrl;
19
+ private status;
20
+ private player;
21
+ private statusListeners;
22
+ private liveId;
23
+ constructor(liveId: string);
24
+ /**
25
+ * 获取当前连接状态
26
+ */
27
+ getStatus(): ResourceStatus;
28
+ /**
29
+ * 添加状态变化监听器
30
+ * @param callback 状态变化回调函数
31
+ */
32
+ onStatusChange(callback: StatusChangeCallback): void;
33
+ /**
34
+ * 移除状态变化监听器
35
+ * @param callback 要移除的回调函数
36
+ */
37
+ offStatusChange(callback: StatusChangeCallback): void;
38
+ /**
39
+ * 移除状态变化监听器
40
+ * @param callback 要移除的回调函数
41
+ */
42
+ removeStatusListener(callback: StatusChangeCallback): void;
43
+ /**
44
+ * 订阅音频资源
45
+ * @param appId 应用ID
46
+ * @param streamId 流ID
47
+ * @param clientId 客户端ID
48
+ */
49
+ subscribe(appId: string, streamId: string, clientId?: string): Promise<{
50
+ status: ResourceStatus;
51
+ peerConnection: RTCPeerConnection;
52
+ }>;
53
+ /**
54
+ * 销毁订阅资源
55
+ */
56
+ unsubscribe(): Promise<boolean>;
57
+ /**
58
+ * 静音/取消静音
59
+ * @param muted 是否静音
60
+ */
61
+ setMuted(muted: boolean): void;
62
+ /**
63
+ * 关闭并清理资源
64
+ */
65
+ close(): void;
66
+ /**
67
+ * 获取直播信息
68
+ */
69
+ getLiveData: () => Promise<import("@coze/api").RetrieveLiveData>;
70
+ /**
71
+ * 等待ICE收集完成
72
+ * @param pc RTCPeerConnection实例
73
+ */
74
+ private waitForIceGathering;
75
+ private setupPeerConnectionListeners;
76
+ /**
77
+ * 关闭PeerConnection
78
+ */
79
+ private closePeerConnection;
80
+ /**
81
+ * 设置状态并触发监听回调
82
+ * @param newStatus 新状态
83
+ * @private 私有方法,仅内部使用
84
+ */
85
+ private setStatus;
86
+ }
@@ -148,6 +148,66 @@ declare enum EventNames {
148
148
  * en: Session updated
149
149
  * zh: 会话更新
150
150
  */
151
- SESSION_UPDATED = "server.session.updated"
151
+ SESSION_UPDATED = "server.session.updated",
152
+ /**
153
+ * en: Conversation created
154
+ * zh: 会话创建
155
+ */
156
+ CONVERSATION_CREATED = "server.conversation.created",
157
+ /**
158
+ * en: Conversation chat created
159
+ * zh: 会话对话创建
160
+ */
161
+ CONVERSATION_CHAT_CREATED = "server.conversation.chat.created",
162
+ /**
163
+ * en: Conversation chat in progress
164
+ * zh: 对话正在处理中
165
+ */
166
+ CONVERSATION_CHAT_IN_PROGRESS = "server.conversation.chat.in_progress",
167
+ /**
168
+ * en: Conversation message delta received
169
+ * zh: 文本消息增量返回
170
+ */
171
+ CONVERSATION_MESSAGE_DELTA = "server.conversation.message.delta",
172
+ /**
173
+ * en: Conversation message completed
174
+ * zh: 文本消息完成
175
+ */
176
+ CONVERSATION_MESSAGE_COMPLETED = "server.conversation.message.completed",
177
+ /**
178
+ * en: Conversation chat completed
179
+ * zh: 对话完成
180
+ */
181
+ CONVERSATION_CHAT_COMPLETED = "server.conversation.chat.completed",
182
+ /**
183
+ * en: Conversation chat requires action
184
+ * zh: 对话需要插件
185
+ */
186
+ CONVERSATION_CHAT_REQUIRES_ACTION = "server.conversation.chat.requires_action",
187
+ /**
188
+ * en: Conversation chat failed
189
+ * zh: 对话失败
190
+ */
191
+ CONVERSATION_CHAT_FAILED = "server.conversation.chat.failed",
192
+ /**
193
+ * en: Session pre answer updated
194
+ * zh: 安抚配置更新成功
195
+ */
196
+ SESSION_PRE_ANSWER_UPDATED = "server.session.pre_answer.updated",
197
+ /**
198
+ * en: Conversation audio transcript delta
199
+ * zh: 用户语音识别字幕
200
+ */
201
+ CONVERSATION_AUDIO_TRANSCRIPT_DELTA = "server.conversation.audio_transcript.delta",
202
+ /**
203
+ * en: Mode updated
204
+ * zh: 更新房间模式成功
205
+ */
206
+ MODE_UPDATED = "server.mode.updated",
207
+ /**
208
+ * en: Live created
209
+ * zh: 直播创建
210
+ */
211
+ LIVE_CREATED = "server.live.created"
152
212
  }
153
213
  export default EventNames;
@@ -1,5 +1,5 @@
1
1
  import { type ScreenConfig, type AudioPropertiesConfig, type IRTCEngine } from '@volcengine/rtc';
2
- import { type CreateRoomData, type GetToken, type RoomMode } from '@coze/api';
2
+ import { RoomMode, type CreateRoomData, type GetToken, type TranslateConfig } from '@coze/api';
3
3
  import * as RealtimeUtils from './utils';
4
4
  import EventNames from './event-names';
5
5
  import { RealtimeEventHandler } from './event-handler';
@@ -32,6 +32,7 @@ export interface RealtimeClientConfig {
32
32
  isAutoSubscribeAudio?: boolean /** optional, Whether to automatically subscribe to bot reply audio streams, defaults to true */;
33
33
  prologueContent?: string /** optional, Prologue content */;
34
34
  roomMode?: RoomMode /** optional, Room mode */;
35
+ translateConfig?: TranslateConfig /** optional, Translation configuration */;
35
36
  }
36
37
  declare class RealtimeClient extends RealtimeEventHandler {
37
38
  _config: RealtimeClientConfig;
@@ -0,0 +1,49 @@
1
+ import { type AudioPropertiesConfig, type IRTCEngine, type NetworkQuality, type onUserJoinedEvent, type onUserLeaveEvent, type UserMessageEvent } from '@volcengine/rtc';
2
+ import { RealtimeEventHandler } from './event-handler';
3
+ import { type VideoConfig } from '.';
4
+ export declare class EngineClient extends RealtimeEventHandler {
5
+ private engine;
6
+ private joinUserId;
7
+ private _AIAnsExtension;
8
+ private _isSupportVideo;
9
+ private _videoConfig?;
10
+ private _streamIndex?;
11
+ private _roomUserId?;
12
+ constructor(appId: string, debug?: boolean, isTestEnv?: boolean, isSupportVideo?: boolean, videoConfig?: VideoConfig);
13
+ bindEngineEvents(): void;
14
+ removeEventListener(): void;
15
+ _parseMessage(event: UserMessageEvent): any;
16
+ handleMessage(event: UserMessageEvent): void;
17
+ handleEventError(e: unknown): void;
18
+ handleUserJoin(event: onUserJoinedEvent): void;
19
+ handleUserLeave(event: onUserLeaveEvent): void;
20
+ handlePlayerEvent(event: unknown): void;
21
+ handleNetworkQuality(uplinkNetworkQuality: NetworkQuality, downlinkNetworkQuality: NetworkQuality): void;
22
+ handleTrackEnded(event: any): void;
23
+ joinRoom(options: {
24
+ token: string;
25
+ roomId: string;
26
+ uid: string;
27
+ audioMutedDefault?: boolean;
28
+ videoOnDefault?: boolean;
29
+ isAutoSubscribeAudio?: boolean;
30
+ }): Promise<void>;
31
+ setAudioInputDevice(deviceId: string): Promise<void>;
32
+ setAudioOutputDevice(deviceId: string): Promise<void>;
33
+ setVideoInputDevice(deviceId: string, isAutoCapture?: boolean): Promise<void>;
34
+ createLocalStream(userId?: string, videoConfig?: VideoConfig): Promise<void>;
35
+ disconnect(): Promise<void>;
36
+ changeAudioState(isMicOn: boolean): Promise<void>;
37
+ changeVideoState(isVideoOn: boolean): Promise<void>;
38
+ stop(): Promise<void>;
39
+ sendMessage(message: Record<string, unknown>): Promise<void>;
40
+ enableAudioPropertiesReport(config?: AudioPropertiesConfig): void;
41
+ handleLocalAudioPropertiesReport(event: any): void;
42
+ handleRemoteAudioPropertiesReport(event: unknown): void;
43
+ enableAudioNoiseReduction(): Promise<void>;
44
+ initAIAnsExtension(): Promise<void>;
45
+ changeAIAnsExtension(enable: boolean): void;
46
+ startAudioPlaybackDeviceTest(): Promise<void>;
47
+ stopAudioPlaybackDeviceTest(): void;
48
+ getRtcEngine(): IRTCEngine;
49
+ }
@@ -0,0 +1,25 @@
1
+ export declare enum RealtimeError {
2
+ DEVICE_ACCESS_ERROR = "DEVICE_ACCESS_ERROR",
3
+ STREAM_CREATION_ERROR = "STREAM_CREATION_ERROR",
4
+ CONNECTION_ERROR = "CONNECTION_ERROR",
5
+ DISCONNECTION_ERROR = "DISCONNECTION_ERROR",
6
+ INTERRUPT_ERROR = "INTERRUPT_ERROR",
7
+ EVENT_HANDLER_ERROR = "EVENT_HANDLER_ERROR",
8
+ PERMISSION_DENIED = "PERMISSION_DENIED",
9
+ NETWORK_ERROR = "NETWORK_ERROR",
10
+ INVALID_STATE = "INVALID_STATE",
11
+ CREATE_ROOM_ERROR = "CREATE_ROOM_ERROR",
12
+ PARSE_MESSAGE_ERROR = "PARSE_MESSAGE_ERROR",
13
+ HANDLER_MESSAGE_ERROR = "HANDLER_MESSAGE_ERROR"
14
+ }
15
+ export declare const ErrorMessages: Record<RealtimeError, string>;
16
+ export declare class RealtimeAPIError extends Error {
17
+ code: RealtimeError;
18
+ error?: unknown;
19
+ /**
20
+ * @param code - Error code
21
+ * @param message - Error message
22
+ * @param error - Error object
23
+ */
24
+ constructor(code: RealtimeError, message: string, error?: unknown);
25
+ }
@@ -0,0 +1,12 @@
1
+ export type EventCallback = (eventName: string, event: unknown) => void;
2
+ export declare class RealtimeEventHandler {
3
+ private eventHandlers;
4
+ protected _debug: boolean;
5
+ constructor(debug?: boolean);
6
+ clearEventHandlers(): void;
7
+ on(eventName: string, callback: EventCallback): EventCallback;
8
+ off(eventName: string, callback: EventCallback): void;
9
+ private _dispatchToHandlers;
10
+ dispatch(eventName: string, event: unknown, consoleLog?: boolean): void;
11
+ _log(message: string, event?: unknown): void;
12
+ }