@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.
@@ -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 };