@ermis-network/ermis-chat-sdk 1.0.0
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 +0 -0
- package/dist/index.browser.cjs +7318 -0
- package/dist/index.browser.cjs.map +1 -0
- package/dist/index.browser.full-bundle.min.js +48 -0
- package/dist/index.browser.full-bundle.min.js.map +1 -0
- package/dist/index.browser.mjs +7257 -0
- package/dist/index.browser.mjs.map +1 -0
- package/dist/index.cjs +7317 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.mts +1469 -0
- package/dist/index.d.ts +1469 -0
- package/dist/index.mjs +7256 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +64 -0
- package/src/attachment_utils.ts +148 -0
- package/src/auth.ts +352 -0
- package/src/channel.ts +1704 -0
- package/src/channel_state.ts +580 -0
- package/src/client.ts +1343 -0
- package/src/client_state.ts +55 -0
- package/src/connection.ts +587 -0
- package/src/ermis_call_node.ts +948 -0
- package/src/errors.ts +60 -0
- package/src/events.ts +46 -0
- package/src/hevc_decoder_config.ts +305 -0
- package/src/index.ts +15 -0
- package/src/media_stream_receiver.ts +525 -0
- package/src/media_stream_sender.ts +400 -0
- package/src/shims/empty.ts +1 -0
- package/src/signal_message.ts +96 -0
- package/src/system_message.ts +117 -0
- package/src/token_manager.ts +48 -0
- package/src/types.ts +567 -0
- package/src/utils.ts +534 -0
- package/src/wasm/ermis_call_node_wasm.d.ts +154 -0
- package/src/wasm/ermis_call_node_wasm.js +1498 -0
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,1469 @@
|
|
|
1
|
+
import { AxiosRequestConfig, AxiosResponse, AxiosInstance } from 'axios';
|
|
2
|
+
import WebSocket from 'isomorphic-ws';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* StableWSConnection - A WS connection that reconnects upon failure.
|
|
6
|
+
* - the browser will sometimes report that you're online or offline
|
|
7
|
+
* - the WS connection can break and fail (there is a 30s health check)
|
|
8
|
+
* - sometimes your WS connection will seem to work while the user is in fact offline
|
|
9
|
+
* - to speed up online/offline detection you can use the window.addEventListener('offline');
|
|
10
|
+
*
|
|
11
|
+
* There are 4 ways in which a connection can become unhealthy:
|
|
12
|
+
* - websocket.onerror is called
|
|
13
|
+
* - websocket.onclose is called
|
|
14
|
+
* - the health check fails and no event is received for ~40 seconds
|
|
15
|
+
* - the browser indicates the connection is now offline
|
|
16
|
+
*
|
|
17
|
+
* There are 2 assumptions we make about the server:
|
|
18
|
+
* - state can be recovered by querying the channel again
|
|
19
|
+
* - if the servers fails to publish a message to the client, the WS connection is destroyed
|
|
20
|
+
*/
|
|
21
|
+
declare class StableWSConnection<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
22
|
+
client: ErmisChat<ErmisChatGenerics>;
|
|
23
|
+
connectionOpen?: ConnectAPIResponse<ErmisChatGenerics>;
|
|
24
|
+
consecutiveFailures: number;
|
|
25
|
+
pingInterval: number;
|
|
26
|
+
healthCheckTimeoutRef?: NodeJS.Timeout;
|
|
27
|
+
isConnecting: boolean;
|
|
28
|
+
isDisconnected: boolean;
|
|
29
|
+
isHealthy: boolean;
|
|
30
|
+
isResolved?: boolean;
|
|
31
|
+
lastEvent: Date | null;
|
|
32
|
+
connectionCheckTimeout: number;
|
|
33
|
+
connectionCheckTimeoutRef?: NodeJS.Timeout;
|
|
34
|
+
rejectPromise?: (reason?: Error & {
|
|
35
|
+
code?: string | number;
|
|
36
|
+
isWSFailure?: boolean;
|
|
37
|
+
StatusCode?: string | number;
|
|
38
|
+
}) => void;
|
|
39
|
+
requestID: string | undefined;
|
|
40
|
+
resolvePromise?: (value: ConnectionOpen<ErmisChatGenerics>) => void;
|
|
41
|
+
totalFailures: number;
|
|
42
|
+
ws?: WebSocket;
|
|
43
|
+
wsID: number;
|
|
44
|
+
constructor({ client }: {
|
|
45
|
+
client: ErmisChat<ErmisChatGenerics>;
|
|
46
|
+
});
|
|
47
|
+
_log(msg: string, extra?: UR, level?: LogLevel): void;
|
|
48
|
+
setClient(client: ErmisChat<ErmisChatGenerics>): void;
|
|
49
|
+
connect(timeout?: number): Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
50
|
+
/**
|
|
51
|
+
* _waitForHealthy polls the promise connection to see if its resolved until it times out
|
|
52
|
+
* the default 15s timeout allows between 2~3 tries
|
|
53
|
+
* @param timeout duration(ms)
|
|
54
|
+
*/
|
|
55
|
+
_waitForHealthy(timeout?: number): Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
56
|
+
/**
|
|
57
|
+
* Builds and returns the url for websocket.
|
|
58
|
+
* @private
|
|
59
|
+
* @returns url string
|
|
60
|
+
*/
|
|
61
|
+
_buildUrl: () => string;
|
|
62
|
+
/**
|
|
63
|
+
* disconnect - Disconnect the connection and doesn't recover...
|
|
64
|
+
*
|
|
65
|
+
*/
|
|
66
|
+
disconnect(timeout?: number): Promise<void>;
|
|
67
|
+
_connect(): Promise<ConnectionOpen<ErmisChatGenerics> | undefined>;
|
|
68
|
+
/**
|
|
69
|
+
* _reconnect - Retry the connection to WS endpoint
|
|
70
|
+
*
|
|
71
|
+
* @param {{ interval?: number; refreshToken?: boolean }} options Following options are available
|
|
72
|
+
*
|
|
73
|
+
* - `interval` {int} number of ms that function should wait before reconnecting
|
|
74
|
+
* - `refreshToken` {boolean} reload/refresh user token be refreshed before attempting reconnection.
|
|
75
|
+
*/
|
|
76
|
+
_reconnect(options?: {
|
|
77
|
+
interval?: number;
|
|
78
|
+
refreshToken?: boolean;
|
|
79
|
+
}): Promise<void>;
|
|
80
|
+
/**
|
|
81
|
+
* onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.
|
|
82
|
+
*
|
|
83
|
+
* @param {Event} event Event with type online or offline
|
|
84
|
+
*
|
|
85
|
+
*/
|
|
86
|
+
onlineStatusChanged: (event: Event) => void;
|
|
87
|
+
onopen: (wsID: number) => void;
|
|
88
|
+
onmessage: (wsID: number, event: WebSocket.MessageEvent) => void;
|
|
89
|
+
onclose: (wsID: number, event: WebSocket.CloseEvent) => void;
|
|
90
|
+
onerror: (wsID: number, event: WebSocket.ErrorEvent) => void;
|
|
91
|
+
/**
|
|
92
|
+
* _setHealth - Sets the connection to healthy or unhealthy.
|
|
93
|
+
* Broadcasts an event in case the connection status changed.
|
|
94
|
+
*
|
|
95
|
+
* @param {boolean} healthy boolean indicating if the connection is healthy or not
|
|
96
|
+
*
|
|
97
|
+
*/
|
|
98
|
+
_setHealth: (healthy: boolean) => void;
|
|
99
|
+
/**
|
|
100
|
+
* _errorFromWSEvent - Creates an error object for the WS event
|
|
101
|
+
*
|
|
102
|
+
*/
|
|
103
|
+
_errorFromWSEvent: (event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent, isWSFailure?: boolean) => Error & {
|
|
104
|
+
code?: string | number;
|
|
105
|
+
isWSFailure?: boolean;
|
|
106
|
+
StatusCode?: string | number;
|
|
107
|
+
};
|
|
108
|
+
/**
|
|
109
|
+
* _destroyCurrentWSConnection - Removes the current WS connection
|
|
110
|
+
*
|
|
111
|
+
*/
|
|
112
|
+
_destroyCurrentWSConnection(): void;
|
|
113
|
+
/**
|
|
114
|
+
* _setupPromise - sets up the this.connectOpen promise
|
|
115
|
+
*/
|
|
116
|
+
_setupConnectionPromise: () => void;
|
|
117
|
+
/**
|
|
118
|
+
* Schedules a next health check ping for websocket.
|
|
119
|
+
*/
|
|
120
|
+
scheduleNextPing: () => void;
|
|
121
|
+
/**
|
|
122
|
+
* scheduleConnectionCheck - schedules a check for time difference between last received event and now.
|
|
123
|
+
* If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs
|
|
124
|
+
* to be reconnected.
|
|
125
|
+
*/
|
|
126
|
+
scheduleConnectionCheck: () => void;
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
declare const EVENT_MAP: {
|
|
130
|
+
'channel.created': boolean;
|
|
131
|
+
'channel.deleted': boolean;
|
|
132
|
+
'channel.truncate': boolean;
|
|
133
|
+
'channel.updated': boolean;
|
|
134
|
+
'channel.pinned': boolean;
|
|
135
|
+
'channel.unpinned': boolean;
|
|
136
|
+
'health.check': boolean;
|
|
137
|
+
'member.added': boolean;
|
|
138
|
+
'member.removed': boolean;
|
|
139
|
+
'member.updated': boolean;
|
|
140
|
+
'member.joined': boolean;
|
|
141
|
+
'member.promoted': boolean;
|
|
142
|
+
'member.demoted': boolean;
|
|
143
|
+
'member.banned': boolean;
|
|
144
|
+
'member.unbanned': boolean;
|
|
145
|
+
'member.blocked': boolean;
|
|
146
|
+
'member.unblocked': boolean;
|
|
147
|
+
'message.deleted': boolean;
|
|
148
|
+
'message.deleted_for_me': boolean;
|
|
149
|
+
'message.new': boolean;
|
|
150
|
+
'message.read': boolean;
|
|
151
|
+
'message.updated': boolean;
|
|
152
|
+
'message.pinned': boolean;
|
|
153
|
+
'message.unpinned': boolean;
|
|
154
|
+
'notification.channel_deleted': boolean;
|
|
155
|
+
'notification.invite_accepted': boolean;
|
|
156
|
+
'notification.invite_rejected': boolean;
|
|
157
|
+
'notification.invite_messaging_skipped': boolean;
|
|
158
|
+
'pollchoice.new': boolean;
|
|
159
|
+
'reaction.deleted': boolean;
|
|
160
|
+
'reaction.new': boolean;
|
|
161
|
+
'typing.start': boolean;
|
|
162
|
+
'typing.stop': boolean;
|
|
163
|
+
'user.watching.start': boolean;
|
|
164
|
+
'user.watching.stop': boolean;
|
|
165
|
+
'connection.changed': boolean;
|
|
166
|
+
'connection.recovered': boolean;
|
|
167
|
+
'capabilities.changed': boolean;
|
|
168
|
+
'channel.topic.disabled': boolean;
|
|
169
|
+
'channel.topic.enabled': boolean;
|
|
170
|
+
'channel.topic.created': boolean;
|
|
171
|
+
'channel.topic.closed': boolean;
|
|
172
|
+
'channel.topic.reopen': boolean;
|
|
173
|
+
'channel.topic.updated': boolean;
|
|
174
|
+
};
|
|
175
|
+
|
|
176
|
+
type Role = 'owner' | 'moder' | 'member' | 'pending' | 'skipped' | string;
|
|
177
|
+
type UR = Record<string, unknown>;
|
|
178
|
+
type DefaultGenerics = {
|
|
179
|
+
attachmentType: UR;
|
|
180
|
+
channelType: UR;
|
|
181
|
+
commandType: LiteralStringForUnion;
|
|
182
|
+
eventType: UR;
|
|
183
|
+
messageType: UR;
|
|
184
|
+
pollOptionType: UR;
|
|
185
|
+
pollType: UR;
|
|
186
|
+
reactionType: UR;
|
|
187
|
+
userType: UR;
|
|
188
|
+
};
|
|
189
|
+
type ExtendableGenerics = {
|
|
190
|
+
attachmentType: UR;
|
|
191
|
+
channelType: UR;
|
|
192
|
+
commandType: string;
|
|
193
|
+
eventType: UR;
|
|
194
|
+
messageType: UR;
|
|
195
|
+
pollOptionType: UR;
|
|
196
|
+
pollType: UR;
|
|
197
|
+
reactionType: UR;
|
|
198
|
+
userType: UR;
|
|
199
|
+
};
|
|
200
|
+
/**
|
|
201
|
+
* Response Types
|
|
202
|
+
*/
|
|
203
|
+
type APIResponse = {
|
|
204
|
+
duration?: string;
|
|
205
|
+
};
|
|
206
|
+
type ChannelResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['channelType'] & {
|
|
207
|
+
cid: string;
|
|
208
|
+
id: string;
|
|
209
|
+
type: string;
|
|
210
|
+
created_at?: string;
|
|
211
|
+
created_by?: UserResponse<ErmisChatGenerics> | null;
|
|
212
|
+
deleted_at?: string;
|
|
213
|
+
last_message_at?: string;
|
|
214
|
+
member_count?: number;
|
|
215
|
+
members: ChannelMemberResponse<ErmisChatGenerics>[];
|
|
216
|
+
name?: string;
|
|
217
|
+
own_capabilities?: string[];
|
|
218
|
+
updated_at?: string;
|
|
219
|
+
image?: string;
|
|
220
|
+
description?: string;
|
|
221
|
+
member_message_cooldown?: number;
|
|
222
|
+
member_capabilities?: string[];
|
|
223
|
+
is_pinned?: boolean;
|
|
224
|
+
topics_enabled?: boolean;
|
|
225
|
+
is_closed_topic?: boolean;
|
|
226
|
+
};
|
|
227
|
+
type QueryChannelsAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
228
|
+
channels: Omit<ChannelAPIResponse<ErmisChatGenerics>, keyof APIResponse>[];
|
|
229
|
+
};
|
|
230
|
+
type QueryChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & ChannelAPIResponse<ErmisChatGenerics>;
|
|
231
|
+
type ChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
232
|
+
channel: ChannelResponse<ErmisChatGenerics>;
|
|
233
|
+
members: ChannelMemberResponse<ErmisChatGenerics>[];
|
|
234
|
+
messages: MessageResponse<ErmisChatGenerics>[];
|
|
235
|
+
pinned_messages: MessageResponse<ErmisChatGenerics>[];
|
|
236
|
+
membership?: ChannelMembership<ErmisChatGenerics> | null;
|
|
237
|
+
read?: ReadResponse<ErmisChatGenerics>[];
|
|
238
|
+
topics?: QueryChannelAPIResponse<ErmisChatGenerics>[];
|
|
239
|
+
watcher_count?: number;
|
|
240
|
+
watchers?: UserResponse<ErmisChatGenerics>[];
|
|
241
|
+
is_pinned?: boolean;
|
|
242
|
+
};
|
|
243
|
+
type ChannelMemberResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
244
|
+
banned?: boolean;
|
|
245
|
+
blocked?: boolean;
|
|
246
|
+
channel_role?: Role;
|
|
247
|
+
created_at?: string;
|
|
248
|
+
updated_at?: string;
|
|
249
|
+
user?: UserResponse<ErmisChatGenerics>;
|
|
250
|
+
user_id?: string;
|
|
251
|
+
};
|
|
252
|
+
type ConnectAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
253
|
+
type FormatMessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<MessageResponse<{
|
|
254
|
+
attachmentType: ErmisChatGenerics['attachmentType'];
|
|
255
|
+
channelType: ErmisChatGenerics['channelType'];
|
|
256
|
+
commandType: ErmisChatGenerics['commandType'];
|
|
257
|
+
eventType: ErmisChatGenerics['eventType'];
|
|
258
|
+
messageType: {};
|
|
259
|
+
pollOptionType: ErmisChatGenerics['pollOptionType'];
|
|
260
|
+
pollType: ErmisChatGenerics['pollType'];
|
|
261
|
+
reactionType: ErmisChatGenerics['reactionType'];
|
|
262
|
+
userType: ErmisChatGenerics['userType'];
|
|
263
|
+
}>, 'created_at' | 'pinned_at' | 'updated_at' | 'status'> & ErmisChatGenerics['messageType'] & {
|
|
264
|
+
created_at: Date;
|
|
265
|
+
pinned_at: Date | null;
|
|
266
|
+
status: string;
|
|
267
|
+
updated_at: Date;
|
|
268
|
+
};
|
|
269
|
+
type MessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = MessageResponseBase<ErmisChatGenerics> & {
|
|
270
|
+
quoted_message?: MessageResponseBase<ErmisChatGenerics>;
|
|
271
|
+
};
|
|
272
|
+
type MessageResponseBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = MessageBase<ErmisChatGenerics> & {
|
|
273
|
+
type: MessageLabel;
|
|
274
|
+
channel?: ChannelResponse<ErmisChatGenerics>;
|
|
275
|
+
cid?: string;
|
|
276
|
+
created_at?: string;
|
|
277
|
+
deleted_at?: string;
|
|
278
|
+
latest_reactions?: ReactionResponse<ErmisChatGenerics>[];
|
|
279
|
+
mentioned_users?: string[];
|
|
280
|
+
own_reactions?: ReactionResponse<ErmisChatGenerics>[] | null;
|
|
281
|
+
pinned_at?: string | null;
|
|
282
|
+
pinned_by?: UserResponse<ErmisChatGenerics> | null;
|
|
283
|
+
reaction_counts?: {
|
|
284
|
+
[key: string]: number;
|
|
285
|
+
} | null;
|
|
286
|
+
reaction_scores?: {
|
|
287
|
+
[key: string]: number;
|
|
288
|
+
} | null;
|
|
289
|
+
reply_count?: number;
|
|
290
|
+
status?: string;
|
|
291
|
+
updated_at?: string;
|
|
292
|
+
};
|
|
293
|
+
type ReactionAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
294
|
+
message: MessageResponse<ErmisChatGenerics>;
|
|
295
|
+
reaction: ReactionResponse<ErmisChatGenerics>;
|
|
296
|
+
};
|
|
297
|
+
type ReactionResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Reaction<ErmisChatGenerics> & {
|
|
298
|
+
created_at: string;
|
|
299
|
+
message_id: string;
|
|
300
|
+
updated_at: string;
|
|
301
|
+
};
|
|
302
|
+
type ReadResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
303
|
+
last_read: string;
|
|
304
|
+
user: UserResponse<ErmisChatGenerics>;
|
|
305
|
+
last_read_message_id?: string;
|
|
306
|
+
unread_messages?: number;
|
|
307
|
+
last_send?: string;
|
|
308
|
+
};
|
|
309
|
+
type SendFileAPIResponse = APIResponse & {
|
|
310
|
+
file: string;
|
|
311
|
+
thumb_url?: string;
|
|
312
|
+
};
|
|
313
|
+
type SendMessageAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
314
|
+
message: MessageResponse<ErmisChatGenerics>;
|
|
315
|
+
};
|
|
316
|
+
type UpdateChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
317
|
+
channel: ChannelResponse<ErmisChatGenerics>;
|
|
318
|
+
members: ChannelMemberResponse<ErmisChatGenerics>[];
|
|
319
|
+
message?: MessageResponse<ErmisChatGenerics>;
|
|
320
|
+
};
|
|
321
|
+
type UserResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['userType'] & {
|
|
322
|
+
id: string;
|
|
323
|
+
name?: string;
|
|
324
|
+
avatar?: string;
|
|
325
|
+
about_me?: string;
|
|
326
|
+
project_id?: string;
|
|
327
|
+
email?: string;
|
|
328
|
+
phone?: string;
|
|
329
|
+
};
|
|
330
|
+
type Contact = {
|
|
331
|
+
project_id: string;
|
|
332
|
+
user_id: string;
|
|
333
|
+
other_id: string;
|
|
334
|
+
relation_status: string;
|
|
335
|
+
created_at: string;
|
|
336
|
+
updated_at: string;
|
|
337
|
+
};
|
|
338
|
+
type ContactResponse = APIResponse & {
|
|
339
|
+
project_id_user_ids: {
|
|
340
|
+
[key: string]: Contact[];
|
|
341
|
+
};
|
|
342
|
+
};
|
|
343
|
+
type ContactResult<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
344
|
+
contact_users: UserResponse<ErmisChatGenerics>[];
|
|
345
|
+
block_users: UserResponse<ErmisChatGenerics>[];
|
|
346
|
+
};
|
|
347
|
+
type ChannelQueryOptions = {
|
|
348
|
+
messages?: {
|
|
349
|
+
limit?: number;
|
|
350
|
+
id_lt?: string;
|
|
351
|
+
id_gt?: string;
|
|
352
|
+
id_around?: string;
|
|
353
|
+
};
|
|
354
|
+
};
|
|
355
|
+
type ChannelStateOptions = {
|
|
356
|
+
offlineMode?: boolean;
|
|
357
|
+
skipInitialization?: string[];
|
|
358
|
+
};
|
|
359
|
+
type ErmisChatOptions = AxiosRequestConfig & {
|
|
360
|
+
/**
|
|
361
|
+
* Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.
|
|
362
|
+
*/
|
|
363
|
+
allowServerSideConnect?: boolean;
|
|
364
|
+
axiosRequestConfig?: AxiosRequestConfig;
|
|
365
|
+
/**
|
|
366
|
+
* Base url for User BE API (uss/v1). Defaults to baseURL + '/uss/v1' if not provided.
|
|
367
|
+
*/
|
|
368
|
+
userBaseURL?: string;
|
|
369
|
+
browser?: boolean;
|
|
370
|
+
enableInsights?: boolean;
|
|
371
|
+
/** experimental feature, please contact support if you want this feature enabled for you */
|
|
372
|
+
logger?: Logger;
|
|
373
|
+
/**
|
|
374
|
+
* When network is recovered, we re-query the active channels on client. But in single query, you can recover
|
|
375
|
+
* only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.
|
|
376
|
+
* Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.
|
|
377
|
+
*
|
|
378
|
+
* `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.
|
|
379
|
+
* When false, user/consumer of this client will need to make sure all the channels present on UI by
|
|
380
|
+
* manually calling queryChannels endpoint.
|
|
381
|
+
*/
|
|
382
|
+
recoverStateOnReconnect?: boolean;
|
|
383
|
+
warmUp?: boolean;
|
|
384
|
+
wsConnection?: StableWSConnection;
|
|
385
|
+
};
|
|
386
|
+
/**
|
|
387
|
+
* Event Types
|
|
388
|
+
*/
|
|
389
|
+
type Event$1<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['eventType'] & {
|
|
390
|
+
type: EventTypes;
|
|
391
|
+
channel?: ChannelResponse<ErmisChatGenerics>;
|
|
392
|
+
channel_id?: string;
|
|
393
|
+
channel_type?: string;
|
|
394
|
+
cid?: string;
|
|
395
|
+
created_at?: string;
|
|
396
|
+
hard_delete?: boolean;
|
|
397
|
+
last_read_at?: string;
|
|
398
|
+
last_read_message_id?: string;
|
|
399
|
+
me?: UserResponse<ErmisChatGenerics>;
|
|
400
|
+
member?: ChannelMemberResponse<ErmisChatGenerics>;
|
|
401
|
+
message?: MessageResponse<ErmisChatGenerics>;
|
|
402
|
+
online?: boolean;
|
|
403
|
+
parent_id?: string;
|
|
404
|
+
reaction?: ReactionResponse<ErmisChatGenerics>;
|
|
405
|
+
received_at?: string | Date;
|
|
406
|
+
unread_messages?: number;
|
|
407
|
+
user?: UserResponse<ErmisChatGenerics>;
|
|
408
|
+
user_id?: string;
|
|
409
|
+
watcher_count?: number;
|
|
410
|
+
};
|
|
411
|
+
type EventHandler<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = (event: Event$1<ErmisChatGenerics>) => void;
|
|
412
|
+
type EventTypes = 'all' | keyof typeof EVENT_MAP;
|
|
413
|
+
/**
|
|
414
|
+
* Filter Types
|
|
415
|
+
*/
|
|
416
|
+
type AscDesc = 1 | -1;
|
|
417
|
+
type ChannelFilters = {
|
|
418
|
+
project_id?: string;
|
|
419
|
+
type: ('messaging' | 'team' | 'topic')[];
|
|
420
|
+
limit?: number;
|
|
421
|
+
offset?: number;
|
|
422
|
+
roles?: string[];
|
|
423
|
+
other_roles?: string[];
|
|
424
|
+
banned?: boolean;
|
|
425
|
+
blocked?: boolean;
|
|
426
|
+
include_pinned_messages?: boolean;
|
|
427
|
+
parent_cid?: string;
|
|
428
|
+
parent_id?: string;
|
|
429
|
+
include_parent?: boolean;
|
|
430
|
+
};
|
|
431
|
+
type ChannelSort = {
|
|
432
|
+
field: string;
|
|
433
|
+
direction: -1 | 1;
|
|
434
|
+
}[];
|
|
435
|
+
type Attachment<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['attachmentType'] & {
|
|
436
|
+
id?: string;
|
|
437
|
+
thumb_url?: string;
|
|
438
|
+
content_disposition?: string;
|
|
439
|
+
content_length?: number;
|
|
440
|
+
content_type?: string;
|
|
441
|
+
updated_at?: string;
|
|
442
|
+
created_at?: string;
|
|
443
|
+
message_id?: string;
|
|
444
|
+
file_name?: string;
|
|
445
|
+
url?: string;
|
|
446
|
+
cid?: string;
|
|
447
|
+
user_id?: string;
|
|
448
|
+
asset_url?: string;
|
|
449
|
+
author_icon?: string;
|
|
450
|
+
author_link?: string;
|
|
451
|
+
author_name?: string;
|
|
452
|
+
color?: string;
|
|
453
|
+
duration?: number;
|
|
454
|
+
fallback?: string;
|
|
455
|
+
file_size?: number | string;
|
|
456
|
+
footer?: string;
|
|
457
|
+
footer_icon?: string;
|
|
458
|
+
image_url?: string;
|
|
459
|
+
mime_type?: string;
|
|
460
|
+
og_scrape_url?: string;
|
|
461
|
+
original_height?: number;
|
|
462
|
+
original_width?: number;
|
|
463
|
+
pretext?: string;
|
|
464
|
+
text?: string;
|
|
465
|
+
title?: string;
|
|
466
|
+
title_link?: string;
|
|
467
|
+
type?: string;
|
|
468
|
+
waveform_data?: Array<number>;
|
|
469
|
+
link_url?: string;
|
|
470
|
+
};
|
|
471
|
+
type ChannelData<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['channelType'] & {
|
|
472
|
+
members?: string[];
|
|
473
|
+
name?: string;
|
|
474
|
+
is_pinned?: boolean;
|
|
475
|
+
};
|
|
476
|
+
type ChannelMembership<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
477
|
+
banned?: boolean;
|
|
478
|
+
blocked?: boolean;
|
|
479
|
+
channel_role?: Role;
|
|
480
|
+
created_at?: string;
|
|
481
|
+
updated_at?: string;
|
|
482
|
+
user?: UserResponse<ErmisChatGenerics>;
|
|
483
|
+
};
|
|
484
|
+
type ConnectionOpen<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
485
|
+
cid?: string;
|
|
486
|
+
created_at?: string;
|
|
487
|
+
me?: UserResponse<ErmisChatGenerics>;
|
|
488
|
+
type?: string;
|
|
489
|
+
};
|
|
490
|
+
type LiteralStringForUnion = string & {};
|
|
491
|
+
type LogLevel = 'info' | 'error' | 'warn';
|
|
492
|
+
type Logger = (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => void;
|
|
493
|
+
type Message<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<MessageBase<ErmisChatGenerics>> & {
|
|
494
|
+
id?: string;
|
|
495
|
+
mentioned_all?: boolean;
|
|
496
|
+
mentioned_users?: string[];
|
|
497
|
+
cid?: string;
|
|
498
|
+
forward_cid?: string;
|
|
499
|
+
forward_message_id?: string;
|
|
500
|
+
poll_type?: string;
|
|
501
|
+
poll_choices?: string[];
|
|
502
|
+
sticker_url?: string;
|
|
503
|
+
};
|
|
504
|
+
type EditMessage = {
|
|
505
|
+
text: string;
|
|
506
|
+
mentioned_all?: boolean;
|
|
507
|
+
mentioned_users?: string[];
|
|
508
|
+
};
|
|
509
|
+
type ForwardMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
510
|
+
cid: string;
|
|
511
|
+
forward_cid: string;
|
|
512
|
+
forward_message_id: string;
|
|
513
|
+
id?: string;
|
|
514
|
+
text?: string;
|
|
515
|
+
attachments?: Attachment<ErmisChatGenerics>[];
|
|
516
|
+
sticker_url?: string;
|
|
517
|
+
};
|
|
518
|
+
type PollMessage = {
|
|
519
|
+
id?: string;
|
|
520
|
+
text: string;
|
|
521
|
+
poll_type: string;
|
|
522
|
+
poll_choices: string[];
|
|
523
|
+
};
|
|
524
|
+
type MessageBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['messageType'] & {
|
|
525
|
+
id: string;
|
|
526
|
+
attachments?: Attachment[];
|
|
527
|
+
html?: string;
|
|
528
|
+
mml?: string;
|
|
529
|
+
parent_id?: string;
|
|
530
|
+
pinned?: boolean;
|
|
531
|
+
pinned_at?: string | null;
|
|
532
|
+
quoted_message_id?: string;
|
|
533
|
+
text?: string;
|
|
534
|
+
user?: UserResponse | null;
|
|
535
|
+
user_id?: string;
|
|
536
|
+
};
|
|
537
|
+
type MessageLabel = 'regular' | 'system' | 'signal' | 'poll' | 'sticker' | 'error';
|
|
538
|
+
type Reaction<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['reactionType'] & {
|
|
539
|
+
type: string;
|
|
540
|
+
message_id?: string;
|
|
541
|
+
score?: number;
|
|
542
|
+
user?: UserResponse | null;
|
|
543
|
+
user_id?: string;
|
|
544
|
+
};
|
|
545
|
+
type MessageSetType = 'latest' | 'current' | 'new';
|
|
546
|
+
type APIErrorResponse = {
|
|
547
|
+
code: number;
|
|
548
|
+
duration: string;
|
|
549
|
+
message: string;
|
|
550
|
+
more_info: string;
|
|
551
|
+
StatusCode: number;
|
|
552
|
+
};
|
|
553
|
+
declare class ErrorFromResponse<T> extends Error {
|
|
554
|
+
code?: number;
|
|
555
|
+
response?: AxiosResponse<T>;
|
|
556
|
+
status?: number;
|
|
557
|
+
}
|
|
558
|
+
type UsersResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {
|
|
559
|
+
data: Array<UserResponse<ErmisChatGenerics>>;
|
|
560
|
+
count: number;
|
|
561
|
+
total: number;
|
|
562
|
+
page: number;
|
|
563
|
+
page_count: number;
|
|
564
|
+
};
|
|
565
|
+
type AttachmentResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {
|
|
566
|
+
attachments: Attachment<ErmisChatGenerics>[];
|
|
567
|
+
};
|
|
568
|
+
type SignalData = {
|
|
569
|
+
cid?: string;
|
|
570
|
+
is_video?: boolean;
|
|
571
|
+
action?: string;
|
|
572
|
+
signal?: Object;
|
|
573
|
+
metadata?: Object;
|
|
574
|
+
};
|
|
575
|
+
declare enum CallAction {
|
|
576
|
+
CREATE_CALL = "create-call",
|
|
577
|
+
ACCEPT_CALL = "accept-call",
|
|
578
|
+
SIGNAL_CALL = "signal-call",
|
|
579
|
+
CONNECT_CALL = "connect-call",
|
|
580
|
+
HEALTH_CALL = "health-call",
|
|
581
|
+
END_CALL = "end-call",
|
|
582
|
+
REJECT_CALL = "reject-call",
|
|
583
|
+
MISS_CALL = "miss-call",
|
|
584
|
+
UPGRADE_CALL = "upgrade-call"
|
|
585
|
+
}
|
|
586
|
+
declare enum CallStatus {
|
|
587
|
+
RINGING = "ringing",
|
|
588
|
+
ENDED = "ended",
|
|
589
|
+
CONNECTED = "connected",
|
|
590
|
+
ERROR = "error"
|
|
591
|
+
}
|
|
592
|
+
type CallEventType = 'incoming' | 'outgoing';
|
|
593
|
+
type CallEventData = {
|
|
594
|
+
type: CallEventType;
|
|
595
|
+
callType: string;
|
|
596
|
+
cid: string;
|
|
597
|
+
callerInfo: UserCallInfo | undefined;
|
|
598
|
+
receiverInfo: UserCallInfo | undefined;
|
|
599
|
+
metadata?: Object;
|
|
600
|
+
};
|
|
601
|
+
type UserCallInfo = {
|
|
602
|
+
id: string;
|
|
603
|
+
name?: string;
|
|
604
|
+
avatar?: string;
|
|
605
|
+
};
|
|
606
|
+
type Metadata = {
|
|
607
|
+
address?: string;
|
|
608
|
+
};
|
|
609
|
+
type INodeCall = {
|
|
610
|
+
connect: (address: string) => Promise<void>;
|
|
611
|
+
acceptConnection: () => Promise<void>;
|
|
612
|
+
sendControlFrame: (packet: Uint8Array) => Promise<void>;
|
|
613
|
+
sendAudioFrame: (packet: Uint8Array) => Promise<void>;
|
|
614
|
+
sendFrame: (packet: Uint8Array) => Promise<void>;
|
|
615
|
+
beginWithGop: (packet: Uint8Array) => Promise<void>;
|
|
616
|
+
asyncRecv: () => Promise<Uint8Array>;
|
|
617
|
+
};
|
|
618
|
+
type VideoConfig = {
|
|
619
|
+
codec: string;
|
|
620
|
+
codedWidth: number;
|
|
621
|
+
codedHeight: number;
|
|
622
|
+
frameRate?: number;
|
|
623
|
+
orientation?: number;
|
|
624
|
+
rotation?: number;
|
|
625
|
+
description?: any;
|
|
626
|
+
};
|
|
627
|
+
type AudioConfig = {
|
|
628
|
+
codec: string;
|
|
629
|
+
sampleRate: number;
|
|
630
|
+
numberOfChannels: number;
|
|
631
|
+
description?: string;
|
|
632
|
+
};
|
|
633
|
+
type TransceiverState = {
|
|
634
|
+
audio_enable: boolean;
|
|
635
|
+
video_enable: boolean;
|
|
636
|
+
};
|
|
637
|
+
interface IMediaReceiverEvents {
|
|
638
|
+
onConnected?: () => void;
|
|
639
|
+
onTransceiverState?: (state: any) => void;
|
|
640
|
+
onRequestConfig?: () => void;
|
|
641
|
+
onRequestKeyFrame?: () => void;
|
|
642
|
+
onEndCall?: () => void;
|
|
643
|
+
}
|
|
644
|
+
declare enum FRAME_TYPE {
|
|
645
|
+
VIDEO_CONFIG = 0,
|
|
646
|
+
AUDIO_CONFIG = 1,
|
|
647
|
+
VIDEO_KEY = 2,
|
|
648
|
+
VIDEO_DELTA = 3,
|
|
649
|
+
AUDIO = 4,
|
|
650
|
+
ORIENTATION = 5,
|
|
651
|
+
CONNECTED = 6,
|
|
652
|
+
TRANSCEIVER_STATE = 7,
|
|
653
|
+
REQUEST_CONFIG = 8,
|
|
654
|
+
REQUEST_KEY_FRAME = 9,
|
|
655
|
+
END_CALL = 10
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
type ChannelReadStatus<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<string, {
|
|
659
|
+
last_read: Date;
|
|
660
|
+
unread_messages: number;
|
|
661
|
+
user: UserResponse<ErmisChatGenerics>;
|
|
662
|
+
last_read_message_id?: string;
|
|
663
|
+
last_send?: string;
|
|
664
|
+
}>;
|
|
665
|
+
/**
|
|
666
|
+
* ChannelState - A container class for the channel state.
|
|
667
|
+
*/
|
|
668
|
+
declare class ChannelState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
669
|
+
_channel: Channel<ErmisChatGenerics>;
|
|
670
|
+
watcher_count: number;
|
|
671
|
+
typing: Record<string, Event$1<ErmisChatGenerics>>;
|
|
672
|
+
read: ChannelReadStatus<ErmisChatGenerics>;
|
|
673
|
+
pinnedMessages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;
|
|
674
|
+
watchers: Record<string, UserResponse<ErmisChatGenerics>>;
|
|
675
|
+
members: Record<string, ChannelMemberResponse<ErmisChatGenerics>>;
|
|
676
|
+
unreadCount: number;
|
|
677
|
+
membership: ChannelMembership<ErmisChatGenerics>;
|
|
678
|
+
last_message_at: Date | null;
|
|
679
|
+
isUpToDate: boolean;
|
|
680
|
+
messageSets: {
|
|
681
|
+
isCurrent: boolean;
|
|
682
|
+
isLatest: boolean;
|
|
683
|
+
messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;
|
|
684
|
+
}[];
|
|
685
|
+
topics?: Channel<ErmisChatGenerics>[];
|
|
686
|
+
constructor(channel: Channel<ErmisChatGenerics>);
|
|
687
|
+
get messages(): Array<ReturnType<ChannelState<ErmisChatGenerics>["formatMessage"]>>;
|
|
688
|
+
set messages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>);
|
|
689
|
+
get latestMessages(): Array<ReturnType<ChannelState<ErmisChatGenerics>["formatMessage"]>>;
|
|
690
|
+
set latestMessages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>);
|
|
691
|
+
addMessageSorted(newMessage: MessageResponse<ErmisChatGenerics>, timestampChanged?: boolean, addIfDoesNotExist?: boolean, messageSetToAddToIfDoesNotExist?: MessageSetType): {
|
|
692
|
+
messageSet: {
|
|
693
|
+
isCurrent: boolean;
|
|
694
|
+
isLatest: boolean;
|
|
695
|
+
messages: Array<ReturnType<ChannelState<ErmisChatGenerics>["formatMessage"]>>;
|
|
696
|
+
};
|
|
697
|
+
};
|
|
698
|
+
formatMessage(message: MessageResponse<ErmisChatGenerics>): FormatMessageResponse<ErmisChatGenerics>;
|
|
699
|
+
addMessagesSorted(newMessages: MessageResponse<ErmisChatGenerics>[], timestampChanged?: boolean, initializing?: boolean, addIfDoesNotExist?: boolean, messageSetToAddToIfDoesNotExist?: MessageSetType): {
|
|
700
|
+
messageSet: {
|
|
701
|
+
isCurrent: boolean;
|
|
702
|
+
isLatest: boolean;
|
|
703
|
+
messages: Array<ReturnType<ChannelState<ErmisChatGenerics>["formatMessage"]>>;
|
|
704
|
+
};
|
|
705
|
+
};
|
|
706
|
+
addPinnedMessages(pinnedMessages: MessageResponse<ErmisChatGenerics>[]): void;
|
|
707
|
+
addPinnedMessage(pinnedMessage: MessageResponse<ErmisChatGenerics>): void;
|
|
708
|
+
removePinnedMessage(message: MessageResponse<ErmisChatGenerics>): void;
|
|
709
|
+
addReaction(reaction: ReactionResponse<ErmisChatGenerics>, message?: MessageResponse<ErmisChatGenerics>, enforce_unique?: boolean): MessageResponse<ErmisChatGenerics> | undefined;
|
|
710
|
+
_addOwnReactionToMessage(ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined, reaction: ReactionResponse<ErmisChatGenerics>, enforce_unique?: boolean): ReactionResponse<ErmisChatGenerics>[];
|
|
711
|
+
_removeOwnReactionFromMessage(ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined, reaction: ReactionResponse<ErmisChatGenerics>): ReactionResponse<ErmisChatGenerics>[] | null | undefined;
|
|
712
|
+
removeReaction(reaction: ReactionResponse<ErmisChatGenerics>, message?: MessageResponse<ErmisChatGenerics>): MessageResponse<ErmisChatGenerics> | undefined;
|
|
713
|
+
removeQuotedMessageReferences(message: MessageResponse<ErmisChatGenerics>): void;
|
|
714
|
+
_updateMessage(message: {
|
|
715
|
+
id?: string;
|
|
716
|
+
parent_id?: string;
|
|
717
|
+
pinned?: boolean;
|
|
718
|
+
}, updateFunc: (msg: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>) => ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>): void;
|
|
719
|
+
setIsUpToDate: (isUpToDate: boolean) => void;
|
|
720
|
+
/**
|
|
721
|
+
* Update the status of a message by ID (used for optimistic UI).
|
|
722
|
+
*/
|
|
723
|
+
updateMessageStatus(messageId: string, status: string): void;
|
|
724
|
+
_addToMessageList(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>, message: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>, timestampChanged?: boolean, sortBy?: 'pinned_at' | 'created_at', addIfDoesNotExist?: boolean): FormatMessageResponse<ErmisChatGenerics>[];
|
|
725
|
+
removeMessage(messageToRemove: {
|
|
726
|
+
id: string;
|
|
727
|
+
messageSetIndex?: number;
|
|
728
|
+
parent_id?: string;
|
|
729
|
+
}): boolean;
|
|
730
|
+
removeMessageFromArray: (msgArray: Array<ReturnType<ChannelState<ErmisChatGenerics>["formatMessage"]>>, msg: {
|
|
731
|
+
id: string;
|
|
732
|
+
parent_id?: string;
|
|
733
|
+
}) => {
|
|
734
|
+
removed: boolean;
|
|
735
|
+
result: FormatMessageResponse<ErmisChatGenerics>[];
|
|
736
|
+
};
|
|
737
|
+
updateUserMessages: (user: UserResponse<ErmisChatGenerics>) => void;
|
|
738
|
+
deleteUserMessages: (user: UserResponse<ErmisChatGenerics>, hardDelete?: boolean) => void;
|
|
739
|
+
filterErrorMessages(): void;
|
|
740
|
+
clean(): void;
|
|
741
|
+
clearMessages(): void;
|
|
742
|
+
initMessages(): void;
|
|
743
|
+
loadMessageIntoState(messageId: string | 'latest', parentMessageId?: string, limit?: number): Promise<void>;
|
|
744
|
+
findMessage(messageId: string, parentMessageId?: string): FormatMessageResponse<ErmisChatGenerics> | undefined;
|
|
745
|
+
private switchToMessageSet;
|
|
746
|
+
private areMessageSetsOverlap;
|
|
747
|
+
private findMessageSetIndex;
|
|
748
|
+
private findTargetMessageSet;
|
|
749
|
+
}
|
|
750
|
+
|
|
751
|
+
/**
|
|
752
|
+
* Normalize a file name for upload:
|
|
753
|
+
* - Remove Vietnamese diacritics
|
|
754
|
+
* - Replace đ/Đ with d/D
|
|
755
|
+
* - Replace spaces with underscores
|
|
756
|
+
* - Preserve extension
|
|
757
|
+
*/
|
|
758
|
+
declare function normalizeFileName(name: string): string;
|
|
759
|
+
/**
|
|
760
|
+
* Check if a MIME type or file extension is HEIC/HEIF.
|
|
761
|
+
*/
|
|
762
|
+
declare function isHeicFile(file: File): boolean;
|
|
763
|
+
/**
|
|
764
|
+
* Categorize a file by MIME type.
|
|
765
|
+
* HEIC/HEIF files are treated as 'file' (not 'image') since browsers can't render them.
|
|
766
|
+
*/
|
|
767
|
+
declare function getAttachmentCategory(mimeType: string, fileName?: string): 'image' | 'video' | 'audio' | 'file';
|
|
768
|
+
/**
|
|
769
|
+
* Check if a file is a video type that supports thumbnail extraction.
|
|
770
|
+
*/
|
|
771
|
+
declare function isVideoFile(file: File): boolean;
|
|
772
|
+
/**
|
|
773
|
+
* Metadata for voice recording attachments.
|
|
774
|
+
*/
|
|
775
|
+
type VoiceRecordingMeta = {
|
|
776
|
+
waveform_data: number[];
|
|
777
|
+
duration: number;
|
|
778
|
+
};
|
|
779
|
+
/**
|
|
780
|
+
* Build a normalized attachment payload from an uploaded file.
|
|
781
|
+
*
|
|
782
|
+
* @param file - Original file object
|
|
783
|
+
* @param uploadedUrl - URL returned by the upload API
|
|
784
|
+
* @param thumbUrl - Optional thumbnail URL (for video)
|
|
785
|
+
* @param voiceMeta - Optional voice recording metadata
|
|
786
|
+
*/
|
|
787
|
+
declare function buildAttachmentPayload(file: File, uploadedUrl: string, thumbUrl?: string, voiceMeta?: VoiceRecordingMeta): Attachment;
|
|
788
|
+
|
|
789
|
+
declare class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
790
|
+
_client: ErmisChat<ErmisChatGenerics>;
|
|
791
|
+
type: string;
|
|
792
|
+
id: string | undefined;
|
|
793
|
+
data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics> | undefined;
|
|
794
|
+
_data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics>;
|
|
795
|
+
cid: string;
|
|
796
|
+
listeners: {
|
|
797
|
+
[key: string]: (string | EventHandler<ErmisChatGenerics>)[];
|
|
798
|
+
};
|
|
799
|
+
state: ChannelState<ErmisChatGenerics>;
|
|
800
|
+
initialized: boolean;
|
|
801
|
+
offlineMode: boolean;
|
|
802
|
+
lastKeyStroke?: Date;
|
|
803
|
+
lastTypingEvent: Date | null;
|
|
804
|
+
isTyping: boolean;
|
|
805
|
+
disconnected: boolean;
|
|
806
|
+
constructor(client: ErmisChat<ErmisChatGenerics>, type: string, id: string | undefined, data: ChannelData<ErmisChatGenerics>);
|
|
807
|
+
getClient(): ErmisChat<ErmisChatGenerics>;
|
|
808
|
+
sendMessage(message: Message<ErmisChatGenerics>): Promise<SendMessageAPIResponse<ErmisChatGenerics>>;
|
|
809
|
+
retryMessage(messageId: string): Promise<SendMessageAPIResponse<ErmisChatGenerics>>;
|
|
810
|
+
createPoll(pollMessage: PollMessage): Promise<SendMessageAPIResponse<ErmisChatGenerics>>;
|
|
811
|
+
votePoll(messageID: string, pollChoice: string): Promise<APIResponse>;
|
|
812
|
+
forwardMessage(message: ForwardMessage<ErmisChatGenerics>, channel: {
|
|
813
|
+
type: string;
|
|
814
|
+
channelID: string;
|
|
815
|
+
}): Promise<SendMessageAPIResponse<ErmisChatGenerics>>;
|
|
816
|
+
pinMessage(messageID: string): Promise<unknown>;
|
|
817
|
+
unpinMessage(messageID: string): Promise<unknown>;
|
|
818
|
+
editMessage(oldMessageID: string, message: EditMessage): Promise<unknown>;
|
|
819
|
+
sendFile(uri: string | NodeJS.ReadableStream | Buffer | File, name?: string, contentType?: string, user?: UserResponse<ErmisChatGenerics>): Promise<SendFileAPIResponse>;
|
|
820
|
+
/**
|
|
821
|
+
* Pre-process files (normalize names), upload them in parallel,
|
|
822
|
+
* generate video thumbnails, and build attachment payloads.
|
|
823
|
+
*
|
|
824
|
+
* @param files - Array of File objects to upload
|
|
825
|
+
* @param options - Optional voice recording metadata
|
|
826
|
+
* @returns `attachments` ready for sendMessage, and `failedFiles` for error display
|
|
827
|
+
*/
|
|
828
|
+
uploadAndPrepareAttachments(files: File[], options?: {
|
|
829
|
+
/** Map from file index → voice recording metadata */
|
|
830
|
+
voiceMetadata?: Map<number, VoiceRecordingMeta>;
|
|
831
|
+
}): Promise<{
|
|
832
|
+
attachments: Attachment[];
|
|
833
|
+
failedFiles: Array<{
|
|
834
|
+
file: File;
|
|
835
|
+
error: Error;
|
|
836
|
+
}>;
|
|
837
|
+
}>;
|
|
838
|
+
sendEvent(event: Event$1<ErmisChatGenerics>): Promise<unknown>;
|
|
839
|
+
sendReaction(messageID: string, reactionType: string): Promise<ReactionAPIResponse<ErmisChatGenerics>>;
|
|
840
|
+
deleteReaction(messageID: string, reactionType: string): Promise<ReactionAPIResponse<ErmisChatGenerics>>;
|
|
841
|
+
update(channelData?: Partial<ChannelData<ErmisChatGenerics>> | Partial<ChannelResponse<ErmisChatGenerics>>, updateMessage?: Message<ErmisChatGenerics>): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
842
|
+
delete(): Promise<unknown>;
|
|
843
|
+
truncate(): Promise<unknown>;
|
|
844
|
+
blockUser(): Promise<unknown>;
|
|
845
|
+
unblockUser(): Promise<unknown>;
|
|
846
|
+
acceptInvite(action: string): Promise<APIResponse>;
|
|
847
|
+
rejectInvite(): Promise<APIResponse>;
|
|
848
|
+
skipInvite(): Promise<APIResponse>;
|
|
849
|
+
addMembers(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
850
|
+
addModerators(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
851
|
+
banMembers(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
852
|
+
unbanMembers(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
853
|
+
updateCapabilities(capabilities: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
854
|
+
/**
|
|
855
|
+
* Set slow mode (message cooldown) for the channel.
|
|
856
|
+
* Only applicable to team channels. Prevents members from sending
|
|
857
|
+
* messages faster than the specified cooldown interval.
|
|
858
|
+
*
|
|
859
|
+
* @param cooldown - Cooldown duration in milliseconds.
|
|
860
|
+
* Allowed values: 0 (off), 10000 (10s), 30000 (30s),
|
|
861
|
+
* 60000 (1min), 300000 (5min), 900000 (15min), 3600000 (1h).
|
|
862
|
+
*/
|
|
863
|
+
setSlowMode(cooldown: 0 | 10000 | 30000 | 60000 | 300000 | 900000 | 3600000): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
864
|
+
queryAttachmentMessages(): Promise<AttachmentResponse<ErmisChatGenerics>>;
|
|
865
|
+
searchMessage(search_term: string, offset: number): Promise<any>;
|
|
866
|
+
removeMembers(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
867
|
+
demoteModerators(members: string[]): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
868
|
+
_update(payload: Object): Promise<UpdateChannelAPIResponse<ErmisChatGenerics>>;
|
|
869
|
+
_processTopics(topicsFromApi: any, users: any[]): void;
|
|
870
|
+
muteNotification(duration: number | null): Promise<AttachmentResponse<ErmisChatGenerics>>;
|
|
871
|
+
unMuteNotification(): Promise<AttachmentResponse<ErmisChatGenerics>>;
|
|
872
|
+
keystroke(parent_id?: string, options?: {
|
|
873
|
+
user_id: string;
|
|
874
|
+
}): Promise<void>;
|
|
875
|
+
stopTyping(parent_id?: string, options?: {
|
|
876
|
+
user_id: string;
|
|
877
|
+
}): Promise<void>;
|
|
878
|
+
_isTypingIndicatorsEnabled(): boolean;
|
|
879
|
+
lastMessage(): FormatMessageResponse<ErmisChatGenerics>;
|
|
880
|
+
markRead(): Promise<unknown>;
|
|
881
|
+
clean(): void;
|
|
882
|
+
watch(options?: ChannelQueryOptions): Promise<QueryChannelAPIResponse<ErmisChatGenerics>>;
|
|
883
|
+
lastRead(): Date | null | undefined;
|
|
884
|
+
_countMessageAsUnread(message: FormatMessageResponse<ErmisChatGenerics> | MessageResponse<ErmisChatGenerics>): boolean;
|
|
885
|
+
countUnread(lastRead?: Date | null): number;
|
|
886
|
+
getUnreadMemberCount(): {
|
|
887
|
+
last_read: Date;
|
|
888
|
+
unread_messages: number;
|
|
889
|
+
user: UserResponse<ErmisChatGenerics>;
|
|
890
|
+
last_read_message_id?: string;
|
|
891
|
+
last_send?: string;
|
|
892
|
+
}[];
|
|
893
|
+
getCapabilitiesMember(): unknown;
|
|
894
|
+
create: () => Promise<QueryChannelAPIResponse<ErmisChatGenerics>>;
|
|
895
|
+
createTopic(data: any): Promise<QueryChannelAPIResponse<ErmisChatGenerics>>;
|
|
896
|
+
query(options: ChannelQueryOptions, messageSetToAddToIfDoesNotExist?: MessageSetType): Promise<QueryChannelAPIResponse<ErmisChatGenerics>>;
|
|
897
|
+
createDirectChannel(messageSetToAddToIfDoesNotExist?: MessageSetType): Promise<QueryChannelAPIResponse<ErmisChatGenerics>>;
|
|
898
|
+
queryMessagesLessThanId(message_id: string, limit?: number): Promise<MessageResponse<ErmisChatGenerics>[]>;
|
|
899
|
+
queryMessagesGreaterThanId(message_id: string, limit?: number): Promise<MessageResponse<ErmisChatGenerics>[]>;
|
|
900
|
+
queryMessagesAroundId(message_id: string, limit?: number): Promise<MessageResponse<ErmisChatGenerics>[]>;
|
|
901
|
+
deleteMessage(messageId: string): Promise<APIResponse & {
|
|
902
|
+
message: MessageResponse<ErmisChatGenerics>;
|
|
903
|
+
}>;
|
|
904
|
+
deleteMessageForMe(messageId: string): Promise<APIResponse & {
|
|
905
|
+
message: MessageResponse<ErmisChatGenerics>;
|
|
906
|
+
}>;
|
|
907
|
+
getThumbBlobVideo(file: File): Promise<Blob | null>;
|
|
908
|
+
enableTopics(): Promise<unknown>;
|
|
909
|
+
disableTopics(): Promise<unknown>;
|
|
910
|
+
closeTopic(topicCID: string): Promise<unknown>;
|
|
911
|
+
reopenTopic(topicCID: string): Promise<unknown>;
|
|
912
|
+
editTopic(topicCID: string, data: any): Promise<any>;
|
|
913
|
+
on(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): {
|
|
914
|
+
unsubscribe: () => void;
|
|
915
|
+
};
|
|
916
|
+
on(callback: EventHandler<ErmisChatGenerics>): {
|
|
917
|
+
unsubscribe: () => void;
|
|
918
|
+
};
|
|
919
|
+
off(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): void;
|
|
920
|
+
off(callback: EventHandler<ErmisChatGenerics>): void;
|
|
921
|
+
_handleChannelEvent(event: Event$1<ErmisChatGenerics>): Promise<void>;
|
|
922
|
+
_callChannelListeners: (event: Event$1<ErmisChatGenerics>) => void;
|
|
923
|
+
_channelURL: () => string;
|
|
924
|
+
_checkInitialized(): void;
|
|
925
|
+
_initializeState(state: ChannelAPIResponse<ErmisChatGenerics>, messageSetToAddToIfDoesNotExist?: MessageSetType, updateUserIds?: (id: string) => void): {
|
|
926
|
+
messageSet: {
|
|
927
|
+
isCurrent: boolean;
|
|
928
|
+
isLatest: boolean;
|
|
929
|
+
messages: FormatMessageResponse<ErmisChatGenerics>[];
|
|
930
|
+
};
|
|
931
|
+
};
|
|
932
|
+
_extendEventWithOwnReactions(event: Event$1<ErmisChatGenerics>): void;
|
|
933
|
+
_disconnect(): void;
|
|
934
|
+
}
|
|
935
|
+
|
|
936
|
+
/**
|
|
937
|
+
* ClientState - A container class for the client state.
|
|
938
|
+
*/
|
|
939
|
+
declare class ClientState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
940
|
+
users: {
|
|
941
|
+
[key: string]: UserResponse<ErmisChatGenerics>;
|
|
942
|
+
};
|
|
943
|
+
userChannelReferences: {
|
|
944
|
+
[key: string]: {
|
|
945
|
+
[key: string]: boolean;
|
|
946
|
+
};
|
|
947
|
+
};
|
|
948
|
+
constructor();
|
|
949
|
+
updateUsers(users: UserResponse<ErmisChatGenerics>[]): void;
|
|
950
|
+
updateUser(user?: UserResponse<ErmisChatGenerics>): void;
|
|
951
|
+
updateUserReference(user: UserResponse<ErmisChatGenerics>, channelID: string): void;
|
|
952
|
+
deleteAllChannelReference(channelID: string): void;
|
|
953
|
+
}
|
|
954
|
+
|
|
955
|
+
/**
|
|
956
|
+
* TokenManager
|
|
957
|
+
*
|
|
958
|
+
* Manages token storage and retrieval for the chat client.
|
|
959
|
+
*/
|
|
960
|
+
declare class TokenManager<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
961
|
+
loadTokenPromise: Promise<string> | null;
|
|
962
|
+
token?: string;
|
|
963
|
+
user?: UserResponse<ErmisChatGenerics>;
|
|
964
|
+
constructor();
|
|
965
|
+
/**
|
|
966
|
+
* Set the static string token.
|
|
967
|
+
*/
|
|
968
|
+
setTokenOrProvider: (tokenOrProvider: string | null, user: UserResponse<ErmisChatGenerics>) => Promise<void>;
|
|
969
|
+
/**
|
|
970
|
+
* Resets the token manager.
|
|
971
|
+
*/
|
|
972
|
+
reset: () => void;
|
|
973
|
+
/**
|
|
974
|
+
* Resolves when token is ready.
|
|
975
|
+
*/
|
|
976
|
+
tokenReady: () => Promise<string> | null;
|
|
977
|
+
/** Returns the current token */
|
|
978
|
+
getToken: () => string | undefined;
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
declare class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
982
|
+
private static _instance?;
|
|
983
|
+
activeChannels: {
|
|
984
|
+
[key: string]: Channel<ErmisChatGenerics>;
|
|
985
|
+
};
|
|
986
|
+
axiosInstance: AxiosInstance;
|
|
987
|
+
baseURL?: string;
|
|
988
|
+
userBaseURL?: string;
|
|
989
|
+
browser: boolean;
|
|
990
|
+
cleaningIntervalRef?: NodeJS.Timeout;
|
|
991
|
+
clientID?: string;
|
|
992
|
+
apiKey: string;
|
|
993
|
+
projectId: string;
|
|
994
|
+
listeners: Record<string, Array<(event: Event$1<ErmisChatGenerics>) => void>>;
|
|
995
|
+
logger: Logger;
|
|
996
|
+
recoverStateOnReconnect?: boolean;
|
|
997
|
+
node: boolean;
|
|
998
|
+
options: ErmisChatOptions;
|
|
999
|
+
setUserPromise: ConnectAPIResponse<ErmisChatGenerics> | null;
|
|
1000
|
+
state: ClientState<ErmisChatGenerics>;
|
|
1001
|
+
tokenManager: TokenManager<ErmisChatGenerics>;
|
|
1002
|
+
user?: UserResponse<ErmisChatGenerics>;
|
|
1003
|
+
userAgent?: string;
|
|
1004
|
+
userID?: string;
|
|
1005
|
+
wsBaseURL?: string;
|
|
1006
|
+
wsConnection: StableWSConnection<ErmisChatGenerics> | null;
|
|
1007
|
+
wsPromise: ConnectAPIResponse<ErmisChatGenerics> | null;
|
|
1008
|
+
consecutiveFailures: number;
|
|
1009
|
+
defaultWSTimeout: number;
|
|
1010
|
+
private eventSource;
|
|
1011
|
+
constructor(apiKey: string, projectId: string, baseURL: string, options?: ErmisChatOptions);
|
|
1012
|
+
static getInstance<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(key: string, projectId: string, baseURL: string, options?: ErmisChatOptions): ErmisChat<ErmisChatGenerics>;
|
|
1013
|
+
refreshNewToken(refresh_token: string): Promise<APIResponse>;
|
|
1014
|
+
getAuthType(): string;
|
|
1015
|
+
setBaseURL(baseURL: string): void;
|
|
1016
|
+
getExternalAuthToken(user: UserResponse<ErmisChatGenerics>, token: string | null): Promise<any>;
|
|
1017
|
+
connectUser: (user: UserResponse<ErmisChatGenerics>, userTokenOrProvider: string | null, extenal_auth?: boolean) => Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
1018
|
+
setUser: (user: UserResponse<ErmisChatGenerics>, userTokenOrProvider: string | null, extenal_auth?: boolean) => Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
1019
|
+
_setToken: (user: UserResponse<ErmisChatGenerics>, userTokenOrProvider: string | null) => Promise<void>;
|
|
1020
|
+
_setUser(user: UserResponse<ErmisChatGenerics>): void;
|
|
1021
|
+
closeConnection: (timeout?: number) => Promise<void>;
|
|
1022
|
+
openConnection: () => Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
1023
|
+
_setupConnection: () => Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
1024
|
+
disconnectUser: (timeout?: number) => Promise<void>;
|
|
1025
|
+
disconnect: (timeout?: number) => Promise<void>;
|
|
1026
|
+
on(callback: EventHandler<ErmisChatGenerics>): {
|
|
1027
|
+
unsubscribe: () => void;
|
|
1028
|
+
};
|
|
1029
|
+
on(eventType: string, callback: EventHandler<ErmisChatGenerics>): {
|
|
1030
|
+
unsubscribe: () => void;
|
|
1031
|
+
};
|
|
1032
|
+
off(callback: EventHandler<ErmisChatGenerics>): void;
|
|
1033
|
+
off(eventType: string, callback: EventHandler<ErmisChatGenerics>): void;
|
|
1034
|
+
_logApiRequest(type: string, url: string, data: unknown, config: AxiosRequestConfig & {
|
|
1035
|
+
config?: AxiosRequestConfig & {
|
|
1036
|
+
maxBodyLength?: number;
|
|
1037
|
+
};
|
|
1038
|
+
}): void;
|
|
1039
|
+
_logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>): void;
|
|
1040
|
+
_logApiError(type: string, url: string, error: unknown, options: unknown): void;
|
|
1041
|
+
doAxiosRequest: <T>(type: string, url: string, data?: unknown, options?: AxiosRequestConfig & {
|
|
1042
|
+
config?: AxiosRequestConfig & {
|
|
1043
|
+
maxBodyLength?: number;
|
|
1044
|
+
};
|
|
1045
|
+
}) => Promise<T>;
|
|
1046
|
+
get<T>(url: string, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1047
|
+
put<T>(url: string, data?: unknown): Promise<T>;
|
|
1048
|
+
post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1049
|
+
patch<T>(url: string, data?: unknown): Promise<T>;
|
|
1050
|
+
delete<T>(url: string, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1051
|
+
sendFile(url: string, uri: string | NodeJS.ReadableStream | Buffer | File, name?: string, contentType?: string, user?: UserResponse<ErmisChatGenerics>): Promise<SendFileAPIResponse>;
|
|
1052
|
+
errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse>;
|
|
1053
|
+
handleResponse<T>(response: AxiosResponse<T>): T;
|
|
1054
|
+
dispatchEvent: (event: Event$1<ErmisChatGenerics>) => void;
|
|
1055
|
+
_afterDispatchEvent(event: Event$1<ErmisChatGenerics>): void;
|
|
1056
|
+
private _handleChannelCreatedEvent;
|
|
1057
|
+
handleEvent: (messageEvent: WebSocket.MessageEvent) => void;
|
|
1058
|
+
_updateMemberWatcherReferences: (user: UserResponse<ErmisChatGenerics>) => void;
|
|
1059
|
+
_updateUserReferences: (user: UserResponse<ErmisChatGenerics>) => void;
|
|
1060
|
+
_updateUserMessageReferences: (user: UserResponse<ErmisChatGenerics>) => void;
|
|
1061
|
+
_deleteUserMessageReference: (user: UserResponse<ErmisChatGenerics>, hardDelete?: boolean) => void;
|
|
1062
|
+
_handleClientEvent(event: Event$1<ErmisChatGenerics>): (() => void)[];
|
|
1063
|
+
_callClientListeners: (event: Event$1<ErmisChatGenerics>) => void;
|
|
1064
|
+
recoverState: () => Promise<void>;
|
|
1065
|
+
connect(): Promise<void | ConnectionOpen<ErmisChatGenerics>>;
|
|
1066
|
+
connectToSSE(onCallBack?: (data: any) => void): Promise<void>;
|
|
1067
|
+
disconnectFromSSE(): Promise<void>;
|
|
1068
|
+
queryUsers(page_size?: string, page?: number): Promise<UsersResponse>;
|
|
1069
|
+
queryUser(user_id: string): Promise<UserResponse<ErmisChatGenerics>>;
|
|
1070
|
+
getBatchUsers(users: string[], page?: number, page_size?: number): Promise<UserResponse<DefaultGenerics>[]>;
|
|
1071
|
+
searchUsers(page: number, page_size: number, name?: string): Promise<UsersResponse>;
|
|
1072
|
+
queryContacts(): Promise<ContactResult>;
|
|
1073
|
+
_updateProjectID(project_id: string): void;
|
|
1074
|
+
uploadFile(file: File): Promise<{
|
|
1075
|
+
avatar: string;
|
|
1076
|
+
}>;
|
|
1077
|
+
updateProfile(name: string, about_me: string): Promise<UserResponse<ErmisChatGenerics>>;
|
|
1078
|
+
queryChannels(filterConditions: ChannelFilters, sort?: ChannelSort, options?: {
|
|
1079
|
+
message_limit?: number;
|
|
1080
|
+
}, stateOptions?: ChannelStateOptions): Promise<Channel<ErmisChatGenerics>[]>;
|
|
1081
|
+
hydrateChannels(channelsFromApi?: ChannelAPIResponse<ErmisChatGenerics>[], stateOptions?: ChannelStateOptions): {
|
|
1082
|
+
channels: Channel<ErmisChatGenerics>[];
|
|
1083
|
+
userIds: string[];
|
|
1084
|
+
};
|
|
1085
|
+
searchPublicChannel(search_term: string, offset?: number, limit?: number): Promise<APIResponse>;
|
|
1086
|
+
pinChannel(channelType: string, channelId: string): Promise<APIResponse>;
|
|
1087
|
+
unpinChannel(channelType: string, channelId: string): Promise<APIResponse>;
|
|
1088
|
+
channel(channelType: string, channelID: string, custom?: ChannelData<ErmisChatGenerics>): Channel<ErmisChatGenerics>;
|
|
1089
|
+
getChannelById: (channelType: string, channelID: string, custom: ChannelData<ErmisChatGenerics>) => Channel<ErmisChatGenerics>;
|
|
1090
|
+
getChannel: (channelType: string, custom: ChannelData<ErmisChatGenerics>) => Channel<ErmisChatGenerics>;
|
|
1091
|
+
_normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date): string | null;
|
|
1092
|
+
getUserAgent(): string;
|
|
1093
|
+
setUserAgent(userAgent: string): void;
|
|
1094
|
+
_enrichAxiosOptions(options?: AxiosRequestConfig & {
|
|
1095
|
+
config?: AxiosRequestConfig;
|
|
1096
|
+
}): AxiosRequestConfig;
|
|
1097
|
+
_getToken(): string | null | undefined;
|
|
1098
|
+
_startCleaning(): void;
|
|
1099
|
+
_buildWSPayload: (client_request_id?: string) => string;
|
|
1100
|
+
}
|
|
1101
|
+
|
|
1102
|
+
declare class ErmisCall {
|
|
1103
|
+
free(): void;
|
|
1104
|
+
[Symbol.dispose](): void;
|
|
1105
|
+
constructor();
|
|
1106
|
+
spawn(relay_urls: any, secret_key?: Uint8Array | null): Promise<void>;
|
|
1107
|
+
getLocalEndpointAddr(): Promise<string>;
|
|
1108
|
+
connect(addr: string): Promise<void>;
|
|
1109
|
+
closeEndpoint(): Promise<void>;
|
|
1110
|
+
closeConnection(): void;
|
|
1111
|
+
acceptConnection(): Promise<void>;
|
|
1112
|
+
sendControlFrame(data: Uint8Array): void;
|
|
1113
|
+
sendAudioFrame(data: Uint8Array): void;
|
|
1114
|
+
sendFrame(data: Uint8Array): void;
|
|
1115
|
+
notifyNewGop(): void;
|
|
1116
|
+
recv(): Uint8Array;
|
|
1117
|
+
asyncRecv(): Promise<Uint8Array>;
|
|
1118
|
+
beginWithGop(data: Uint8Array): void;
|
|
1119
|
+
connectionType(): string | undefined;
|
|
1120
|
+
roundTripTime(): number | undefined;
|
|
1121
|
+
currentPacketLoss(): number | undefined;
|
|
1122
|
+
networkChange(): void;
|
|
1123
|
+
getStats(): any;
|
|
1124
|
+
}
|
|
1125
|
+
|
|
1126
|
+
declare class MediaStreamSender {
|
|
1127
|
+
private videoEncoder;
|
|
1128
|
+
private audioEncoder;
|
|
1129
|
+
private videoReader;
|
|
1130
|
+
private localStream;
|
|
1131
|
+
private videoConfig;
|
|
1132
|
+
private audioConfig;
|
|
1133
|
+
private videoConfigSent;
|
|
1134
|
+
private audioConfigSent;
|
|
1135
|
+
private hasVideo;
|
|
1136
|
+
private hasAudio;
|
|
1137
|
+
private forceKeyFrame;
|
|
1138
|
+
private nodeCall;
|
|
1139
|
+
constructor(nodeCall: INodeCall);
|
|
1140
|
+
/**
|
|
1141
|
+
* Bắt đầu xử lý MediaStream
|
|
1142
|
+
*/
|
|
1143
|
+
connect(address: string): Promise<void>;
|
|
1144
|
+
sendConfigs(): Promise<void>;
|
|
1145
|
+
/**
|
|
1146
|
+
* Dừng và reset encoders
|
|
1147
|
+
*/
|
|
1148
|
+
stop: () => void;
|
|
1149
|
+
initAudioEncoder: (audioTrack: MediaStreamTrack) => void;
|
|
1150
|
+
initVideoEncoder(videoTrack: MediaStreamTrack): void;
|
|
1151
|
+
initEncoders: (stream: MediaStream) => void;
|
|
1152
|
+
sendTransceiverState: (audioEnable: boolean, videoEnable: boolean) => Promise<void>;
|
|
1153
|
+
replaceVideoTrack(track: MediaStreamTrack): Promise<void>;
|
|
1154
|
+
replaceAudioTrack(track: MediaStreamTrack): Promise<void>;
|
|
1155
|
+
/**
|
|
1156
|
+
* Yêu cầu gửi keyframe ngay lập tức (được gọi khi nhận REQUEST_KEY_FRAME từ receiver)
|
|
1157
|
+
*/
|
|
1158
|
+
requestKeyFrame: () => void;
|
|
1159
|
+
private processVideoFrames;
|
|
1160
|
+
private processAudioFrames;
|
|
1161
|
+
private isReadyToSendData;
|
|
1162
|
+
private sendVideoConfig;
|
|
1163
|
+
private sendAudioConfig;
|
|
1164
|
+
sendConnected: () => Promise<void>;
|
|
1165
|
+
private sendPacketOrQueue;
|
|
1166
|
+
}
|
|
1167
|
+
|
|
1168
|
+
declare class MediaStreamReceiver {
|
|
1169
|
+
private videoDecoder;
|
|
1170
|
+
private audioDecoder;
|
|
1171
|
+
private videoWriter;
|
|
1172
|
+
private audioContext;
|
|
1173
|
+
private mediaDestination;
|
|
1174
|
+
private isWaitingForKeyFrame;
|
|
1175
|
+
private nextStartTime;
|
|
1176
|
+
private lastVideoConfig;
|
|
1177
|
+
private nodeCall;
|
|
1178
|
+
private events;
|
|
1179
|
+
private generatedStream;
|
|
1180
|
+
constructor(nodeCall: INodeCall, events?: IMediaReceiverEvents);
|
|
1181
|
+
acceptConnection(): Promise<void>;
|
|
1182
|
+
getRemoteStream: () => MediaStream | null;
|
|
1183
|
+
/**
|
|
1184
|
+
* Dừng toàn bộ quá trình và giải phóng tài nguyên
|
|
1185
|
+
*/
|
|
1186
|
+
stop: () => void;
|
|
1187
|
+
private initAudioContext;
|
|
1188
|
+
initDecoders: (callType: string) => void;
|
|
1189
|
+
setupVideoDecoder: () => void;
|
|
1190
|
+
private playDecodedAudio;
|
|
1191
|
+
private newCodecFromDescription;
|
|
1192
|
+
receiveLoop: () => Promise<void>;
|
|
1193
|
+
private resetDecoders;
|
|
1194
|
+
}
|
|
1195
|
+
|
|
1196
|
+
declare class ErmisCallNode<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {
|
|
1197
|
+
wasmPath: string;
|
|
1198
|
+
relayUrl: string;
|
|
1199
|
+
/** Reference to the Ermis Chat client instance */
|
|
1200
|
+
_client: ErmisChat<ErmisChatGenerics>;
|
|
1201
|
+
/** Unique identifier for the current call session */
|
|
1202
|
+
sessionID: string;
|
|
1203
|
+
/** Channel ID for communication between users */
|
|
1204
|
+
cid?: string;
|
|
1205
|
+
/** Type of call: 'audio' or 'video' */
|
|
1206
|
+
callType?: string;
|
|
1207
|
+
/** ID of the current user */
|
|
1208
|
+
userID?: string | undefined;
|
|
1209
|
+
/** Current status of the call */
|
|
1210
|
+
callStatus?: string | undefined;
|
|
1211
|
+
metadata?: Metadata;
|
|
1212
|
+
callNode: ErmisCall | null;
|
|
1213
|
+
/** Local media stream from user's camera/microphone */
|
|
1214
|
+
localStream?: MediaStream | null;
|
|
1215
|
+
/** Remote media stream from the other participant */
|
|
1216
|
+
remoteStream?: MediaStream | null;
|
|
1217
|
+
/** Information about the caller */
|
|
1218
|
+
callerInfo?: UserCallInfo;
|
|
1219
|
+
/** Information about the call receiver */
|
|
1220
|
+
receiverInfo?: UserCallInfo;
|
|
1221
|
+
/** Callback triggered when call events occur (incoming/outgoing) */
|
|
1222
|
+
onCallEvent?: (data: CallEventData) => void;
|
|
1223
|
+
/** Callback triggered when local stream is available */
|
|
1224
|
+
onLocalStream?: (stream: MediaStream) => void;
|
|
1225
|
+
/** Callback triggered when remote stream is available */
|
|
1226
|
+
onRemoteStream?: (stream: MediaStream) => void;
|
|
1227
|
+
/** Callback for connection status message changes */
|
|
1228
|
+
onConnectionMessageChange?: (message: string | null) => void;
|
|
1229
|
+
/** Callback for call status changes */
|
|
1230
|
+
onCallStatus?: (status: string | null) => void;
|
|
1231
|
+
/** Callback for messages received through WebRTC data channel */
|
|
1232
|
+
onDataChannelMessage?: (data: any) => void;
|
|
1233
|
+
/** Callback for when a call is upgraded (e.g., audio to video) */
|
|
1234
|
+
onUpgradeCall?: (upgraderInfo: UserCallInfo) => void;
|
|
1235
|
+
/** Callback for screen sharing status changes */
|
|
1236
|
+
onScreenShareChange?: (isSharing: boolean) => void;
|
|
1237
|
+
/** Callback for error handling */
|
|
1238
|
+
onError?: (error: string) => void;
|
|
1239
|
+
/** Callback for device list changes */
|
|
1240
|
+
onDeviceChange?: (audioDevices: MediaDeviceInfo[], videoDevices: MediaDeviceInfo[]) => void;
|
|
1241
|
+
/** Available audio input devices */
|
|
1242
|
+
private availableAudioDevices;
|
|
1243
|
+
/** Available video input devices */
|
|
1244
|
+
private availableVideoDevices;
|
|
1245
|
+
/** Currently selected audio device ID */
|
|
1246
|
+
private selectedAudioDeviceId?;
|
|
1247
|
+
/** Currently selected video device ID */
|
|
1248
|
+
private selectedVideoDeviceId?;
|
|
1249
|
+
/** Timeout for ending call if not answered after a period */
|
|
1250
|
+
private missCallTimeout;
|
|
1251
|
+
/** Interval for sending health check via WebRTC */
|
|
1252
|
+
private healthCallInterval;
|
|
1253
|
+
/** Interval for sending health check via server */
|
|
1254
|
+
private healthCallServerInterval;
|
|
1255
|
+
/** Timeout for detecting if remote peer has disconnected */
|
|
1256
|
+
private healthCallTimeout;
|
|
1257
|
+
/** Timeout for showing warning when connection becomes unstable */
|
|
1258
|
+
private healthCallWarningTimeout;
|
|
1259
|
+
/** Handler for signal events */
|
|
1260
|
+
private signalHandler;
|
|
1261
|
+
/** Handler for connection change events */
|
|
1262
|
+
private connectionChangedHandler;
|
|
1263
|
+
/** Handler for message updated events */
|
|
1264
|
+
private messageUpdatedHandler;
|
|
1265
|
+
/** Flag indicating if the user is offline */
|
|
1266
|
+
private isOffline;
|
|
1267
|
+
/**
|
|
1268
|
+
* True if this call instance is destroyed (e.g., when another device accepts the call).
|
|
1269
|
+
* When true, SIGNAL_CALL events will be ignored.
|
|
1270
|
+
*/
|
|
1271
|
+
private isDestroyed;
|
|
1272
|
+
mediaSender: MediaStreamSender | null;
|
|
1273
|
+
mediaReceiver: MediaStreamReceiver | null;
|
|
1274
|
+
constructor(client: ErmisChat<ErmisChatGenerics>, sessionID: string, wasmPath: string, relayUrl: string);
|
|
1275
|
+
private loadWasm;
|
|
1276
|
+
private initialize;
|
|
1277
|
+
getLocalEndpointAddr(): Promise<string | null>;
|
|
1278
|
+
private getClient;
|
|
1279
|
+
private _sendSignal;
|
|
1280
|
+
private getAvailableDevices;
|
|
1281
|
+
private getMediaConstraints;
|
|
1282
|
+
startLocalStream(): Promise<MediaStream | null | undefined>;
|
|
1283
|
+
private setConnectionMessage;
|
|
1284
|
+
private setCallStatus;
|
|
1285
|
+
private setUserInfo;
|
|
1286
|
+
private listenSocketEvents;
|
|
1287
|
+
private cleanupCall;
|
|
1288
|
+
private destroy;
|
|
1289
|
+
getDevices(): Promise<{
|
|
1290
|
+
audioDevices: MediaDeviceInfo[];
|
|
1291
|
+
videoDevices: MediaDeviceInfo[];
|
|
1292
|
+
}>;
|
|
1293
|
+
getSelectedDevices(): {
|
|
1294
|
+
audioDevice?: MediaDeviceInfo;
|
|
1295
|
+
videoDevice?: MediaDeviceInfo;
|
|
1296
|
+
};
|
|
1297
|
+
getDefaultDevices(): {
|
|
1298
|
+
audioDevice?: MediaDeviceInfo;
|
|
1299
|
+
videoDevice?: MediaDeviceInfo;
|
|
1300
|
+
};
|
|
1301
|
+
createCall(callType: string, cid: string): Promise<void>;
|
|
1302
|
+
acceptCall(): Promise<void>;
|
|
1303
|
+
endCall(): Promise<void>;
|
|
1304
|
+
rejectCall(): Promise<void>;
|
|
1305
|
+
private missCall;
|
|
1306
|
+
private connectCall;
|
|
1307
|
+
private healthCall;
|
|
1308
|
+
private addVideoTrackToLocalStream;
|
|
1309
|
+
upgradeCall(): Promise<void>;
|
|
1310
|
+
requestUpgradeCall(enabled: boolean): Promise<void>;
|
|
1311
|
+
startScreenShare(): Promise<void>;
|
|
1312
|
+
stopScreenShare(): Promise<void>;
|
|
1313
|
+
toggleMic(enabled: boolean): Promise<void>;
|
|
1314
|
+
toggleCamera(enabled: boolean): Promise<void>;
|
|
1315
|
+
switchAudioDevice(deviceId: string): Promise<boolean>;
|
|
1316
|
+
switchVideoDevice(deviceId: string): Promise<boolean>;
|
|
1317
|
+
private setupDeviceChangeListener;
|
|
1318
|
+
}
|
|
1319
|
+
|
|
1320
|
+
declare class ErmisAuthProvider {
|
|
1321
|
+
apiKey: string;
|
|
1322
|
+
baseURL?: string;
|
|
1323
|
+
options?: ErmisChatOptions;
|
|
1324
|
+
axiosInstance: AxiosInstance;
|
|
1325
|
+
disconnected: boolean;
|
|
1326
|
+
browser: boolean;
|
|
1327
|
+
node: boolean;
|
|
1328
|
+
logger: Logger;
|
|
1329
|
+
consecutiveFailures: number;
|
|
1330
|
+
userAgent?: string;
|
|
1331
|
+
/** Last identifier (phone or email) used for OTP */
|
|
1332
|
+
lastIdentifier?: string;
|
|
1333
|
+
/**
|
|
1334
|
+
* The last OTP method used ('Sms', 'Voice', or 'Email').
|
|
1335
|
+
* Used to verify OTP for the correct method.
|
|
1336
|
+
*/
|
|
1337
|
+
lastMethod?: 'Sms' | 'Voice' | 'Email';
|
|
1338
|
+
/** Wallet address used for wallet authentication */
|
|
1339
|
+
address?: string;
|
|
1340
|
+
constructor(apiKey: string, baseURL: string, options?: ErmisChatOptions);
|
|
1341
|
+
_logApiRequest(type: string, url: string, data: unknown, config: AxiosRequestConfig & {
|
|
1342
|
+
config?: AxiosRequestConfig & {
|
|
1343
|
+
maxBodyLength?: number;
|
|
1344
|
+
};
|
|
1345
|
+
}): void;
|
|
1346
|
+
_logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>): void;
|
|
1347
|
+
_logApiError(type: string, url: string, error: unknown, options: unknown): void;
|
|
1348
|
+
doAxiosRequest: <T>(type: string, url: string, data?: unknown, options?: AxiosRequestConfig & {
|
|
1349
|
+
config?: AxiosRequestConfig & {
|
|
1350
|
+
maxBodyLength?: number;
|
|
1351
|
+
};
|
|
1352
|
+
}) => Promise<T>;
|
|
1353
|
+
get<T>(url: string, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1354
|
+
put<T>(url: string, data?: unknown): Promise<T>;
|
|
1355
|
+
post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1356
|
+
patch<T>(url: string, data?: unknown): Promise<T>;
|
|
1357
|
+
delete<T>(url: string, params?: AxiosRequestConfig['params']): Promise<T>;
|
|
1358
|
+
errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse>;
|
|
1359
|
+
handleResponse<T>(response: AxiosResponse<T>): T;
|
|
1360
|
+
getUserAgent(): string;
|
|
1361
|
+
setUserAgent(userAgent: string): void;
|
|
1362
|
+
_enrichAxiosOptions(options?: AxiosRequestConfig & {
|
|
1363
|
+
config?: AxiosRequestConfig;
|
|
1364
|
+
}): AxiosRequestConfig;
|
|
1365
|
+
/**
|
|
1366
|
+
* Send OTP to a phone number.
|
|
1367
|
+
* @param identifier Phone number
|
|
1368
|
+
* @param language Language code (e.g. 'En', 'Vi')
|
|
1369
|
+
* @param method Method type (e.g. 'Sms', 'Voice')
|
|
1370
|
+
*/
|
|
1371
|
+
sendOtpToPhone(identifier: string, method: 'Sms' | 'Voice'): Promise<{
|
|
1372
|
+
success: boolean;
|
|
1373
|
+
message?: string;
|
|
1374
|
+
}>;
|
|
1375
|
+
/**
|
|
1376
|
+
* Send OTP to a email.
|
|
1377
|
+
* @param identifier Email address
|
|
1378
|
+
* @param language Language code (e.g. 'En', 'Vi')
|
|
1379
|
+
* @param method Method type (e.g. 'Email')
|
|
1380
|
+
*/
|
|
1381
|
+
sendOtpToEmail(identifier: string): Promise<{
|
|
1382
|
+
success: boolean;
|
|
1383
|
+
message?: string;
|
|
1384
|
+
}>;
|
|
1385
|
+
/**
|
|
1386
|
+
* Verify OTP for phone or email.
|
|
1387
|
+
* @param otp OTP code
|
|
1388
|
+
*/
|
|
1389
|
+
verifyOtp(otp: string): Promise<{
|
|
1390
|
+
success: boolean;
|
|
1391
|
+
message?: string;
|
|
1392
|
+
}>;
|
|
1393
|
+
/**
|
|
1394
|
+
* Login with Google.
|
|
1395
|
+
* @param token Google OAuth token
|
|
1396
|
+
* @param apikey API key
|
|
1397
|
+
*/
|
|
1398
|
+
loginWithGoogle(token: string): Promise<{
|
|
1399
|
+
success: boolean;
|
|
1400
|
+
message?: string;
|
|
1401
|
+
}>;
|
|
1402
|
+
/**
|
|
1403
|
+
* Get challenge for wallet login.
|
|
1404
|
+
* @param address Wallet address
|
|
1405
|
+
* @param apiKey API key
|
|
1406
|
+
*/
|
|
1407
|
+
getWalletChallenge(address: string): Promise<any>;
|
|
1408
|
+
private createNonce;
|
|
1409
|
+
/**
|
|
1410
|
+
* Verify wallet signature after receiving the challenge.
|
|
1411
|
+
* @param address Wallet address
|
|
1412
|
+
* @param signature Signature generated by the wallet
|
|
1413
|
+
* @param nonce Nonce used in the challenge
|
|
1414
|
+
* @returns Verification result and token if successful
|
|
1415
|
+
*/
|
|
1416
|
+
verifyWalletSignature(signature: string): Promise<{
|
|
1417
|
+
success: boolean;
|
|
1418
|
+
token?: string;
|
|
1419
|
+
message?: string;
|
|
1420
|
+
}>;
|
|
1421
|
+
}
|
|
1422
|
+
|
|
1423
|
+
/**
|
|
1424
|
+
* logChatPromiseExecution - utility function for logging the execution of a promise..
|
|
1425
|
+
* use this when you want to run the promise and handle errors by logging a warning
|
|
1426
|
+
*
|
|
1427
|
+
* @param {Promise<T>} promise The promise you want to run and log
|
|
1428
|
+
* @param {string} name A descriptive name of what the promise does for log output
|
|
1429
|
+
*
|
|
1430
|
+
*/
|
|
1431
|
+
declare function logChatPromiseExecution<T>(promise: Promise<T>, name: string): void;
|
|
1432
|
+
declare const chatCodes: {
|
|
1433
|
+
TOKEN_EXPIRED: number;
|
|
1434
|
+
WS_CLOSED_SUCCESS: number;
|
|
1435
|
+
};
|
|
1436
|
+
/**
|
|
1437
|
+
* formatMessage - Takes the message object. Parses the dates, sets __html
|
|
1438
|
+
* and sets the status to received if missing. Returns a message object
|
|
1439
|
+
*
|
|
1440
|
+
* @param {MessageResponse<ErmisChatGenerics>} message a message object
|
|
1441
|
+
*
|
|
1442
|
+
*/
|
|
1443
|
+
declare function formatMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(message: MessageResponse<ErmisChatGenerics>): FormatMessageResponse<ErmisChatGenerics>;
|
|
1444
|
+
declare const createForwardMessagePayload: <ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(message: FormatMessageResponse<ErmisChatGenerics>, targetCid: string, activeCid: string) => ForwardMessage<ErmisChatGenerics>;
|
|
1445
|
+
|
|
1446
|
+
/**
|
|
1447
|
+
* Parse a raw system message string into a human-readable English sentence.
|
|
1448
|
+
*
|
|
1449
|
+
* The raw format is: `"<formatId> <userID> [<param1> <param2> ...]"`
|
|
1450
|
+
*
|
|
1451
|
+
* @param value - Raw system message string from the server
|
|
1452
|
+
* @param userMap - Mapping of user IDs → display names
|
|
1453
|
+
* @returns Parsed English text, or the original string if the format is unknown
|
|
1454
|
+
*/
|
|
1455
|
+
declare function parseSystemMessage(value: string, userMap: Record<string, string>): string;
|
|
1456
|
+
|
|
1457
|
+
/**
|
|
1458
|
+
* Parse a raw signal message string into a human-readable English sentence.
|
|
1459
|
+
*
|
|
1460
|
+
* Signal messages represent call events. The raw format is:
|
|
1461
|
+
* `"<formatId> <userID> [<param1> <param2> ...]"`
|
|
1462
|
+
*
|
|
1463
|
+
* @param value - Raw signal message string from the server
|
|
1464
|
+
* @param userMap - Mapping of user IDs → display names
|
|
1465
|
+
* @returns Parsed English text, or the original string if unknown
|
|
1466
|
+
*/
|
|
1467
|
+
declare function parseSignalMessage(value: string, userMap: Record<string, string>): string;
|
|
1468
|
+
|
|
1469
|
+
export { type APIErrorResponse, type APIResponse, type AscDesc, type Attachment, type AttachmentResponse, type AudioConfig, CallAction, type CallEventData, type CallEventType, CallStatus, Channel, type ChannelAPIResponse, type ChannelData, type ChannelFilters, type ChannelMemberResponse, type ChannelMembership, type ChannelQueryOptions, type ChannelResponse, type ChannelSort, ChannelState, type ChannelStateOptions, ClientState, type ConnectAPIResponse, type ConnectionOpen, type Contact, type ContactResponse, type ContactResult, type DefaultGenerics, EVENT_MAP, type EditMessage, ErmisAuthProvider, ErmisCallNode, ErmisChat, type ErmisChatOptions, ErrorFromResponse, type Event$1 as Event, type EventHandler, type EventTypes, type ExtendableGenerics, FRAME_TYPE, type FormatMessageResponse, type ForwardMessage, type IMediaReceiverEvents, type INodeCall, type LiteralStringForUnion, type LogLevel, type Logger, type Message, type MessageBase, type MessageLabel, type MessageResponse, type MessageResponseBase, type MessageSetType, type Metadata, type PollMessage, type QueryChannelAPIResponse, type QueryChannelsAPIResponse, type Reaction, type ReactionAPIResponse, type ReactionResponse, type ReadResponse, type Role, type SendFileAPIResponse, type SendMessageAPIResponse, type SignalData, StableWSConnection, TokenManager, type TransceiverState, type UR, type UpdateChannelAPIResponse, type UserCallInfo, type UserResponse, type UsersResponse, type VideoConfig, type VoiceRecordingMeta, buildAttachmentPayload, chatCodes, createForwardMessagePayload, formatMessage, getAttachmentCategory, isHeicFile, isVideoFile, logChatPromiseExecution, normalizeFileName, parseSignalMessage, parseSystemMessage };
|