@ermis-network/ermis-chat-sdk 1.0.3 → 1.0.4
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/dist/index.browser.cjs +122 -2
- package/dist/index.browser.cjs.map +1 -1
- package/dist/index.browser.full-bundle.min.js +2 -2
- package/dist/index.browser.full-bundle.min.js.map +1 -1
- package/dist/index.browser.mjs +122 -2
- package/dist/index.browser.mjs.map +1 -1
- package/dist/index.cjs +122 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.mts +173 -0
- package/dist/index.d.ts +173 -0
- package/dist/index.mjs +122 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
- package/src/channel.ts +42 -0
- package/src/channel_state.ts +27 -0
- package/src/client.ts +104 -0
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/client.ts","../src/shims/empty.ts","../src/utils.ts","../src/channel_state.ts","../src/attachment_utils.ts","../src/channel.ts","../src/client_state.ts","../src/connection.ts","../src/token_manager.ts","../src/errors.ts","../src/types.ts","../src/events.ts","../src/wasm/ermis_call_node_wasm.js","../src/media_stream_sender.ts","../src/hevc_decoder_config.ts","../src/media_stream_receiver.ts","../src/ermis_call_node.ts","../src/auth.ts","../src/system_message.ts","../src/signal_message.ts"],"sourcesContent":["/* eslint no-unused-vars: \"off\" */\n/* global process */\n\nimport axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport https from 'https';\nimport WebSocket from 'isomorphic-ws';\n\nimport { Channel } from './channel';\nimport { ClientState } from './client_state';\nimport { StableWSConnection } from './connection';\n\nimport { TokenManager } from './token_manager';\n\nimport { isErrorResponse } from './errors';\nimport { EventSourcePolyfill } from 'event-source-polyfill';\nimport {\n addFileToFormData,\n axiosParamsSerializer,\n enrichWithUserInfo,\n ensureMembersUserInfoLoaded,\n getDirectChannelImage,\n getDirectChannelName,\n getLatestCreatedAt,\n isFunction,\n randomId,\n} from './utils';\n\nimport {\n APIErrorResponse,\n APIResponse,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelSort,\n ChannelStateOptions,\n ConnectAPIResponse,\n DefaultGenerics,\n ErrorFromResponse,\n Event,\n EventHandler,\n ExtendableGenerics,\n Logger,\n QueryChannelsAPIResponse,\n SendFileAPIResponse,\n ErmisChatOptions,\n UserResponse,\n ContactResponse,\n UsersResponse,\n ContactResult,\n Contact,\n} from './types';\n\nfunction isString(x: unknown): x is string {\n return typeof x === 'string' || x instanceof String;\n}\nexport class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n private static _instance?: unknown | ErmisChat; // type is undefined|ErmisChat, unknown is due to TS limitations with statics\n\n activeChannels: {\n [key: string]: Channel<ErmisChatGenerics>;\n };\n axiosInstance: AxiosInstance;\n baseURL?: string;\n userBaseURL?: string;\n browser: boolean;\n cleaningIntervalRef?: NodeJS.Timeout;\n clientID?: string;\n apiKey: string;\n projectId: string;\n listeners: Record<string, Array<(event: Event<ErmisChatGenerics>) => void>>;\n logger: Logger;\n recoverStateOnReconnect?: boolean;\n node: boolean;\n options: ErmisChatOptions;\n setUserPromise: ConnectAPIResponse<ErmisChatGenerics> | null;\n state: ClientState<ErmisChatGenerics>;\n tokenManager: TokenManager<ErmisChatGenerics>;\n user?: UserResponse<ErmisChatGenerics>;\n userAgent?: string;\n userID?: string;\n wsBaseURL?: string;\n wsConnection: StableWSConnection<ErmisChatGenerics> | null;\n wsPromise: ConnectAPIResponse<ErmisChatGenerics> | null;\n consecutiveFailures: number;\n defaultWSTimeout: number;\n\n private eventSource: EventSourcePolyfill | null = null;\n\n constructor(apiKey: string, projectId: string, baseURL: string, options?: ErmisChatOptions) {\n this.apiKey = apiKey;\n this.projectId = projectId;\n this.listeners = {};\n this.state = new ClientState<ErmisChatGenerics>();\n\n const inputOptions = options || {};\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n\n this.options = {\n withCredentials: false,\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n\n this.axiosInstance = axios.create(this.options);\n\n this.setBaseURL(baseURL);\n\n // WS connection is initialized when setUser is called\n this.wsConnection = null;\n this.wsPromise = null;\n this.setUserPromise = null;\n // keeps a reference to all the channels that are in use\n this.activeChannels = {};\n\n this.tokenManager = new TokenManager();\n this.consecutiveFailures = 0;\n this.defaultWSTimeout = 15000;\n\n this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;\n\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;\n }\n\n public static getInstance<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n projectId: string,\n baseURL: string,\n options?: ErmisChatOptions,\n ): ErmisChat<ErmisChatGenerics> {\n if (!ErmisChat._instance) {\n ErmisChat._instance = new ErmisChat<ErmisChatGenerics>(key, projectId, baseURL, options);\n }\n\n return ErmisChat._instance as ErmisChat<ErmisChatGenerics>;\n }\n\n async refreshNewToken(refresh_token: string) {\n return await this.post<APIResponse>(this.userBaseURL + '/refresh_token', { refresh_token });\n }\n\n getAuthType() {\n return 'jwt';\n }\n\n setBaseURL(baseURL: string) {\n this.baseURL = baseURL;\n this.userBaseURL = this.options.userBaseURL || baseURL + '/uss/v1';\n this.wsBaseURL = this.baseURL.replace('http', 'ws').replace(':3030', ':8800');\n }\n\n async getExternalAuthToken(user: UserResponse<ErmisChatGenerics>, token: string | null) {\n const params: any = { apikey: this.apiKey, name: user.name };\n if (user.avatar) {\n params.avatar = user.avatar;\n }\n const url = this.userBaseURL + '/get_token/external_auth';\n const query = new URLSearchParams(params).toString();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) {\n const tokenStr = typeof token === 'string' && token.startsWith('Bearer ') ? token : `Bearer ${token}`;\n headers['Authorization'] = tokenStr;\n }\n const response = await fetch(`${url}?${query}`, {\n method: 'GET',\n headers,\n });\n if (!response.ok) {\n let errorMsg = '';\n try {\n const errorData = await response.json();\n errorMsg = errorData.message || JSON.stringify(errorData);\n } catch {\n errorMsg = await response.text();\n }\n throw new Error(errorMsg);\n }\n return await response.json();\n }\n\n connectUser = async (\n user: UserResponse<ErmisChatGenerics>,\n userTokenOrProvider: string | null,\n extenal_auth?: boolean, // pass true if you are using external auth\n ) => {\n this.logger('info', 'client:connectUser() - started', {\n tags: ['connection', 'client'],\n });\n if (!user.id) {\n throw new Error('The \"id\" field on the user is missing');\n }\n\n // If external auth is enabled, get the token from the server\n if (extenal_auth) {\n const external_auth_token = await this.getExternalAuthToken(user, userTokenOrProvider);\n\n userTokenOrProvider = external_auth_token.token;\n user.id = external_auth_token.user_id;\n }\n\n /**\n * Calling connectUser multiple times is potentially the result of a bad integration, however,\n * If the user id remains the same we don't throw error\n */\n if (this.userID === user.id && this.setUserPromise) {\n console.warn(\n 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',\n );\n return this.setUserPromise;\n }\n\n if (this.userID) {\n throw new Error(\n 'Use client.disconnect() before trying to connect as a different user. connectUser was called twice.',\n );\n }\n\n if (this.node && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n // we generate the client id client side\n this.userID = user.id;\n\n const setTokenPromise = this._setToken(user, userTokenOrProvider);\n this._setUser(user);\n this.state.updateUser({ id: user.id, name: user?.name || user.id, avatar: user?.avatar || '' });\n\n const wsPromise = this.openConnection();\n\n this.setUserPromise = Promise.all([setTokenPromise, wsPromise]).then(\n (result) => result[1], // We only return connection promise;\n );\n\n try {\n const result = await this.setUserPromise;\n // Call SSE after successful connect\n await this.connectToSSE();\n return result;\n } catch (err) {\n this.disconnectUser();\n throw err;\n }\n };\n\n setUser = this.connectUser;\n\n _setToken = (user: UserResponse<ErmisChatGenerics>, userTokenOrProvider: string | null) =>\n this.tokenManager.setTokenOrProvider(userTokenOrProvider, user);\n\n _setUser(user: UserResponse<ErmisChatGenerics>) {\n this.user = { ...user };\n this.userID = user.id;\n }\n\n closeConnection = async (timeout?: number) => {\n if (this.cleaningIntervalRef != null) {\n clearInterval(this.cleaningIntervalRef);\n this.cleaningIntervalRef = undefined;\n }\n\n await this.wsConnection?.disconnect(timeout);\n return Promise.resolve();\n };\n\n openConnection = async () => {\n if (!this.userID) {\n throw Error('User is not set on client, use client.connectUser instead');\n }\n\n if (this.wsConnection?.isConnecting && this.wsPromise) {\n this.logger('info', 'client:openConnection() - connection already in progress', {\n tags: ['connection', 'client'],\n });\n return this.wsPromise;\n }\n\n if (this.wsConnection?.isHealthy) {\n this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists', {\n tags: ['connection', 'client'],\n });\n\n return Promise.resolve();\n }\n\n this.clientID = `${this.userID}--${randomId()}`;\n this.wsPromise = this.connect();\n this._startCleaning();\n return this.wsPromise;\n };\n\n _setupConnection = this.openConnection;\n\n disconnectUser = async (timeout?: number) => {\n this.logger('info', 'client:disconnect() - Disconnecting the client', {\n tags: ['connection', 'client'],\n });\n\n // remove the user specific fields\n delete this.user;\n delete this.userID;\n\n const closePromise = this.closeConnection(timeout);\n\n for (const channel of Object.values(this.activeChannels)) {\n channel._disconnect();\n }\n // ensure we no longer return inactive channels\n this.activeChannels = {};\n // reset client state\n this.state = new ClientState();\n // reset token manager\n setTimeout(this.tokenManager.reset); // delay reseting to use token for disconnect calls\n\n // close the WS connection\n return closePromise;\n };\n\n disconnect = this.disconnectUser;\n\n on(callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(eventType: string, callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<ErmisChatGenerics> | string,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<ErmisChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this.logger('info', `Attaching listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key].push(callback);\n return {\n unsubscribe: () => {\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n off(callback: EventHandler<ErmisChatGenerics>): void;\n off(eventType: string, callback: EventHandler<ErmisChatGenerics>): void;\n off(callbackOrString: EventHandler<ErmisChatGenerics> | string, callbackOrNothing?: EventHandler<ErmisChatGenerics>) {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<ErmisChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger(\n 'info',\n `client: ${type} - Request - ${url}- ${JSON.stringify(data)} - ${JSON.stringify(config.params)}`,\n {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n },\n );\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown, options: unknown) {\n this.logger(\n 'error',\n `client:${type} - Error: ${JSON.stringify(error)} - url: ${url} - options: ${JSON.stringify(options)}`,\n {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n },\n );\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n await this.tokenManager.tokenReady();\n\n const requestConfig = this._enrichAxiosOptions(options);\n\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e, options);\n this.consecutiveFailures += 1;\n if (e.response) {\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('post', url, data, { params });\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n\n sendFile(\n url: string,\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<ErmisChatGenerics>,\n ) {\n const data = addFileToFormData(uri, name, contentType || 'multipart/form-data');\n if (user != null) data.append('user', JSON.stringify(user));\n\n return this.doAxiosRequest<SendFileAPIResponse>('postForm', url, data, {\n headers: data.getHeaders ? data.getHeaders() : {}, // node vs browser\n config: {\n timeout: 0,\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n },\n });\n }\n\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`ErmisChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`ErmisChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n dispatchEvent = (event: Event<ErmisChatGenerics>) => {\n if (!event.received_at) event.received_at = new Date();\n\n // If the event is channel.created, handle it asynchronously\n if (event.type === 'channel.created') {\n this._handleChannelCreatedEvent(event).then(() => {\n this._afterDispatchEvent(event);\n });\n } else {\n const postListenerCallbacks = this._handleClientEvent(event);\n\n // channel event handlers\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n }\n };\n\n _afterDispatchEvent(event: Event<ErmisChatGenerics>) {\n const postListenerCallbacks = this._handleClientEvent(event);\n\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n }\n\n private async _handleChannelCreatedEvent(event: Event<ErmisChatGenerics>) {\n const members = event.channel?.members || [];\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this, members);\n\n // Get the latest users after updating\n const updatedUsers = Object.values(this.state.users);\n\n const enrichedMembers = enrichWithUserInfo(members, updatedUsers);\n const channelName =\n event.channel_type === 'messaging'\n ? getDirectChannelName(enrichedMembers, this.userID || '')\n : event.channel?.name;\n const channel = {\n ...event.channel,\n members: enrichedMembers,\n name: channelName,\n };\n const channelState: any = {\n channel,\n members: enrichedMembers,\n messages: [],\n pinned_messages: [],\n };\n const c = this.channel(event.channel_type || '', event.channel_id || '');\n c.data = channel;\n c._initializeState(channelState, 'latest');\n }\n\n handleEvent = (messageEvent: WebSocket.MessageEvent) => {\n // dispatch the event to the channel listeners\n const jsonString = messageEvent.data as string;\n const event = JSON.parse(jsonString) as Event<ErmisChatGenerics>;\n this.dispatchEvent(event);\n };\n\n _updateMemberWatcherReferences = (user: UserResponse<ErmisChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n if (channel?.state) {\n if (channel.state.members[user.id]) {\n channel.state.members[user.id].user = user;\n }\n if (channel.state.watchers[user.id]) {\n channel.state.watchers[user.id] = user;\n }\n if (channel.state.read[user.id]) {\n channel.state.read[user.id].user = user;\n }\n }\n }\n };\n\n _updateUserReferences = this._updateMemberWatcherReferences;\n\n _updateUserMessageReferences = (user: UserResponse<ErmisChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n\n if (!channel) continue;\n\n const state = channel.state;\n\n /** update the messages from this user. */\n state?.updateUserMessages(user);\n }\n };\n\n _deleteUserMessageReference = (user: UserResponse<ErmisChatGenerics>, hardDelete = false) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n const state = channel.state;\n\n /** deleted the messages from this user. */\n state?.deleteUserMessages(user, hardDelete);\n }\n };\n\n _handleClientEvent(event: Event<ErmisChatGenerics>) {\n const client = this;\n const postListenerCallbacks = [];\n this.logger('info', `client:_handleClientEvent - Received event of type { ${event.type} }`, {\n tags: ['event', 'client'],\n event,\n });\n\n if (event.type === 'health.check' && event.me) {\n }\n\n if ((event.type === 'channel.deleted' || event.type === 'notification.channel_deleted') && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n\n for (const channel of Object.values(this.activeChannels)) {\n if (channel.type === 'team' && channel.state.topics?.some((t) => t.cid === event.cid)) {\n // Remove the topic with matching cid from the topics array\n channel.state.topics = channel.state.topics.filter((t) => t.cid !== event.cid);\n }\n }\n }\n if (event.type === 'notification.invite_rejected') {\n if (event.member?.user_id === this.userID && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n }\n }\n if (event.type === 'notification.invite_accepted') {\n //TODO handle channel list and invited channels here\n }\n\n if (event.type === 'member.added') {\n if (event.member?.user_id === this.userID) {\n const c = this.channel(event.channel_type || '', event.channel_id || '');\n // Gọi watch để lấy đầy đủ thông tin channel từ server\n c.watch().catch((err) => {\n this.logger('error', 'Failed to watch channel after member.added', { err, event });\n });\n }\n }\n\n if (event.type === 'connection.recovered') {\n postListenerCallbacks.push(() => {\n // Auto-resend offline failed messages\n Object.values(this.activeChannels).forEach((channel) => {\n if (!channel.state?.messages) return;\n const offlineFailedMsgs = channel.state.messages.filter(\n (m) =>\n m.status === 'failed_offline' &&\n m.user?.id === this.userID &&\n (!m.attachments || m.attachments.length === 0),\n );\n offlineFailedMsgs.forEach((msg) => {\n if (msg.id) {\n channel.retryMessage(msg.id).catch((err) => {\n this.logger('error', `Failed to auto-resend offline message ${msg.id}`, {\n tags: ['offline', 'retry'],\n err,\n });\n });\n }\n });\n });\n });\n }\n\n return postListenerCallbacks;\n }\n\n _callClientListeners = (event: Event<ErmisChatGenerics>) => {\n const client = this;\n // gather and call the listeners\n const listeners: Array<(event: Event<ErmisChatGenerics>) => void> = [];\n if (client.listeners.all) {\n listeners.push(...client.listeners.all);\n }\n if (client.listeners[event.type]) {\n listeners.push(...client.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n listener(event);\n }\n };\n\n recoverState = async () => {\n this.logger('info', 'client:recoverState() - Start of recoverState', {\n tags: ['connection'],\n });\n\n const cids = Object.keys(this.activeChannels);\n if (cids.length && this.recoverStateOnReconnect) {\n this.logger('info', `client:recoverState() - Start the querying of ${cids.length} channels`, {\n tags: ['connection', 'client'],\n });\n\n const filter: ChannelFilters = {\n type: ['messaging', 'team'],\n };\n const sort: [] = [];\n const options = {\n message_limit: 25,\n };\n\n await this.queryChannels(filter, sort, options);\n\n this.logger('info', 'client:recoverState() - Querying channels finished', { tags: ['connection', 'client'] });\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<ErmisChatGenerics>);\n } else {\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<ErmisChatGenerics>);\n }\n\n this.wsPromise = Promise.resolve();\n this.setUserPromise = Promise.resolve();\n };\n\n async connect() {\n if (!this.userID || !this.user) {\n throw Error('Call connectUser before starting the connection');\n }\n if (!this.wsBaseURL) {\n throw Error('Websocket base url not set');\n }\n if (!this.clientID) {\n throw Error('clientID is not set');\n }\n\n // if (!this.wsConnection && (this.options.warmUp || this.options.enableInsights)) {\n // this._sayHi();\n // }\n // The StableWSConnection handles all the reconnection logic.\n if (this.options.wsConnection && this.node) {\n // Intentionally avoiding adding ts generics on wsConnection in options since its only useful for unit test purpose.\n (this.options.wsConnection as unknown as StableWSConnection<ErmisChatGenerics>).setClient(this);\n this.wsConnection = this.options.wsConnection as unknown as StableWSConnection<ErmisChatGenerics>;\n } else {\n this.wsConnection = new StableWSConnection<ErmisChatGenerics>({\n client: this,\n });\n }\n\n try {\n return await this.wsConnection.connect(this.defaultWSTimeout);\n } catch (err: any) {\n throw err;\n }\n }\n public async connectToSSE(onCallBack?: (data: any) => void): Promise<void> {\n if (this.eventSource) {\n this.logger('info', 'client:connectToSSE() - SSE connection already established', {});\n return;\n }\n let token = this._getToken();\n\n if (!token?.startsWith('Bearer ')) {\n token = `Bearer ${token}`;\n }\n const headers = {\n method: 'GET',\n Authorization: token,\n };\n this.eventSource = new EventSourcePolyfill(this.userBaseURL + '/sse/subscribe', {\n headers,\n heartbeatTimeout: 60000,\n });\n this.eventSource.onopen = () => {\n this.logger('info', 'client:connectToSSE() - SSE connection established', {});\n };\n this.eventSource.onmessage = (event) => {\n const data = JSON.parse(event.data);\n\n this.logger('info', `client:connectToSSE() - SSE message received event : ${JSON.stringify(data)}`, { event });\n\n if (data.type === 'AccountUserChainProjects') {\n let user: UserResponse = {\n name: data.name,\n id: data.id,\n avatar: data.avatar,\n about_me: data.about_me,\n project_id: data.project_id,\n };\n\n if (this.user?.id === user.id) {\n this.user = { ...this.user, ...user };\n }\n\n this.state.updateUser(user);\n\n const userInfo = {\n id: user.id,\n name: user.name ? user.name : user.id,\n avatar: user?.avatar || '',\n };\n\n this._updateMemberWatcherReferences(userInfo);\n this._updateUserMessageReferences(userInfo);\n\n Object.values(this.activeChannels).forEach((channel) => {\n if (channel.data?.type === 'messaging' && Object.keys(channel.state.members).length === 2) {\n const otherMember = Object.values(channel.state.members).find((member) => member.user?.id !== this.userID);\n if (otherMember && otherMember.user?.id === user.id) {\n // Cập nhật tên và avatar channel theo user vừa đổi thông tin\n channel.data.name = user.name || user.id;\n channel.data.image = user.avatar || '';\n }\n }\n });\n\n if (onCallBack) {\n onCallBack(data);\n }\n }\n };\n this.eventSource.onerror = (event: any) => {\n this.logger('error', `client:connectToSSE() - SSE connection error : ${JSON.stringify(event.data)} `, { event });\n if (event.status === 401) {\n this.logger('error', 'client:connectToSSE() - Unauthorized (401). Aborting the connection.', {});\n this.disconnectFromSSE();\n } else if (\n this.eventSource?.readyState === EventSourcePolyfill.CLOSED ||\n this.eventSource?.readyState === EventSourcePolyfill.CONNECTING\n ) {\n this.eventSource.close();\n setTimeout(() => {\n this.logger('info', 'client:connectToSSE() - Reconnecting to SSE', {});\n this.connectToSSE(onCallBack);\n }, 3000);\n }\n };\n }\n public async disconnectFromSSE(): Promise<void> {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n this.logger('info', 'client:disconnectFromSSE() - SSE connection closed', {});\n } else {\n this.logger('info', 'client:disconnectFromSSE() - SSE connection already closed', {});\n }\n }\n\n async queryUsers(page_size?: string, page?: number): Promise<UsersResponse> {\n const defaultOptions = {\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n let project_id = this.projectId;\n // Return a list of users\n const data = await this.get<UsersResponse>(this.userBaseURL + '/users', {\n project_id,\n page,\n page_size,\n });\n\n this.state.updateUsers(data.data);\n\n return data;\n }\n\n async queryUser(user_id: string): Promise<UserResponse<ErmisChatGenerics>> {\n const project_id = this.projectId;\n\n const userResponse = await this.get<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/' + user_id, {\n project_id,\n });\n\n this.state.updateUser(userResponse);\n return userResponse;\n }\n\n async getBatchUsers(users: string[], page?: number, page_size?: number) {\n let project_id = this.projectId;\n\n const usersRepsonse = await this.post<UsersResponse>(\n this.userBaseURL + '/users/batch?page=1&page_size=10000',\n { users, project_id },\n { page, page_size },\n );\n\n this.state.updateUsers(usersRepsonse.data);\n\n return usersRepsonse.data || [];\n }\n\n async searchUsers(page: number, page_size: number, name?: string): Promise<UsersResponse> {\n let project_id = this.projectId;\n\n const usersResponse = await this.post<UsersResponse>(this.userBaseURL + '/users/search', undefined, {\n page,\n page_size,\n name,\n project_id,\n });\n\n // this.state.updateUsers(usersResponse.data);\n\n return usersResponse;\n }\n\n async queryContacts(): Promise<ContactResult> {\n let project_id = this.projectId;\n const contactResponse = await this.post<ContactResponse>(this.baseURL + '/contacts/list', { project_id });\n const userIds = contactResponse.project_id_user_ids[project_id];\n const contact_users: UserResponse<ErmisChatGenerics>[] = [];\n const block_users: UserResponse<ErmisChatGenerics>[] = [];\n\n userIds.forEach((contact: Contact) => {\n const userID = contact.other_id;\n const state_user = this.state.users[userID];\n const user = state_user ? state_user : { id: userID };\n switch (contact.relation_status) {\n case 'blocked':\n block_users.push(user);\n break;\n case 'normal':\n contact_users.push(user);\n break;\n default:\n }\n });\n\n return {\n contact_users,\n block_users,\n };\n }\n\n _updateProjectID(project_id: string) {\n this.projectId = project_id;\n }\n\n async uploadFile(file: File) {\n const formData = new FormData();\n formData.append('avatar', file);\n let response = await this.post<{ avatar: string }>(this.userBaseURL + '/users/upload', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n if (this.user) {\n this.user.avatar = response.avatar;\n const new_user = { ...this.user, avatar: response.avatar };\n this.state.updateUser(new_user);\n }\n\n return response;\n }\n async updateProfile(name: string, about_me: string) {\n let body = {\n name,\n about_me,\n };\n let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', body);\n this.user = response;\n this.state.updateUser(response);\n return response;\n }\n\n async queryChannels(\n filterConditions: ChannelFilters,\n sort: ChannelSort = [],\n options: { message_limit?: number } = {},\n stateOptions: ChannelStateOptions = {},\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n let project_id = this.projectId;\n\n // Return a list of channels\n const payload = {\n filter_conditions: { ...filterConditions, project_id },\n sort,\n ...options,\n };\n\n const data = await this.post<QueryChannelsAPIResponse<ErmisChatGenerics>>(this.baseURL + '/channels', payload);\n\n // Sort channels by latest message created_at (including topics if present)\n data.channels.sort((a, b) => {\n // Get latest message created_at in channel a\n let aLatest = getLatestCreatedAt(a.messages);\n\n // If channel a has topics, check messages in topics\n if (a.channel.type === 'team' && Array.isArray(a.topics)) {\n for (const topic of a.topics) {\n aLatest = Math.max(aLatest, getLatestCreatedAt(topic.messages));\n }\n }\n\n // Get latest message created_at in channel b\n let bLatest = getLatestCreatedAt(b.messages);\n\n // If channel b has topics, check messages in topics\n if (b.channel.type === 'team' && Array.isArray(b.topics)) {\n for (const topic of b.topics) {\n bLatest = Math.max(bLatest, getLatestCreatedAt(topic.messages));\n }\n }\n\n // Descending order (newest first)\n return bLatest - aLatest;\n });\n\n const memberIds =\n Array.from(\n new Set(data.channels.flatMap((c) => (c.channel.members || []).map((member: any) => member.user.id))),\n ) || [];\n\n const membersInfo = filterConditions.parent_cid\n ? Object.values(this.state.users)\n : await this.getBatchUsers(memberIds);\n data.channels.forEach((c) => {\n c.channel.members = enrichWithUserInfo(c.channel.members, membersInfo);\n c.messages = enrichWithUserInfo(c.messages, membersInfo);\n c.read = enrichWithUserInfo(c.read || [], membersInfo);\n c.channel.name =\n c.channel.type === 'messaging' ? getDirectChannelName(c.channel.members, this.userID || '') : c.channel.name;\n c.channel.image =\n c.channel.type === 'messaging' ? getDirectChannelImage(c.channel.members, this.userID || '') : c.channel.image;\n\n if (c.channel.type === 'team' && Array.isArray(c.topics)) {\n c.topics.sort((a, b) => {\n const aLatest = getLatestCreatedAt(a.messages);\n const bLatest = getLatestCreatedAt(b.messages);\n return bLatest - aLatest;\n });\n }\n\n if (c.pinned_messages) {\n c.pinned_messages = enrichWithUserInfo(c.pinned_messages || [], membersInfo);\n }\n });\n\n const { channels, userIds } = this.hydrateChannels(data.channels, stateOptions);\n\n // if (userIds.length > 0) {\n // await this.getBatchUsers(userIds);\n // }\n\n console.log('---channels---', channels);\n\n return channels;\n }\n\n hydrateChannels(\n channelsFromApi: ChannelAPIResponse<ErmisChatGenerics>[] = [],\n stateOptions: ChannelStateOptions = {},\n ) {\n const { skipInitialization, offlineMode = false } = stateOptions;\n\n const channels: Channel<ErmisChatGenerics>[] = [];\n const userIds: string[] = [];\n for (const channelState of channelsFromApi) {\n const c = this.channel(channelState.channel.type, channelState.channel.id);\n c.data = { ...channelState.channel, is_pinned: channelState.is_pinned || false };\n c.offlineMode = offlineMode;\n c.initialized = !offlineMode;\n\n if (skipInitialization === undefined) {\n c._initializeState(channelState, 'latest', (id) => {\n if (!userIds.includes(id)) {\n userIds.push(id);\n }\n });\n } else if (!skipInitialization.includes(channelState.channel.id)) {\n c.state.clearMessages();\n c._initializeState(channelState, 'latest', (id) => {\n if (!userIds.includes(id)) {\n userIds.push(id);\n }\n });\n }\n\n channels.push(c);\n }\n\n // const sortedChannels = channels.sort((a: any, b: any) => {\n // const aTime = a.state.last_message_at\n // ? new Date(a.state.last_message_at).getTime()\n // : a.data.created_at\n // ? new Date(a.data.created_at).getTime()\n // : 0;\n // const bTime = b.state.last_message_at\n // ? new Date(b.state.last_message_at).getTime()\n // : b.data.created_at\n // ? new Date(b.data.created_at).getTime()\n // : 0;\n // return bTime - aTime; // Descending order\n // });\n\n // ensure we have the users for all the channels we just added\n\n return { channels, userIds };\n }\n\n async searchPublicChannel(search_term: string, offset = 0, limit = 25) {\n let project_id = this.projectId;\n\n return await this.post<APIResponse>(this.baseURL + `/channels/public/search`, {\n project_id,\n search_term,\n limit: limit,\n offset: offset,\n });\n }\n\n async pinChannel(channelType: string, channelId: string) {\n return await this.post<APIResponse>(this.baseURL + `/channels/${channelType}/${channelId}/pin`);\n }\n\n async unpinChannel(channelType: string, channelId: string) {\n return await this.post<APIResponse>(this.baseURL + `/channels/${channelType}/${channelId}/unpin`);\n }\n\n channel(type: string, custom?: ChannelData<ErmisChatGenerics>): Channel<ErmisChatGenerics>;\n channel(type: string, id: string, custom?: ChannelData<ErmisChatGenerics>): Channel<ErmisChatGenerics>;\n channel(\n channelType: string,\n channelIDOrCustom?: string | ChannelData<ErmisChatGenerics>,\n custom?: ChannelData<ErmisChatGenerics>,\n ): Channel<ErmisChatGenerics> {\n if (!this.userID) {\n throw Error('Call connectUser before creating a channel');\n }\n\n if (~channelType.indexOf(':')) {\n throw Error(`Invalid channel group ${channelType}, can't contain the : character`);\n }\n\n let channelID: string | undefined = undefined;\n let customData = custom || ({} as ChannelData<ErmisChatGenerics>);\n\n if (typeof channelIDOrCustom === 'string') {\n channelID = channelIDOrCustom;\n } else if (typeof channelIDOrCustom === 'object' && channelIDOrCustom !== null) {\n customData = channelIDOrCustom as ChannelData<ErmisChatGenerics>;\n }\n\n return this.getChannelById(channelType, channelID, customData);\n }\n\n getChannelById = (channelType: string, channelID: string | undefined, custom: ChannelData<ErmisChatGenerics>) => {\n const cid = `${channelType}:${channelID || ''}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = custom;\n channel._data = custom;\n }\n return channel;\n }\n const channel = new Channel<ErmisChatGenerics>(this, channelType, channelID, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n getChannel = (channelType: string, custom: ChannelData<ErmisChatGenerics>) => {\n const uuid = randomId();\n const id = `${this.projectId}:${uuid}`;\n // only allow 1 channel object per cid\n const cid = `${channelType}:${id}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = custom;\n channel._data = custom;\n }\n return channel;\n }\n const channel = new Channel<ErmisChatGenerics>(this, channelType, id, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n _normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {\n let pinExpires: null | string = null;\n if (typeof timeoutOrExpirationDate === 'number') {\n const now = new Date();\n now.setSeconds(now.getSeconds() + timeoutOrExpirationDate);\n pinExpires = now.toISOString();\n } else if (isString(timeoutOrExpirationDate)) {\n pinExpires = timeoutOrExpirationDate;\n } else if (timeoutOrExpirationDate instanceof Date) {\n pinExpires = timeoutOrExpirationDate.toISOString();\n }\n return pinExpires;\n }\n\n getUserAgent() {\n return (\n this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n let token = this._getToken();\n\n if (!token?.startsWith('Bearer ')) {\n token = `Bearer ${token}`;\n }\n\n const authorization = token ? { Authorization: token } : undefined;\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n const {\n params: axiosRequestConfigParams,\n headers: axiosRequestConfigHeaders,\n ...axiosRequestConfigRest\n } = this.options.axiosRequestConfig || {};\n\n let user_service_params = {\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n };\n\n return {\n params: user_service_params,\n headers: {\n ...authorization,\n 'stream-auth-type': this.getAuthType(),\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n _getToken() {\n if (!this.tokenManager) return null;\n\n return this.tokenManager.getToken();\n }\n\n _startCleaning() {\n const that = this;\n if (this.cleaningIntervalRef != null) {\n return;\n }\n this.cleaningIntervalRef = setInterval(() => {\n // call clean on the channel, used for calling the stop.typing event etc.\n for (const channel of Object.values(that.activeChannels)) {\n channel.clean();\n }\n }, 500);\n }\n\n _buildWSPayload = (client_request_id?: string) => {\n return JSON.stringify({\n user_id: this.userID,\n user_details: this.user,\n client_request_id,\n });\n };\n}\n","export default null;\n","import FormData from 'form-data';\nimport { ExtendableGenerics, DefaultGenerics, MessageResponse, FormatMessageResponse, ForwardMessage } from './types';\nimport { AxiosRequestConfig } from 'axios';\nimport { ErmisChat } from './client';\n\n/**\n * logChatPromiseExecution - utility function for logging the execution of a promise..\n * use this when you want to run the promise and handle errors by logging a warning\n *\n * @param {Promise<T>} promise The promise you want to run and log\n * @param {string} name A descriptive name of what the promise does for log output\n *\n */\nexport function logChatPromiseExecution<T>(promise: Promise<T>, name: string) {\n promise.then().catch((error) => {\n console.warn(`failed to do ${name}, ran into error: `, error);\n });\n}\n\nexport const sleep = (m: number): Promise<void> => new Promise((r) => setTimeout(r, m));\n\nexport function isFunction<T>(value: Function | T): value is Function {\n return (\n value &&\n (Object.prototype.toString.call(value) === '[object Function]' ||\n 'function' === typeof value ||\n value instanceof Function)\n );\n}\n\nexport const chatCodes = {\n TOKEN_EXPIRED: 40,\n WS_CLOSED_SUCCESS: 1000,\n};\n\nfunction isReadableStream(obj: unknown): obj is NodeJS.ReadStream {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function')\n );\n}\n\nfunction isBuffer(obj: unknown): obj is Buffer {\n return (\n obj != null &&\n (obj as Buffer).constructor != null &&\n // @ts-expect-error\n typeof obj.constructor.isBuffer === 'function' &&\n // @ts-expect-error\n obj.constructor.isBuffer(obj)\n );\n}\n\nfunction isFileWebAPI(uri: unknown): uri is File {\n return typeof window !== 'undefined' && 'File' in window && uri instanceof File;\n}\n\nfunction isBlobWebAPI(uri: unknown): uri is Blob {\n return typeof window !== 'undefined' && 'Blob' in window && uri instanceof Blob;\n}\n\nexport function addFileToFormData(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n) {\n const data = new FormData();\n\n if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {\n if (name) data.append('file', uri, name);\n else data.append('file', uri);\n } else {\n data.append('file', {\n uri,\n name: name || (uri as string).split('/').reverse()[0],\n contentType: contentType || undefined,\n type: contentType || undefined,\n });\n }\n\n return data;\n}\n\n\n/**\n * retryInterval - A retry interval which increases acc to number of failures\n *\n * @return {number} Duration to wait in milliseconds\n */\nexport function retryInterval(numberOfFailures: number) {\n // try to reconnect in 0.25-25 seconds (random to spread out the load from failures)\n const max = Math.min(500 + numberOfFailures * 2000, 25000);\n const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2000), 25000);\n return Math.floor(Math.random() * (max - min) + min);\n}\n\nexport function randomId() {\n return generateUUIDv4();\n}\n\nfunction hex(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0');\n }\n return s;\n}\n\n// https://tools.ietf.org/html/rfc4122\nexport function generateUUIDv4() {\n const bytes = getRandomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant\n\n return (\n hex(bytes.subarray(0, 4)) +\n '-' +\n hex(bytes.subarray(4, 6)) +\n '-' +\n hex(bytes.subarray(6, 8)) +\n '-' +\n hex(bytes.subarray(8, 10)) +\n '-' +\n hex(bytes.subarray(10, 16))\n );\n}\n\nfunction getRandomValuesWithMathRandom(bytes: Uint8Array): void {\n const max = Math.pow(2, (8 * bytes.byteLength) / bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.random() * max;\n }\n}\ndeclare const msCrypto: Crypto;\n\nconst getRandomValues = (() => {\n if (typeof crypto !== 'undefined' && typeof crypto?.getRandomValues !== 'undefined') {\n return crypto.getRandomValues.bind(crypto);\n } else if (typeof msCrypto !== 'undefined') {\n return msCrypto.getRandomValues.bind(msCrypto);\n } else {\n return getRandomValuesWithMathRandom;\n }\n})();\n\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getRandomValues(bytes);\n return bytes;\n}\n\n\n\n\n\n/**\n * listenForConnectionChanges - Adds an event listener fired on browser going online or offline\n */\nexport function addConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('offline', cb);\n window.addEventListener('online', cb);\n }\n}\n\nexport function removeConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.removeEventListener) {\n window.removeEventListener('offline', cb);\n window.removeEventListener('online', cb);\n }\n}\n\nexport const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (params) => {\n const newParams = [];\n for (const k in params) {\n // Ermis backend doesn't treat \"undefined\" value same as value not being present.\n // So, we need to skip the undefined values.\n if (params[k] === undefined) continue;\n\n if (Array.isArray(params[k]) || typeof params[k] === 'object') {\n newParams.push(`${k}=${encodeURIComponent(JSON.stringify(params[k]))}`);\n } else {\n newParams.push(`${k}=${encodeURIComponent(params[k])}`);\n }\n }\n\n return newParams.join('&');\n};\n\n/**\n * formatMessage - Takes the message object. Parses the dates, sets __html\n * and sets the status to received if missing. Returns a message object\n *\n * @param {MessageResponse<ErmisChatGenerics>} message a message object\n *\n */\nexport function formatMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: MessageResponse<ErmisChatGenerics>,\n): FormatMessageResponse<ErmisChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the date..\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),\n status: message.status || 'received',\n };\n}\n\nexport function addToMessageList<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n messages: Array<FormatMessageResponse<ErmisChatGenerics>>,\n message: FormatMessageResponse<ErmisChatGenerics>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n) {\n const addMessageToList = addIfDoesNotExist || timestampChanged;\n let messageArr = messages;\n\n // if created_at has changed, message should be filtered and re-inserted in correct order\n // slow op but usually this only happens for a message inserted to state before actual response with correct timestamp\n if (timestampChanged) {\n messageArr = messageArr.filter((msg) => !(msg.id && message.id === msg.id));\n }\n\n // Get array length after filtering\n const messageArrayLength = messageArr.length;\n\n // for empty list just concat and return unless it's an update or deletion\n if (messageArrayLength === 0 && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageArrayLength === 0) {\n return [...messageArr];\n }\n\n if (sortBy === 'pinned_at') {\n return messageArr.concat(message);\n }\n\n const messageTime = (message[sortBy] as Date).getTime();\n const messageIsNewest = (messageArr[messageArrayLength - 1][sortBy] as Date).getTime() < messageTime;\n\n // if message is newer than last item in the list concat and return unless it's an update or deletion\n if (messageIsNewest && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageIsNewest) {\n return [...messageArr];\n }\n\n // find the closest index to push the new message\n let left = 0;\n let middle = 0;\n let right = messageArrayLength - 1;\n while (left <= right) {\n middle = Math.floor((right + left) / 2);\n if ((messageArr[middle][sortBy] as Date).getTime() <= messageTime) left = middle + 1;\n else right = middle - 1;\n }\n\n // message already exists and not filtered due to timestampChanged, update and return\n if (!timestampChanged && message.id) {\n if (messageArr[left] && message.id === messageArr[left].id) {\n messageArr[left] = message;\n return [...messageArr];\n }\n\n if (messageArr[left - 1] && message.id === messageArr[left - 1].id) {\n messageArr[left - 1] = message;\n return [...messageArr];\n }\n }\n\n // Do not add updated or deleted messages to the list if they do not already exist\n // or have a timestamp change.\n if (addMessageToList) {\n messageArr.splice(left, 0, message);\n }\n\n // Remove duplicate messages by ID\n const map = new Map();\n const uniqueMessages = [];\n\n for (const msg of messageArr) {\n if (!map.has(msg.id)) {\n map.set(msg.id, true);\n uniqueMessages.push(msg);\n }\n }\n return uniqueMessages;\n}\n\nexport const enrichWithUserInfo = (items: any[], users: any[]) => {\n if (items.length === 0) return [];\n\n if (users.length === 0) {\n return items.map((item) => {\n item.user = { id: item.user?.id, name: item.user?.id, avatar: '' };\n return item;\n });\n }\n\n return items.map((item) => {\n const userId = item.user?.id;\n const lastestReactionMsg = item?.latest_reactions;\n const quotedMsg = item?.quoted_message;\n const user = users.find((u) => u.id === userId);\n if (user) {\n item.user = { id: user.id, name: user.name || user.id, avatar: user.avatar || '' };\n }\n\n if (lastestReactionMsg) {\n item.latest_reactions = lastestReactionMsg.map((reaction: any) => {\n const reactionUser = users.find((u) => u.id === reaction.user_id);\n return {\n ...reaction,\n user: {\n id: reactionUser?.id || reaction.user_id,\n name: reactionUser?.name || reaction.user_id,\n avatar: reactionUser?.avatar || '',\n },\n };\n });\n }\n\n if (quotedMsg) {\n const quotedUser = users.find((u) => u.id === quotedMsg.user?.id);\n item.quoted_message.user = {\n id: quotedUser?.id || quotedMsg.user?.id,\n name: quotedUser?.name || quotedMsg.user?.id,\n avatar: quotedUser?.avatar || '',\n };\n }\n\n return item;\n });\n};\n\nexport const getUserInfo = (id: string, users: any[]) => {\n if (users.length === 0) {\n return {\n id,\n name: id,\n avatar: '',\n };\n }\n\n const user = users.find((u) => u.id === id);\n return {\n id,\n name: user?.name || id,\n avatar: user?.avatar || '',\n };\n};\n\nexport const getDirectChannelName = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return 'Empty channel';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.name || otherMember.user.id;\n }\n return 'Empty channel';\n};\n\nexport const getDirectChannelImage = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return '';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.avatar || '';\n }\n return '';\n};\n\n/**\n * Ensure all members' user info are loaded in state.users.\n * @param client ErmisChat client instance\n * @param members Array of channel members (each member must have user?.id)\n */\nexport async function ensureMembersUserInfoLoaded<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n client: ErmisChat<ErmisChatGenerics>,\n members: any[],\n) {\n // Get all memberIds\n const memberIds = (members || []).map((m: any) => m.user?.id).filter((id: string | undefined) => !!id);\n\n // Filter out ids that do not exist in users\n const users = client.state.users;\n const missingUserIds = memberIds.filter((id: string) => !users[id]);\n\n // If there are users missing, fetch and update them into state\n if (missingUserIds.length > 0) {\n await client.getBatchUsers(missingUserIds);\n }\n}\n\nexport const getLatestCreatedAt = (messages: any[] = []) =>\n messages.length > 0 ? Math.max(...messages.map((msg) => new Date(msg.created_at).getTime())) : 0;\n\nexport const createPacketWithHeader = (\n data: ArrayBuffer | null,\n timestamp: number | null,\n type: string,\n configMsg: any,\n): Uint8Array => {\n let HEADER_SIZE: number;\n let payload: Uint8Array;\n\n // Config messages\n if (['videoConfig', 'audioConfig', 'transciverState'].includes(type) && configMsg) {\n HEADER_SIZE = 1;\n const jsonString = JSON.stringify(configMsg);\n const encoder = new TextEncoder();\n payload = encoder.encode(jsonString);\n } else if (type === 'connected') {\n HEADER_SIZE = 1;\n payload = new Uint8Array(0);\n } else {\n // Data packets\n // HEADER_SIZE = 5;\n HEADER_SIZE = 9;\n payload = new Uint8Array(data!);\n }\n\n const packet = new Uint8Array(HEADER_SIZE + payload.byteLength);\n\n let typeCode: number = 0;\n switch (type) {\n case 'videoConfig':\n typeCode = 0;\n break;\n case 'audioConfig':\n typeCode = 1;\n break;\n case 'video-key':\n typeCode = 2;\n break;\n case 'video-delta':\n typeCode = 3;\n break;\n case 'audio':\n typeCode = 4;\n break;\n case 'connected':\n typeCode = 6;\n break;\n case 'transciverState':\n typeCode = 7;\n break;\n }\n\n // Byte 0: Type code\n packet[0] = typeCode;\n\n // Byte 1-8: Timestamp\n if (timestamp !== null) {\n const view = new DataView(packet.buffer);\n // view.setUint32(1, timestamp, false); // Little-endian = false (Big-endian)\n view.setBigUint64(1, BigInt(timestamp), false);\n }\n\n packet.set(payload, HEADER_SIZE);\n\n return packet;\n};\n\nexport const base64Encode = (arrayBuffer: ArrayBuffer): string => {\n let binary = '';\n const bytes = new Uint8Array(arrayBuffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n};\n\nexport const replaceCodecNumber = (input: string): string => {\n const map: Record<string, string> = {\n '2048': '123',\n '4096': '153',\n '8192': '156',\n '16384': '183',\n '32768': '186',\n };\n\n // Regex để tìm các key\n const regex = /2048|4096|8192|16384|32768/g;\n\n // Kiểm tra: Nếu input KHÔNG match bất kỳ số nào trong regex\n // thì trả về chuỗi mặc định\n if (!input.match(regex)) {\n return 'hev1.1.6.L123.B0';\n }\n\n // Nếu có match, thực hiện thay thế\n return input.replace(regex, (match) => map[match]);\n};\n\nexport const createForwardMessagePayload = <ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: FormatMessageResponse<ErmisChatGenerics>,\n targetCid: string,\n activeCid: string,\n): ForwardMessage<ErmisChatGenerics> => {\n const forwardPayload: ForwardMessage<ErmisChatGenerics> = {\n cid: targetCid,\n forward_cid: activeCid,\n forward_message_id: message.id as string,\n };\n\n if (\n message.sticker_url &&\n (!message.text || message.text === '') &&\n (!message.attachments || (Array.isArray(message.attachments) && message.attachments.length === 0))\n ) {\n forwardPayload.sticker_url = message.sticker_url as string;\n forwardPayload.text = message.text;\n } else {\n forwardPayload.text = message.text || '';\n if (message.attachments && message.attachments.length > 0) {\n forwardPayload.attachments = message.attachments.filter((item: any) => item.type !== 'linkPreview');\n }\n }\n\n return forwardPayload;\n};\n","import { Channel } from './channel';\nimport {\n ChannelMemberResponse,\n ChannelMembership,\n FormatMessageResponse,\n Event,\n ExtendableGenerics,\n DefaultGenerics,\n MessageSetType,\n MessageResponse,\n ReactionResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList } from './utils';\n\ntype ChannelReadStatus<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n {\n last_read: Date;\n unread_messages: number;\n user: UserResponse<ErmisChatGenerics>;\n last_read_message_id?: string;\n last_send?: string;\n }\n>;\n\n/**\n * ChannelState - A container class for the channel state.\n */\nexport class ChannelState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _channel: Channel<ErmisChatGenerics>;\n watcher_count: number;\n typing: Record<string, Event<ErmisChatGenerics>>;\n read: ChannelReadStatus<ErmisChatGenerics>;\n pinnedMessages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;\n watchers: Record<string, UserResponse<ErmisChatGenerics>>;\n members: Record<string, ChannelMemberResponse<ErmisChatGenerics>>;\n unreadCount: number;\n membership: ChannelMembership<ErmisChatGenerics>;\n last_message_at: Date | null;\n isUpToDate: boolean;\n messageSets: {\n isCurrent: boolean;\n isLatest: boolean;\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;\n }[] = [];\n topics?: Channel<ErmisChatGenerics>[] = [];\n constructor(channel: Channel<ErmisChatGenerics>) {\n this._channel = channel;\n this.watcher_count = 0;\n this.typing = {};\n this.read = {};\n this.initMessages();\n this.pinnedMessages = [];\n this.watchers = {};\n this.members = {};\n this.membership = {};\n this.unreadCount = 0;\n this.isUpToDate = true;\n this.last_message_at = channel?.state?.last_message_at != null ? new Date(channel.state.last_message_at) : null;\n }\n\n get messages() {\n return this.messageSets.find((s) => s.isCurrent)?.messages || [];\n }\n\n set messages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isCurrent);\n this.messageSets[index].messages = messages;\n }\n\n get latestMessages() {\n return this.messageSets.find((s) => s.isLatest)?.messages || [];\n }\n\n set latestMessages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isLatest);\n this.messageSets[index].messages = messages;\n }\n\n addMessageSorted(\n newMessage: MessageResponse<ErmisChatGenerics>,\n timestampChanged = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n return this.addMessagesSorted(\n [newMessage],\n timestampChanged,\n false,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n }\n\n formatMessage(message: MessageResponse<ErmisChatGenerics>): FormatMessageResponse<ErmisChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the date..\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : null,\n status: message.status || 'received',\n };\n }\n\n addMessagesSorted(\n newMessages: MessageResponse<ErmisChatGenerics>[],\n timestampChanged = false,\n initializing = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n const { messagesToAdd, targetMessageSetIndex } = this.findTargetMessageSet(\n newMessages,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n\n for (let i = 0; i < messagesToAdd.length; i += 1) {\n // If message is already formatted we can skip the tasks below\n // This will be true for messages that are already present at the state -> this happens when we perform merging of message sets\n // This will be also true for message previews used by some SDKs\n const isMessageFormatted = messagesToAdd[i].created_at instanceof Date;\n let message: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n if (isMessageFormatted) {\n message = messagesToAdd[i] as ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n } else {\n message = this.formatMessage(messagesToAdd[i] as MessageResponse<ErmisChatGenerics>);\n\n if (message.user && this._channel?.cid) {\n /**\n * Store the reference to user for this channel, so that when we have to\n * handle updates to user, we can use the reference map, to determine which\n * channels need to be updated with updated user object.\n */\n this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);\n }\n\n if (!this.last_message_at) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n\n if (message.created_at.getTime() > this.last_message_at.getTime()) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n }\n\n // Cross-reference with pinnedMessages to ensure `pinned` and `pinned_at` are accurate\n if (!message.pinned) {\n const pinnedMatch = this.pinnedMessages.find((pm) => pm.id === message.id);\n if (pinnedMatch) {\n message.pinned = true;\n message.pinned_at = pinnedMatch.pinned_at || new Date();\n }\n }\n\n // update or append the messages...\n const parentID = message.parent_id;\n\n // add to the given message set\n if (!parentID && targetMessageSetIndex !== -1) {\n this.messageSets[targetMessageSetIndex].messages = this._addToMessageList(\n this.messageSets[targetMessageSetIndex].messages,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n }\n\n return {\n messageSet: this.messageSets[targetMessageSetIndex],\n };\n }\n\n addPinnedMessages(pinnedMessages: MessageResponse<ErmisChatGenerics>[]) {\n for (let i = 0; i < pinnedMessages.length; i += 1) {\n this.addPinnedMessage(pinnedMessages[i]);\n }\n // Sort by pinned_at descending (newest pin first)\n this.pinnedMessages.sort((a, b) => {\n const timeA = a.pinned_at ? new Date(a.pinned_at).getTime() : 0;\n const timeB = b.pinned_at ? new Date(b.pinned_at).getTime() : 0;\n return timeB - timeA;\n });\n }\n\n addPinnedMessage(pinnedMessage: MessageResponse<ErmisChatGenerics>) {\n const formatted = this.formatMessage(pinnedMessage);\n // Remove existing entry if present (to avoid duplicates)\n this.pinnedMessages = this.pinnedMessages.filter((msg) => msg.id !== formatted.id);\n // Add to the beginning of the list (newest pin first)\n this.pinnedMessages = [formatted, ...this.pinnedMessages];\n }\n\n removePinnedMessage(message: MessageResponse<ErmisChatGenerics>) {\n const { result } = this.removeMessageFromArray(this.pinnedMessages, message);\n this.pinnedMessages = result;\n }\n\n addReaction(\n reaction: ReactionResponse<ErmisChatGenerics>,\n message?: MessageResponse<ErmisChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._addOwnReactionToMessage(msg.own_reactions, reaction, enforce_unique);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _addOwnReactionToMessage(\n ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<ErmisChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (enforce_unique) {\n ownReactions = [];\n } else {\n ownReactions = this._removeOwnReactionFromMessage(ownReactions, reaction);\n }\n\n ownReactions = ownReactions || [];\n if (this._channel.getClient().userID === reaction.user_id) {\n ownReactions.push(reaction);\n }\n\n return ownReactions;\n }\n\n _removeOwnReactionFromMessage(\n ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<ErmisChatGenerics>,\n ) {\n if (ownReactions) {\n return ownReactions.filter((item) => item.user_id !== reaction.user_id || item.type !== reaction.type);\n }\n return ownReactions;\n }\n\n removeReaction(reaction: ReactionResponse<ErmisChatGenerics>, message?: MessageResponse<ErmisChatGenerics>) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._removeOwnReactionFromMessage(msg.own_reactions, reaction);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n removeQuotedMessageReferences(message: MessageResponse<ErmisChatGenerics>) {\n const parseMessage = (m: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>) =>\n ({\n ...m,\n created_at: m.created_at.toISOString(),\n pinned_at: m.pinned_at?.toISOString(),\n updated_at: m.updated_at?.toISOString(),\n } as unknown as MessageResponse<ErmisChatGenerics>);\n\n this.messageSets.forEach((set) => {\n const updatedMessages = set.messages\n .filter((msg) => msg.quoted_message_id === message.id)\n .map(parseMessage)\n .map((msg) => ({ ...msg, quoted_message: { ...message, attachments: [] } }));\n\n this.addMessagesSorted(updatedMessages, true);\n });\n }\n\n _updateMessage(\n message: {\n id?: string;\n parent_id?: string;\n pinned?: boolean;\n },\n updateFunc: (\n msg: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n ) => ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n ) {\n const { parent_id, pinned } = message;\n\n if (!parent_id) {\n const messageSetIndex = this.findMessageSetIndex(message);\n if (messageSetIndex !== -1) {\n const msgIndex = this.messageSets[messageSetIndex].messages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.messageSets[messageSetIndex].messages[msgIndex] = updateFunc(\n this.messageSets[messageSetIndex].messages[msgIndex],\n );\n }\n }\n }\n\n if (pinned) {\n const msgIndex = this.pinnedMessages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.pinnedMessages[msgIndex] = updateFunc(this.pinnedMessages[msgIndex]);\n }\n }\n }\n\n setIsUpToDate = (isUpToDate: boolean) => {\n this.isUpToDate = isUpToDate;\n };\n\n /**\n * Update the status of a message by ID (used for optimistic UI).\n */\n updateMessageStatus(messageId: string, status: string) {\n this._updateMessage({ id: messageId }, (msg) => ({\n ...msg,\n status,\n }));\n }\n\n _addToMessageList(\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n message: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n ) {\n return addToMessageList(messages, message, timestampChanged, sortBy, addIfDoesNotExist);\n }\n\n removeMessage(messageToRemove: { id: string; messageSetIndex?: number; parent_id?: string }) {\n let isRemoved = false;\n const messageSetIndex = messageToRemove.messageSetIndex ?? this.findMessageSetIndex(messageToRemove);\n if (messageSetIndex !== -1) {\n const { removed, result: messages } = this.removeMessageFromArray(\n this.messageSets[messageSetIndex].messages,\n messageToRemove,\n );\n this.messageSets[messageSetIndex].messages = messages;\n isRemoved = removed;\n }\n\n return isRemoved;\n }\n\n removeMessageFromArray = (\n msgArray: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n msg: { id: string; parent_id?: string },\n ) => {\n const result = msgArray.filter((message) => !(!!message.id && !!msg.id && message.id === msg.id));\n\n return { removed: result.length < msgArray.length, result };\n };\n\n updateUserMessages = (user: UserResponse<ErmisChatGenerics>) => {\n const _updateUserMessages = (\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n user: UserResponse<ErmisChatGenerics>,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n const latestReactions = m?.latest_reactions || [];\n if (m.user?.id === user.id) {\n messages[i] = {\n ...m,\n user: m.user?.id === user.id ? user : m.user,\n };\n }\n\n if (latestReactions && latestReactions.some((r) => r.user?.id === user.id)) {\n messages[i] = {\n ...m,\n latest_reactions: latestReactions.map((r) => (r.user?.id === user.id ? { ...r, user } : r)),\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _updateUserMessages(set.messages, user));\n\n _updateUserMessages(this.pinnedMessages, user);\n };\n\n deleteUserMessages = (user: UserResponse<ErmisChatGenerics>, hardDelete = false) => {\n const _deleteUserMessages = (\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n user: UserResponse<ErmisChatGenerics>,\n hardDelete = false,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id !== user.id) {\n continue;\n }\n\n if (hardDelete) {\n /**\n * In case of hard delete, we need to strip down all text, html,\n * attachments and all the custom properties on message\n */\n messages[i] = {\n cid: m.cid,\n created_at: m.created_at,\n deleted_at: new Date().toISOString(),\n id: m.id,\n latest_reactions: [],\n mentioned_users: [],\n own_reactions: [],\n parent_id: m.parent_id,\n reply_count: m.reply_count,\n status: m.status,\n type: 'deleted',\n updated_at: m.updated_at,\n user: m.user,\n } as unknown as ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n } else {\n messages[i] = {\n ...m,\n type: 'deleted',\n deleted_at: new Date().toISOString(),\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _deleteUserMessages(set.messages, user, hardDelete));\n\n _deleteUserMessages(this.pinnedMessages, user, hardDelete);\n };\n\n filterErrorMessages() {\n const filteredMessages = this.latestMessages.filter((message) => message.type !== 'error');\n\n this.latestMessages = filteredMessages;\n }\n\n clean() {\n const now = new Date();\n // prevent old users from showing up as typing\n for (const [userID, lastEvent] of Object.entries(this.typing)) {\n const receivedAt =\n typeof lastEvent.received_at === 'string'\n ? new Date(lastEvent.received_at)\n : lastEvent.received_at || new Date();\n if (now.getTime() - receivedAt.getTime() > 7000) {\n delete this.typing[userID];\n this._channel.getClient().dispatchEvent({\n cid: this._channel.cid,\n type: 'typing.stop',\n user: { id: userID },\n } as Event<ErmisChatGenerics>);\n }\n }\n }\n\n clearMessages() {\n this.initMessages();\n this.pinnedMessages = [];\n }\n\n initMessages() {\n this.messageSets = [{ messages: [], isLatest: true, isCurrent: true }];\n }\n\n async loadMessageIntoState(messageId: string | 'latest', parentMessageId?: string, limit = 25) {\n let messageSetIndex: number;\n let switchedToMessageSet = false;\n const messageIdToFind = parentMessageId || messageId;\n if (messageId === 'latest') {\n if (this.messages === this.latestMessages) {\n return;\n }\n messageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n } else {\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n }\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n switchedToMessageSet = true;\n }\n if (!switchedToMessageSet) {\n await this._channel.query({ messages: { id_around: messageIdToFind, limit } }, 'new');\n }\n\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n }\n }\n\n findMessage(messageId: string, parentMessageId?: string) {\n const messageSetIndex = this.findMessageSetIndex({ id: messageId });\n if (messageSetIndex === -1) {\n return undefined;\n }\n return this.messageSets[messageSetIndex].messages.find((m) => m.id === messageId);\n }\n\n private switchToMessageSet(index: number) {\n const currentMessages = this.messageSets.find((s) => s.isCurrent);\n if (!currentMessages) {\n return;\n }\n currentMessages.isCurrent = false;\n this.messageSets[index].isCurrent = true;\n }\n\n private areMessageSetsOverlap(messages1: Array<{ id: string }>, messages2: Array<{ id: string }>) {\n return messages1.some((m1) => messages2.find((m2) => m1.id === m2.id));\n }\n\n private findMessageSetIndex(message: { id?: string }) {\n return this.messageSets.findIndex((set) => !!set.messages.find((m) => m.id === message.id));\n }\n\n private findTargetMessageSet(\n newMessages: MessageResponse<ErmisChatGenerics>[],\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n let messagesToAdd: (\n | MessageResponse<ErmisChatGenerics>\n | ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>\n )[] = newMessages;\n let targetMessageSetIndex!: number;\n if (addIfDoesNotExist) {\n const overlappingMessageSetIndices = this.messageSets\n .map((_, i) => i)\n .filter((i) => this.areMessageSetsOverlap(this.messageSets[i].messages, newMessages));\n switch (messageSetToAddToIfDoesNotExist) {\n case 'new':\n if (overlappingMessageSetIndices.length > 0) {\n targetMessageSetIndex = overlappingMessageSetIndices[0];\n } else if (newMessages.some((m) => !m.parent_id)) {\n this.messageSets.push({ messages: [], isCurrent: false, isLatest: false });\n targetMessageSetIndex = this.messageSets.length - 1;\n }\n break;\n case 'current':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isCurrent);\n break;\n case 'latest':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n break;\n default:\n targetMessageSetIndex = -1;\n }\n // when merging the target set will be the first one from the overlapping message sets\n const mergeTargetMessageSetIndex = overlappingMessageSetIndices.splice(0, 1)[0];\n const mergeSourceMessageSetIndices = [...overlappingMessageSetIndices];\n if (mergeTargetMessageSetIndex !== undefined && mergeTargetMessageSetIndex !== targetMessageSetIndex) {\n mergeSourceMessageSetIndices.push(targetMessageSetIndex);\n }\n // merge message sets\n if (mergeSourceMessageSetIndices.length > 0) {\n const target = this.messageSets[mergeTargetMessageSetIndex];\n const sources = this.messageSets.filter((_, i) => mergeSourceMessageSetIndices.indexOf(i) !== -1);\n sources.forEach((messageSet) => {\n target.isLatest = target.isLatest || messageSet.isLatest;\n target.isCurrent = target.isCurrent || messageSet.isCurrent;\n messagesToAdd = [...messagesToAdd, ...messageSet.messages];\n });\n sources.forEach((s) => this.messageSets.splice(this.messageSets.indexOf(s), 1));\n const overlappingMessageSetIndex = this.messageSets.findIndex((s) =>\n this.areMessageSetsOverlap(s.messages, newMessages),\n );\n targetMessageSetIndex = overlappingMessageSetIndex;\n }\n } else {\n // assumes that all new messages belong to the same set\n targetMessageSetIndex = this.findMessageSetIndex(newMessages[0]);\n }\n\n return { targetMessageSetIndex, messagesToAdd };\n }\n}\n","import type { Attachment } from './types';\n\n/**\n * Normalize a file name for upload:\n * - Remove Vietnamese diacritics\n * - Replace đ/Đ with d/D\n * - Replace spaces with underscores\n * - Preserve extension\n */\nexport function normalizeFileName(name: string): string {\n const dotIndex = name.lastIndexOf('.');\n const baseName = dotIndex > 0 ? name.slice(0, dotIndex) : name;\n const extension = dotIndex > 0 ? name.slice(dotIndex) : '';\n\n const normalized = baseName\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '') // strip diacritics\n .replace(/đ/g, 'd')\n .replace(/Đ/g, 'D')\n .replace(/\\s+/g, '_');\n\n return normalized + extension;\n}\n\n/**\n * Check if a MIME type or file extension is HEIC/HEIF.\n */\nexport function isHeicFile(file: File): boolean {\n const mime = file.type.toLowerCase();\n const ext = file.name.toLowerCase().split('.').pop() || '';\n return (\n mime === 'image/heic' ||\n mime === 'image/heif' ||\n ext === 'heic' ||\n ext === 'heif'\n );\n}\n\n/**\n * Categorize a file by MIME type.\n * HEIC/HEIF files are treated as 'file' (not 'image') since browsers can't render them.\n */\nexport function getAttachmentCategory(\n mimeType: string,\n fileName?: string,\n): 'image' | 'video' | 'audio' | 'file' {\n const mime = mimeType.toLowerCase();\n const ext = (fileName || '').toLowerCase().split('.').pop() || '';\n\n // HEIC/HEIF → file (not image)\n if (mime === 'image/heic' || mime === 'image/heif' || ext === 'heic' || ext === 'heif') {\n return 'file';\n }\n\n if (mime.startsWith('image/')) return 'image';\n if (mime.startsWith('video/')) return 'video';\n if (mime.startsWith('audio/')) return 'audio';\n return 'file';\n}\n\n/**\n * Check if a file is a video type that supports thumbnail extraction.\n */\nexport function isVideoFile(file: File): boolean {\n return (\n file.type === 'video/mp4' ||\n file.type === 'video/webm' ||\n file.type === 'video/quicktime'\n );\n}\n\n/**\n * Metadata for voice recording attachments.\n */\nexport type VoiceRecordingMeta = {\n waveform_data: number[];\n duration: number;\n};\n\n/**\n * Build a normalized attachment payload from an uploaded file.\n *\n * @param file - Original file object\n * @param uploadedUrl - URL returned by the upload API\n * @param thumbUrl - Optional thumbnail URL (for video)\n * @param voiceMeta - Optional voice recording metadata\n */\nexport function buildAttachmentPayload(\n file: File,\n uploadedUrl: string,\n thumbUrl?: string,\n voiceMeta?: VoiceRecordingMeta,\n): Attachment {\n const title = normalizeFileName(file.name);\n const mimeType = file.type || '';\n const category = getAttachmentCategory(mimeType, file.name);\n\n if (voiceMeta) {\n return {\n type: 'voiceRecording',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n waveform_data: voiceMeta.waveform_data,\n duration: voiceMeta.duration,\n };\n }\n\n switch (category) {\n case 'image':\n return {\n type: 'image',\n image_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n };\n\n case 'video':\n return {\n type: 'video',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n thumb_url: thumbUrl || '',\n };\n\n case 'audio':\n return {\n type: 'file',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n };\n\n default:\n return {\n type: 'file',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType || '',\n };\n }\n}\n","import { ChannelState } from './channel_state';\nimport { normalizeFileName, isVideoFile, buildAttachmentPayload } from './attachment_utils';\nimport type { VoiceRecordingMeta } from './attachment_utils';\nimport {\n enrichWithUserInfo,\n ensureMembersUserInfoLoaded,\n getDirectChannelImage,\n getDirectChannelName,\n getUserInfo,\n logChatPromiseExecution,\n randomId,\n} from './utils';\nimport { ErmisChat } from './client';\nimport {\n APIResponse,\n Attachment,\n ChannelAPIResponse,\n ChannelData,\n ChannelQueryOptions,\n ChannelResponse,\n DefaultGenerics,\n Event,\n EventHandler,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n Message,\n MessageResponse,\n MessageSetType,\n ReactionAPIResponse,\n SendMessageAPIResponse,\n UpdateChannelAPIResponse,\n UserResponse,\n QueryChannelAPIResponse,\n AttachmentResponse,\n PollMessage,\n EditMessage,\n ForwardMessage,\n} from './types';\nexport class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _client: ErmisChat<ErmisChatGenerics>;\n type: string;\n id: string | undefined;\n data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics> | undefined;\n _data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics>;\n cid: string;\n listeners: { [key: string]: (string | EventHandler<ErmisChatGenerics>)[] };\n state: ChannelState<ErmisChatGenerics>;\n initialized: boolean;\n offlineMode: boolean;\n lastKeyStroke?: Date;\n lastTypingEvent: Date | null;\n isTyping: boolean;\n disconnected: boolean;\n\n constructor(\n client: ErmisChat<ErmisChatGenerics>,\n type: string,\n id: string | undefined,\n data: ChannelData<ErmisChatGenerics>,\n ) {\n const validTypeRe = /^[\\w_-]+$/;\n const validIDRe = /^[\\w!:_-]+$/;\n\n if (!validTypeRe.test(type)) {\n throw new Error(`Invalid chat type ${type}, letters, numbers and \"_-\" are allowed`);\n }\n if (typeof id === 'string' && !validIDRe.test(id)) {\n throw new Error(`Invalid chat id ${id}, letters, numbers and \"!-_\" are allowed`);\n }\n\n this._client = client;\n this.type = type;\n this.id = id;\n this.data = data;\n this._data = { ...data };\n this.cid = `${type}:${id}`;\n this.listeners = {};\n this.state = new ChannelState<ErmisChatGenerics>(this);\n this.initialized = false;\n this.offlineMode = false;\n this.lastTypingEvent = null;\n this.isTyping = false;\n this.disconnected = false;\n }\n\n getClient(): ErmisChat<ErmisChatGenerics> {\n return this._client;\n }\n\n async sendMessage(message: Message<ErmisChatGenerics>) {\n // 1. Generate ID upfront\n if (!message.id) {\n message = { ...message, id: randomId() };\n }\n const messageId = message.id!;\n\n // 2. Build optimistic (fake) message and push into state immediately\n const optimisticMessage = {\n ...message,\n id: messageId,\n status: 'sending',\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n user: this.getClient().user,\n user_id: this.getClient().userID,\n type: 'regular',\n } as unknown as MessageResponse<ErmisChatGenerics>;\n\n this.state.addMessageSorted(optimisticMessage);\n\n // 3. Call API — don't update status on success (WS message.new will handle it)\n try {\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n this._channelURL() + '/message',\n { message: { ...message } },\n );\n } catch (error: any) {\n // 4. On error: check if it's an offline/network error\n const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;\n const statusToSet = isOfflineError ? 'failed_offline' : 'error';\n this.state.updateMessageStatus(messageId, statusToSet);\n throw error;\n }\n }\n\n async retryMessage(messageId: string) {\n const stateMsg = this.state.messages.find((m) => m.id === messageId);\n if (!stateMsg) throw new Error(`Message ${messageId} not found in state`);\n\n this.state.updateMessageStatus(messageId, 'sending');\n\n const messagePayload: any = {\n id: stateMsg.id,\n text: stateMsg.text,\n attachments: stateMsg.attachments,\n mentioned_users: stateMsg.mentioned_users,\n parent_id: stateMsg.parent_id,\n quoted_message_id: stateMsg.quoted_message_id,\n sticker_url: (stateMsg as any).sticker_url,\n };\n\n if (stateMsg.show_in_channel !== undefined) {\n messagePayload.show_in_channel = stateMsg.show_in_channel;\n }\n\n try {\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n this._channelURL() + '/message',\n { message: messagePayload },\n );\n } catch (error: any) {\n const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;\n this.state.updateMessageStatus(messageId, isOfflineError ? 'failed_offline' : 'error');\n throw error;\n }\n }\n\n async createPoll(pollMessage: PollMessage) {\n const id = randomId();\n pollMessage = { ...pollMessage, id };\n\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(this._channelURL() + '/message', {\n message: { ...pollMessage },\n });\n }\n\n async votePoll(messageID: string, pollChoice: string) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return await this.getClient().post<APIResponse>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/poll/${pollChoice}`,\n );\n }\n\n async forwardMessage(message: ForwardMessage<ErmisChatGenerics>, channel: { type: string; channelID: string }) {\n if (!message.id) {\n message = { ...message, id: randomId() };\n }\n\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n `${this.getClient().baseURL}/channels/${channel.type}/${channel.channelID}` + '/message',\n {\n message: { ...message },\n },\n );\n }\n\n async pinMessage(messageID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/pin`);\n }\n\n async unpinMessage(messageID: string) {\n return await this.getClient().post(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/unpin`,\n );\n }\n\n async editMessage(oldMessageID: string, message: EditMessage) {\n return await this.getClient().post(this.getClient().baseURL + `/messages/${this.type}/${this.id}/${oldMessageID}`, {\n message,\n });\n }\n\n sendFile(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<ErmisChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/file`, uri, name, contentType, user);\n }\n /**\n * Pre-process files (normalize names), upload them in parallel,\n * generate video thumbnails, and build attachment payloads.\n *\n * @param files - Array of File objects to upload\n * @param options - Optional voice recording metadata\n * @returns `attachments` ready for sendMessage, and `failedFiles` for error display\n */\n async uploadAndPrepareAttachments(\n files: File[],\n options?: {\n /** Map from file index → voice recording metadata */\n voiceMetadata?: Map<number, VoiceRecordingMeta>;\n },\n ): Promise<{\n attachments: Attachment[];\n failedFiles: Array<{ file: File; error: Error }>;\n }> {\n const failedFiles: Array<{ file: File; error: Error }> = [];\n\n // 1. Pre-process: normalize file names\n const processedFiles = files.map((file) => {\n const newName = normalizeFileName(file.name);\n if (newName !== file.name) {\n return new File([file], newName, { type: file.type, lastModified: file.lastModified });\n }\n return file;\n });\n\n // 2. Upload all files in parallel\n const uploadResults = await Promise.allSettled(\n processedFiles.map((file) =>\n this.sendFile(file, file.name, file.type),\n ),\n );\n\n // 3. For successful video uploads, generate and upload thumbnails\n const thumbUrls = new Map<number, string>();\n const thumbPromises: Promise<void>[] = [];\n\n for (let i = 0; i < processedFiles.length; i++) {\n const result = uploadResults[i];\n if (result.status === 'fulfilled' && isVideoFile(processedFiles[i])) {\n thumbPromises.push(\n (async () => {\n try {\n const thumbBlob = await this.getThumbBlobVideo(files[i]);\n if (thumbBlob) {\n const thumbFile = new File(\n [thumbBlob],\n `thumb_${processedFiles[i].name}.jpg`,\n { type: 'image/jpeg' },\n );\n const thumbResp = await this.sendFile(thumbFile, thumbFile.name, 'image/jpeg');\n thumbUrls.set(i, thumbResp.file);\n }\n } catch {\n // Thumbnail failure is non-critical\n }\n })(),\n );\n }\n }\n\n await Promise.allSettled(thumbPromises);\n\n // 4. Build attachment payloads from successful uploads\n const attachments: Attachment[] = [];\n for (let i = 0; i < processedFiles.length; i++) {\n const result = uploadResults[i];\n if (result.status === 'fulfilled') {\n const uploadedUrl = result.value.file;\n const thumbUrl = thumbUrls.get(i);\n const voiceMeta = options?.voiceMetadata?.get(i);\n attachments.push(\n buildAttachmentPayload(processedFiles[i], uploadedUrl, thumbUrl, voiceMeta),\n );\n } else {\n failedFiles.push({\n file: files[i],\n error: result.reason instanceof Error ? result.reason : new Error(String(result.reason)),\n });\n }\n }\n\n return { attachments, failedFiles };\n }\n\n async sendEvent(event: Event<ErmisChatGenerics>) {\n // this._checkInitialized();\n return await this.getClient().post(this._channelURL() + '/event', {\n event,\n });\n }\n\n async sendReaction(messageID: string, reactionType: string) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return await this.getClient().post<ReactionAPIResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/reaction/${reactionType}`,\n );\n }\n\n deleteReaction(messageID: string, reactionType: string) {\n // this._checkInitialized();\n if (!reactionType || !messageID) {\n throw Error('Deleting a reaction requires specifying both the message and reaction type');\n }\n\n const url = this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/reaction/${reactionType}`;\n //provided when server side request\n // if (user_id) {\n // return this.getClient().delete<ReactionAPIResponse<ErmisChatGenerics>>(url, { user_id });\n // }\n\n return this.getClient().delete<ReactionAPIResponse<ErmisChatGenerics>>(url, {});\n }\n\n async update(\n channelData: Partial<ChannelData<ErmisChatGenerics>> | Partial<ChannelResponse<ErmisChatGenerics>> = {},\n updateMessage?: Message<ErmisChatGenerics>,\n ) {\n // Strip out reserved names that will result in API errors.\n const reserved = [\n 'config',\n 'cid',\n 'created_by',\n 'id',\n 'member_count',\n 'type',\n 'created_at',\n 'updated_at',\n 'last_message_at',\n 'own_capabilities',\n ];\n reserved.forEach((key) => {\n delete channelData[key];\n });\n\n return await this._update({\n message: updateMessage,\n data: channelData,\n });\n }\n\n async delete() {\n return await this.getClient().delete(this._channelURL());\n }\n\n async truncate() {\n return await this.getClient().delete(this._channelURL() + '/truncate');\n }\n\n async blockUser() {\n return await this.getClient().post(this._channelURL(), { action: 'block' });\n }\n\n async unblockUser() {\n return await this.getClient().post(this._channelURL(), { action: 'unblock' });\n }\n\n async acceptInvite(action: string) {\n // const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/accept`;\n const channel_id = this.id;\n\n const url = this.getClient().userBaseURL + `/token_gate/join_channel/${this.type}`;\n return this.getClient().post<APIResponse>(url, {}, { channel_id, action });\n }\n\n async rejectInvite() {\n const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/reject`;\n return this.getClient().post<APIResponse>(url);\n }\n\n async skipInvite() {\n const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/skip`;\n return this.getClient().post<APIResponse>(url);\n }\n\n async addMembers(members: string[]) {\n return await this._update({ add_members: members });\n }\n\n async addModerators(members: string[]) {\n return await this._update({ promote_members: members });\n }\n\n async banMembers(members: string[]) {\n return await this._update({ ban_members: members });\n }\n\n async unbanMembers(members: string[]) {\n return await this._update({ unban_members: members });\n }\n\n async updateCapabilities(capabilities: string[]) {\n return await this._update({ capabilities });\n }\n\n /**\n * Set slow mode (message cooldown) for the channel.\n * Only applicable to team channels. Prevents members from sending\n * messages faster than the specified cooldown interval.\n *\n * @param cooldown - Cooldown duration in milliseconds.\n * Allowed values: 0 (off), 10000 (10s), 30000 (30s),\n * 60000 (1min), 300000 (5min), 900000 (15min), 3600000 (1h).\n */\n async setSlowMode(cooldown: 0 | 10000 | 30000 | 60000 | 300000 | 900000 | 3600000) {\n const allowedValues = [0, 10000, 30000, 60000, 300000, 900000, 3600000];\n if (!allowedValues.includes(cooldown)) {\n throw new Error(\n `Invalid cooldown value: ${cooldown}. Allowed values are: ${allowedValues.join(', ')} (milliseconds).`,\n );\n }\n return await this.update({ member_message_cooldown: cooldown } as any);\n }\n\n async queryAttachmentMessages() {\n const response = await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/attachment`,\n {\n attachment_types: ['image', 'video', 'file', 'voiceRecording', 'linkPreview'],\n },\n );\n\n // Sort newest first\n if (response.attachments) {\n response.attachments.sort(\n (a: any, b: any) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),\n );\n }\n\n return response;\n }\n\n async searchMessage(search_term: string, offset: number) {\n const response: any = await this.getClient().post(this.getClient().baseURL + `/channels/search`, {\n cid: this.cid,\n search_term,\n offset,\n limit: 25,\n });\n\n if (!response || response?.search_result?.messages.length === 0) {\n return null;\n }\n\n return {\n ...response?.search_result,\n messages: response?.search_result?.messages.map((message: any) => {\n const user = getUserInfo(message.user_id, Object.values(this.getClient().state.users)) || message.user;\n return { ...message, user };\n }),\n };\n }\n\n async removeMembers(members: string[]) {\n return await this._update({ remove_members: members });\n }\n\n async demoteModerators(members: string[]) {\n return await this._update({ demote_members: members });\n }\n\n async _update(payload: Object) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<ErmisChatGenerics>>(this._channelURL(), payload);\n this.data = { ...this.data, ...data.channel };\n return data;\n }\n\n _processTopics(topicsFromApi: any, users: any[]) {\n const topics = topicsFromApi.map((topic: any) => {\n // Enrich topic members with user info\n if (topic.channel && topic.channel.members) {\n topic.channel.members = enrichWithUserInfo(topic.channel.members, users);\n }\n // Enrich topic messages with user info\n if (topic.messages) {\n topic.messages = enrichWithUserInfo(topic.messages, users);\n }\n // Enrich topic pinned messages with user info\n if (topic.pinned_messages) {\n topic.pinned_messages = enrichWithUserInfo(topic.pinned_messages, users);\n }\n // Enrich topic read with user info\n if (topic.read) {\n topic.read = enrichWithUserInfo(topic.read, users);\n }\n return topic;\n });\n\n const { channels } = this.getClient().hydrateChannels(topics, {});\n\n // Store topics in channel state\n this.state.topics = channels;\n }\n\n async muteNotification(duration: number | null) {\n return await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/muted`,\n { mute: true, duration },\n );\n }\n\n async unMuteNotification() {\n return await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/muted`,\n { mute: false },\n );\n }\n\n async keystroke(parent_id?: string, options?: { user_id: string }) {\n const now = new Date();\n const diff = this.lastTypingEvent && now.getTime() - this.lastTypingEvent.getTime();\n this.lastKeyStroke = now;\n this.isTyping = true;\n // send a typing.start every 2 seconds\n if (diff === null || diff > 2000) {\n this.lastTypingEvent = new Date();\n await this.sendEvent({\n type: 'typing.start',\n parent_id,\n ...(options || {}),\n } as Event<ErmisChatGenerics>);\n }\n }\n\n async stopTyping(parent_id?: string, options?: { user_id: string }) {\n if (!this.isTyping) return;\n this.lastTypingEvent = null;\n this.isTyping = false;\n await this.sendEvent({\n type: 'typing.stop',\n parent_id,\n ...(options || {}),\n } as Event<ErmisChatGenerics>);\n }\n\n _isTypingIndicatorsEnabled(): boolean {\n return true;\n }\n\n lastMessage() {\n let min = this.state.latestMessages.length - 5;\n if (min < 0) {\n min = 0;\n }\n const max = this.state.latestMessages.length + 1;\n const messageSlice = this.state.latestMessages.slice(min, max);\n\n // sort by pk desc\n messageSlice.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());\n\n return messageSlice[0];\n }\n\n async markRead() {\n return await this.getClient().post(this._channelURL() + '/read');\n }\n\n clean() {\n if (this.lastKeyStroke) {\n const now = new Date();\n const diff = now.getTime() - this.lastKeyStroke.getTime();\n if (diff > 1000 && this.isTyping) {\n logChatPromiseExecution(this.stopTyping(), 'stop typing event');\n }\n }\n\n this.state.clean();\n }\n\n async watch(options?: ChannelQueryOptions) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n const combined = { ...options };\n const state = await this.query(combined, 'latest');\n this.initialized = true;\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this.getClient(), state.channel.members);\n\n // Get the latest users after updating\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.channel.image =\n state.channel.type === 'messaging'\n ? getDirectChannelImage(state.channel.members, this.getClient().userID || '')\n : state.channel.image;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n\n // Process topics for team channels (already handled in query, but ensuring consistency)\n if (this.type === 'team' && state.channel.topics_enabled) {\n const payload = {\n filter_conditions: { type: ['topic'], parent_cid: this.cid, project_id: this.getClient().projectId },\n sort: [],\n message_limit: 25,\n };\n const topicsFromApi: any = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + '/channels',\n payload,\n );\n\n this._processTopics(topicsFromApi.channels || [], users);\n }\n\n this.data = state.channel;\n\n this._client.logger('info', `channel:watch() - started watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n return state;\n }\n\n lastRead() {\n const { userID } = this.getClient();\n if (userID) {\n return this.state.read[userID] ? this.state.read[userID].last_read : null;\n }\n }\n // TODO: KhoaKheu Add mute Users later, confict here\n _countMessageAsUnread(message: FormatMessageResponse<ErmisChatGenerics> | MessageResponse<ErmisChatGenerics>) {\n if (message.parent_id && !message.show_in_channel) return false;\n if (message.user?.id === this.getClient().userID) return false;\n if (message.type === 'system') return false;\n\n // Return false if channel doesn't allow read events.\n if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes('read-events'))\n return false;\n\n return true;\n }\n\n countUnread(lastRead?: Date | null) {\n if (!lastRead) return this.state.unreadCount;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (message.created_at > lastRead && this._countMessageAsUnread(message)) {\n count++;\n }\n }\n return count;\n }\n\n getUnreadMemberCount() {\n if (!this.state.read) return [];\n\n return Object.values(this.state.read);\n }\n\n getCapabilitiesMember() {\n if (!this.data) return [];\n\n return this.data.member_capabilities;\n }\n\n create = async () => {\n if (this.type === 'messaging') {\n return await this.createDirectChannel('latest');\n } else {\n return await this.query({}, 'latest');\n }\n };\n\n async createTopic(data: any) {\n const project_id = this._client.projectId;\n const uuid = randomId();\n const topicID = `${project_id}:${uuid}`;\n\n const queryURL = `${this.getClient().baseURL}/channels/topic/${topicID}`;\n const payload: any = {\n project_id,\n parent_cid: this.cid,\n data: { ...data },\n };\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n\n return state;\n }\n\n async query(options: ChannelQueryOptions, messageSetToAddToIfDoesNotExist: MessageSetType = 'current') {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let update_options = { ...options, project_id };\n\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}`;\n if (this.id) {\n queryURL += `/${this.id}`;\n } else {\n if (this.type === 'team') {\n const uuid = randomId();\n this.id = `${project_id}:${uuid}`;\n queryURL += `/${this.id}`;\n }\n }\n\n const payload: any = {\n state: true,\n ...update_options,\n };\n\n if (this._data && Object.keys(this._data).length > 0) {\n payload.data = this._data;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this.getClient(), state.channel.members);\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.channel.image =\n state.channel.type === 'messaging'\n ? getDirectChannelImage(state.channel.members, this.getClient().userID || '')\n : state.channel.image;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n state.channel.is_pinned = state.is_pinned || false;\n\n // Process topics for team channels\n // if (this.type === 'team' && state.channel.topics_enabled && state.topics) {\n // this._processTopics(state.topics, users);\n // }\n\n // update the channel id if it was missing\n\n if (!this.id) {\n this.id = state.channel.id;\n this.cid = state.channel.cid;\n\n // set the channel as active...\n const membersStr = state.channel.members\n .map((member) => member.user_id || member.user?.id)\n .sort()\n .join(',');\n const tempChannelCid = `${this.type}:!members-${membersStr}`;\n\n if (tempChannelCid in this.getClient().activeChannels) {\n // This gets set in `client.channel()` function, when channel is created\n // using members, not id.\n delete this.getClient().activeChannels[tempChannelCid];\n }\n\n if (!(this.cid in this.getClient().activeChannels)) {\n this.getClient().activeChannels[this.cid] = this;\n }\n }\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n return state;\n }\n\n async createDirectChannel(messageSetToAddToIfDoesNotExist: MessageSetType = 'current') {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n const project_id = this._client.projectId;\n\n const queryURL = `${this.getClient().baseURL}/channels/${this.type}`;\n\n const payload: any = {\n project_id,\n };\n\n if (this._data && Object.keys(this._data).length > 0) {\n payload.data = this._data;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: state.channel.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n return state;\n }\n\n async queryMessagesLessThanId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_lt: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async queryMessagesGreaterThanId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_gt: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async queryMessagesAroundId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_around: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async deleteMessage(messageId: string) {\n return await this.getClient().delete<APIResponse & { message: MessageResponse<ErmisChatGenerics> }>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageId}`,\n );\n }\n\n async deleteMessageForMe(messageId: string) {\n return await this.getClient().delete<APIResponse & { message: MessageResponse<ErmisChatGenerics> }>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageId}`,\n { for_me: true },\n );\n }\n\n async getThumbBlobVideo(file: File): Promise<Blob | null> {\n return new Promise((resolve) => {\n const seekTo = 0.1;\n const videoPlayer = document.createElement('video');\n videoPlayer.src = URL.createObjectURL(file);\n videoPlayer.crossOrigin = 'anonymous'; // Tránh lỗi CORS nếu cần\n videoPlayer.load();\n\n videoPlayer.addEventListener('error', () => {\n console.error('Error when loading video file.');\n resolve(null);\n });\n\n videoPlayer.addEventListener('loadedmetadata', () => {\n if (videoPlayer.duration < seekTo) {\n console.error('Video is too short.');\n resolve(null);\n return;\n }\n\n setTimeout(() => {\n videoPlayer.currentTime = seekTo;\n }, 200);\n });\n\n videoPlayer.addEventListener('seeked', () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = videoPlayer.videoWidth;\n canvas.height = videoPlayer.videoHeight;\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n console.error('Failed to create canvas context.');\n resolve(null);\n return;\n }\n\n ctx.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);\n\n ctx.canvas.toBlob(\n (blob) => {\n if (!blob) {\n console.error('Failed to generate thumbnail.');\n resolve(null);\n return;\n }\n resolve(blob);\n URL.revokeObjectURL(videoPlayer.src); // Giải phóng bộ nhớ\n },\n 'image/jpeg',\n 0.75,\n );\n } catch (error) {\n console.error('Error while extracting thumbnail:', error);\n resolve(null);\n }\n });\n });\n }\n\n async enableTopics() {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/enable`, {\n project_id: this.getClient().projectId,\n messages: { limit: 25 },\n });\n }\n\n async disableTopics() {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/disable`, {\n project_id: this.getClient().projectId,\n });\n }\n\n async closeTopic(topicCID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/close`, {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n });\n }\n\n async reopenTopic(topicCID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/reopen`, {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n });\n }\n\n async editTopic(topicCID: string, data: any) {\n const response: any = await this.getClient().post(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics`,\n {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n data,\n },\n );\n\n if (response) {\n const activeTopic = this.getClient().activeChannels[topicCID];\n\n if (activeTopic) {\n activeTopic.data = response.channel;\n return activeTopic.data;\n } else {\n return response.channel;\n }\n }\n }\n\n on(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<ErmisChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this._client.logger('info', `Attaching listener for ${key} event on channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key].push(callback);\n\n return {\n unsubscribe: () => {\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n off(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): void;\n off(callback: EventHandler<ErmisChatGenerics>): void;\n off(\n callbackOrString: EventHandler<ErmisChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): void {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n async _handleChannelEvent(event: Event<ErmisChatGenerics>) {\n const channel = this;\n this._client.logger(\n 'info',\n `channel:_handleChannelEvent - Received event of type { ${event.type} } on ${this.cid}`,\n {\n tags: ['event', 'channel'],\n channel: this,\n },\n );\n\n const channelState = channel.state;\n const users = Object.values(this.getClient().state.users);\n switch (event.type) {\n case 'typing.start':\n if (event.user?.id) {\n const user = getUserInfo(event.user.id || '', users);\n event.user = user;\n channelState.typing[event.user.id] = event;\n }\n break;\n case 'typing.stop':\n if (event.user?.id) {\n delete channelState.typing[event.user.id];\n }\n break;\n case 'message.read':\n if (event.user?.id && event.created_at) {\n const user = getUserInfo(event.user.id || '', users);\n event.user = user;\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at),\n last_read_message_id: event.last_read_message_id,\n user,\n unread_messages: 0,\n };\n\n if (event.user?.id === this.getClient().user?.id) {\n channelState.unreadCount = 0;\n }\n }\n break;\n case 'user.watching.start':\n if (event.user?.id) {\n channelState.watchers[event.user.id] = event.user;\n }\n break;\n case 'user.watching.stop':\n if (event.user?.id) {\n delete channelState.watchers[event.user.id];\n }\n break;\n case 'message.deleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n //! NOTE: check lai o day\n channelState.removeMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n // if (event.hard_delete) channelState.removeMessage(event.message);\n // else channelState.addMessageSorted(event.message, false, false);\n\n channelState.removeQuotedMessageReferences(event.message);\n\n // if (event.message.pinned) {\n // channelState.removePinnedMessage(event.message);\n // }\n\n if ([...channelState.pinnedMessages].some((msg) => msg.id === event.message?.id)) {\n channelState.removePinnedMessage(event.message);\n }\n\n for (const userId in channelState.read) {\n if (userId !== event.user?.id && event.message.id === channelState.read[userId].last_read_message_id) {\n // Clear last_read_message_id if the deleted message is the last_read_message_id\n channelState.read[userId] = { ...channelState.read[userId], last_read_message_id: undefined };\n }\n }\n }\n break;\n case 'message.deleted_for_me':\n if (event.message) {\n channelState.removeMessage(event.message);\n channelState.removeQuotedMessageReferences(event.message);\n\n if ([...channelState.pinnedMessages].some((msg) => msg.id === event.message?.id)) {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.new':\n if (event.message) {\n /* if message belongs to current user, always assume timestamp is changed to filter it out and add again to avoid duplication */\n const ownMessage = event.user?.id === this.getClient().user?.id;\n const isThreadMessage = !!event.message.parent_id;\n\n const existUser = users.find((user) => user.id === event.user?.id);\n if (!existUser) {\n if (event.user?.id) {\n const resUser = await this.getClient().queryUser(event.user.id);\n users.push(resUser);\n }\n }\n\n const userInfo = getUserInfo(event.user?.id || '', users);\n event.message.user = userInfo;\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.user = userInfo;\n\n if (this.state.isUpToDate || isThreadMessage) {\n channelState.addMessageSorted(event.message, ownMessage);\n }\n // if (event.message.pinned) {\n // channelState.addPinnedMessage(event.message);\n // }\n\n // do not increase the unread count - the back-end does not increase the count neither in the following cases:\n // 1. the message is mine\n // 2. the message is a thread reply from any user\n const preventUnreadCountUpdate = ownMessage || isThreadMessage;\n if (preventUnreadCountUpdate) break;\n\n if (event.user?.id) {\n for (const userId in channelState.read) {\n if (userId === event.user.id) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at as string),\n user: event.user,\n unread_messages: 0,\n };\n } else {\n channelState.read[userId].unread_messages += 1;\n }\n }\n }\n\n if (this._countMessageAsUnread(event.message)) {\n channelState.unreadCount = channelState.unreadCount + 1;\n }\n }\n break;\n case 'message.updated':\n if (event.message) {\n const userEvent = getUserInfo(event.user?.id || '', users);\n const userMsg = getUserInfo(event.message.user?.id || '', users);\n event.user = userEvent;\n event.message.user = userMsg;\n\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n\n if (event.message?.latest_reactions) {\n event.message.latest_reactions = enrichWithUserInfo(event.message.latest_reactions || [], users);\n }\n\n this._extendEventWithOwnReactions(event);\n channelState.addMessageSorted(event.message, false, false);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n } else {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.pinned':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.addPinnedMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'message.unpinned':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.removePinnedMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'channel.truncate':\n if (event.channel?.created_at) {\n const truncatedAt = +new Date(event.channel.created_at);\n\n channelState.messageSets.forEach((messageSet, messageSetIndex) => {\n messageSet.messages.forEach(({ created_at: createdAt, id }) => {\n if (truncatedAt > +createdAt) channelState.removeMessage({ id, messageSetIndex });\n });\n });\n\n channelState.pinnedMessages.forEach(({ id, created_at: createdAt }) => {\n if (truncatedAt > +createdAt)\n channelState.removePinnedMessage({ id } as MessageResponse<ErmisChatGenerics>);\n });\n } else {\n channelState.clearMessages();\n }\n\n channelState.unreadCount = 0;\n // system messages don't increment unread counts\n if (event.message) {\n channelState.addMessageSorted(event.message);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n }\n break;\n case 'member.added':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n channelState.members[event.member.user_id] = event.member;\n\n if (event.member.user?.id === this.getClient().user?.id) {\n channelState.membership = event.member;\n }\n }\n break;\n case 'member.updated':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n channelState.members[event.member.user_id] = event.member;\n channelState.membership = event.member;\n }\n break;\n case 'member.removed':\n if (event.member?.user_id) {\n delete channelState.members[event.member.user_id];\n } else if (event.user?.id) {\n // fallback just in case some legacy payload uses event.user for the removed user\n delete channelState.members[event.user.id];\n }\n break;\n case 'channel.updated':\n if (event.channel) {\n channel.data = {\n ...channel.data,\n ...event.channel,\n own_capabilities: event.channel?.own_capabilities ?? channel.data?.own_capabilities,\n };\n }\n break;\n case 'pollchoice.new':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'reaction.new':\n if (event.message && event.reaction) {\n const userMsg = getUserInfo(event.message.user?.id || '', users);\n const userReaction = getUserInfo(event.reaction.user?.id || '', users);\n event.message.user = userMsg;\n event.message.latest_reactions = enrichWithUserInfo(event.message.latest_reactions || [], users);\n event.reaction.user = userReaction;\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.message = channelState.addReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.deleted':\n event.user = getUserInfo(event.user?.id || '', users);\n if (event.message) {\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.message.user = getUserInfo(event.message.user?.id || '', users);\n event.message.latest_reactions?.map((item) => {\n item.user = getUserInfo(item.user?.id || '', users);\n return item;\n });\n }\n\n if (event.reaction) {\n event.reaction.user = getUserInfo(event.reaction.user?.id || '', users);\n event.message = channelState.removeReaction(event.reaction, event.message);\n }\n break;\n case 'member.joined':\n case 'notification.invite_accepted':\n if (event.member?.user_id) {\n const existUser = users.find((user) => user.id === event.member?.user_id);\n\n if (!existUser) {\n const resUser = await this.getClient().queryUser(event.member?.user_id);\n users.push(resUser);\n }\n\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n\n channelState.members[event.member.user_id] = event.member;\n channel.data = {\n ...channel.data,\n member_count: Number(channel.data?.member_count) + 1,\n members: channel.data?.members ? [...channel.data.members, event.member] : [event.member],\n } as ChannelAPIResponse<ErmisChatGenerics>['channel'];\n this.offlineMode = true;\n this.initialized = true;\n }\n break;\n case 'notification.invite_rejected':\n if (event.member?.user_id) {\n delete channelState.members[event.member.user_id];\n\n // channel.data = {\n // ...channel.data,\n // member_count: Number(channel.data?.member_count) - 1,\n // members: channel.data?.members?.filter((m: any) => m.user_id !== event.member?.user_id) || [],\n // } as ChannelAPIResponse<ErmisChatGenerics>['channel'];\n }\n break;\n case 'notification.invite_messaging_skipped':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n\n channelState.members[event.member.user_id] = event.member;\n\n // this.offlineMode = true;\n // this.initialized = true;\n }\n break;\n case 'member.promoted':\n case 'member.demoted':\n case 'member.banned':\n case 'member.unbanned':\n case 'member.blocked':\n case 'member.unblocked':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n channelState.members[event.member.user_id] = event.member;\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n }\n break;\n case 'channel.pinned':\n if (channel.data) {\n channel.data.is_pinned = true;\n }\n break;\n case 'channel.unpinned':\n if (channel.data) {\n channel.data.is_pinned = false;\n }\n break;\n case 'channel.topic.disabled':\n if (channel.data) {\n channel.data.topics_enabled = false;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.enabled':\n if (channel.data) {\n channel.data.topics_enabled = true;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.created':\n const members = event.channel?.members || [];\n const enrichedMembers = enrichWithUserInfo(members, users);\n\n const topicState: any = {\n channel: event.channel,\n members: enrichedMembers,\n messages: [],\n pinned_messages: [],\n };\n const topic = this.getClient().channel(event.channel_type || '', event.channel_id || '');\n topic.data = event.channel;\n topic._initializeState(topicState, 'latest');\n channelState.topics?.unshift(topic);\n break;\n case 'channel.topic.closed':\n if (channel.data) {\n channel.data.is_closed_topic = true;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.reopen':\n if (channel.data) {\n channel.data.is_closed_topic = false;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.updated':\n if (channel.data) {\n channel.data.name = event.channel?.name;\n channel.data.image = event.channel?.image;\n channel.data.description = event.channel?.description;\n }\n\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n default:\n }\n\n // any event can send over the online count\n if (event.watcher_count !== undefined) {\n channel.state.watcher_count = event.watcher_count;\n }\n }\n\n _callChannelListeners = (event: Event<ErmisChatGenerics>) => {\n const channel = this;\n // gather and call the listeners\n const listeners = [];\n if (channel.listeners.all) {\n listeners.push(...channel.listeners.all);\n }\n if (channel.listeners[event.type]) {\n listeners.push(...channel.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n if (typeof listener !== 'string') {\n listener(event);\n }\n }\n };\n\n _channelURL = () => {\n if (!this.id) {\n throw new Error('channel id is not defined');\n }\n return `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n };\n\n _checkInitialized() {\n if (!this.initialized && !this.offlineMode) {\n throw Error(\n `Channel ${this.cid} hasn't been initialized yet. Make sure to call .watch() and wait for it to resolve`,\n );\n }\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _initializeState(\n state: ChannelAPIResponse<ErmisChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n updateUserIds?: (id: string) => void,\n ) {\n const { state: clientState, user, userID } = this.getClient();\n // add the Users\n if (state.channel.members) {\n for (const member of state.channel.members) {\n if (member.user) {\n if (updateUserIds) {\n updateUserIds(member.user.id);\n }\n clientState.updateUserReference(member.user, this.cid);\n }\n }\n }\n\n this.state.membership = state.membership || {};\n\n // Remove duplicate messages by ID\n const map = new Map();\n const uniqueMessages = [];\n\n if (!state.messages) {\n state.messages = [];\n }\n for (const msg of state.messages) {\n if (!map.has(msg.id)) {\n map.set(msg.id, true);\n uniqueMessages.push(msg);\n }\n }\n\n if (this.state.pinnedMessages) {\n this.state.pinnedMessages = [];\n }\n this.state.addPinnedMessages(state.pinned_messages || []);\n\n const messages = uniqueMessages || [];\n if (!this.state.messages) {\n this.state.initMessages();\n }\n const { messageSet } = this.state.addMessagesSorted(messages, false, true, true, messageSetToAddToIfDoesNotExist);\n\n if (state.watcher_count !== undefined) {\n this.state.watcher_count = state.watcher_count;\n }\n // NOTE: we don't send the watchers with the channel data anymore\n // // convert the arrays into objects for easier syncing...\n if (state.watchers) {\n for (const watcher of state.watchers) {\n if (watcher) {\n clientState.updateUserReference(watcher, this.cid);\n this.state.watchers[watcher.id] = watcher;\n }\n }\n }\n\n // initialize read state to last message or current time if the channel is empty\n // if the user is a member, this value will be overwritten later on otherwise this ensures\n // that everything up to this point is not marked as unread\n if (userID != null) {\n const last_read = this.state.last_message_at || new Date();\n if (user) {\n this.state.read[user.id] = {\n user,\n last_read,\n unread_messages: 0,\n };\n }\n }\n\n // apply read state if part of the state\n if (state.read) {\n for (const read of state.read) {\n this.state.read[read.user.id] = {\n last_read: new Date(read.last_read),\n last_read_message_id: read.last_read_message_id,\n unread_messages: read.unread_messages ?? 0,\n user: read.user,\n last_send: read.last_send,\n };\n\n if (read.user.id === user?.id) {\n this.state.unreadCount = this.state.read[read.user.id].unread_messages;\n }\n }\n }\n\n if (state.channel.members) {\n this.state.members = state.channel.members.reduce((acc, member) => {\n if (member.user) {\n acc[member.user.id] = member;\n }\n return acc;\n }, {} as ChannelState<ErmisChatGenerics>['members']);\n }\n\n // Process topics for team channels\n if (state.channel.type === 'team' && state.channel.topics_enabled && state.topics) {\n const users = Object.values(this.getClient().state.users);\n this._processTopics(state.topics, users);\n }\n\n return {\n messageSet,\n };\n }\n\n _extendEventWithOwnReactions(event: Event<ErmisChatGenerics>) {\n if (!event.message) {\n return;\n }\n const message = this.state.findMessage(event.message.id, event.message.parent_id);\n if (message) {\n event.message.own_reactions = message.own_reactions;\n }\n }\n\n _disconnect() {\n this._client.logger('info', `channel:disconnect() - Disconnecting the channel ${this.cid}`, {\n tags: ['connection', 'channel'],\n channel: this,\n });\n\n this.disconnected = true;\n this.state.setIsUpToDate(false);\n }\n}\n","import { UserResponse, ExtendableGenerics, DefaultGenerics } from './types';\n\n/**\n * ClientState - A container class for the client state.\n */\nexport class ClientState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n users: {\n [key: string]: UserResponse<ErmisChatGenerics>;\n };\n userChannelReferences: { [key: string]: { [key: string]: boolean } };\n constructor() {\n // show the status for a certain user...\n // ie online, offline etc\n this.users = {};\n // store which channels contain references to the specified user...\n this.userChannelReferences = {};\n }\n\n updateUsers(users: UserResponse<ErmisChatGenerics>[]) {\n for (const user of users) {\n this.updateUser(user);\n }\n }\n\n updateUser(user?: UserResponse<ErmisChatGenerics>) {\n if (user != null) {\n if (this.users[user.id]) {\n // Update existing user's fields, because the user is updated from 2 diffferent servers\n const updatedUser = { ...this.users[user.id], ...user };\n this.users[user.id] = updatedUser;\n } else {\n // Add new user\n this.users[user.id] = user;\n }\n }\n }\n\n updateUserReference(user: UserResponse<ErmisChatGenerics>, channelID: string) {\n if (user == null) {\n return;\n }\n // dont update user here\n // this.updateUser(user);\n if (!this.userChannelReferences[user.id]) {\n this.userChannelReferences[user.id] = {};\n }\n this.userChannelReferences[user.id][channelID] = true;\n }\n\n deleteAllChannelReference(channelID: string) {\n for (const userID in this.userChannelReferences) {\n delete this.userChannelReferences[userID][channelID];\n }\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport {\n chatCodes,\n sleep,\n retryInterval,\n randomId,\n removeConnectionEventListeners,\n addConnectionEventListeners,\n} from './utils';\n\nimport { ConnectAPIResponse, ConnectionOpen, ExtendableGenerics, DefaultGenerics, UR, LogLevel } from './types';\nimport { ErmisChat } from './client';\n\n// Type guards to check WebSocket error type\nconst isCloseEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.CloseEvent =>\n (res as WebSocket.CloseEvent).code !== undefined;\n\nconst isErrorEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.ErrorEvent =>\n (res as WebSocket.ErrorEvent).error !== undefined;\n\n/**\n * StableWSConnection - A WS connection that reconnects upon failure.\n * - the browser will sometimes report that you're online or offline\n * - the WS connection can break and fail (there is a 30s health check)\n * - sometimes your WS connection will seem to work while the user is in fact offline\n * - to speed up online/offline detection you can use the window.addEventListener('offline');\n *\n * There are 4 ways in which a connection can become unhealthy:\n * - websocket.onerror is called\n * - websocket.onclose is called\n * - the health check fails and no event is received for ~40 seconds\n * - the browser indicates the connection is now offline\n *\n * There are 2 assumptions we make about the server:\n * - state can be recovered by querying the channel again\n * - if the servers fails to publish a message to the client, the WS connection is destroyed\n */\nexport class StableWSConnection<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n // global from constructor\n client: ErmisChat<ErmisChatGenerics>;\n\n // local vars\n\n connectionOpen?: ConnectAPIResponse<ErmisChatGenerics>;\n consecutiveFailures: number;\n pingInterval: number;\n healthCheckTimeoutRef?: NodeJS.Timeout;\n isConnecting: boolean;\n isDisconnected: boolean;\n isHealthy: boolean;\n isResolved?: boolean;\n lastEvent: Date | null;\n connectionCheckTimeout: number;\n connectionCheckTimeoutRef?: NodeJS.Timeout;\n rejectPromise?: (\n reason?: Error & { code?: string | number; isWSFailure?: boolean; StatusCode?: string | number },\n ) => void;\n requestID: string | undefined;\n resolvePromise?: (value: ConnectionOpen<ErmisChatGenerics>) => void;\n totalFailures: number;\n ws?: WebSocket;\n wsID: number;\n\n constructor({ client }: { client: ErmisChat<ErmisChatGenerics> }) {\n /** ErmisChat client */\n this.client = client;\n /** consecutive failures influence the duration of the timeout */\n this.consecutiveFailures = 0;\n /** keep track of the total number of failures */\n this.totalFailures = 0;\n /** We only make 1 attempt to reconnect at the same time.. */\n this.isConnecting = false;\n /** To avoid reconnect if client is disconnected */\n this.isDisconnected = false;\n /** Boolean that indicates if the connection promise is resolved */\n this.isResolved = false;\n /** Boolean that indicates if we have a working connection to the server */\n this.isHealthy = false;\n /** Incremented when a new WS connection is made */\n this.wsID = 1;\n /** Store the last event time for health checks */\n this.lastEvent = null;\n /** Send a health check message every 25 seconds */\n this.pingInterval = 25 * 1000;\n this.connectionCheckTimeout = this.pingInterval + 10 * 1000;\n\n addConnectionEventListeners(this.onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'connection:' + msg, { tags: ['connection'], ...extra });\n }\n\n setClient(client: ErmisChat<ErmisChatGenerics>) {\n this.client = client;\n }\n\n async connect(timeout = 15000) {\n if (this.isConnecting) {\n throw Error(`You've called connect twice, can only attempt 1 connection at the time`);\n }\n\n this.isDisconnected = false;\n\n try {\n const healthCheck = await this._connect();\n this.consecutiveFailures = 0;\n\n this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);\n } catch (error: any) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n if (error.code === chatCodes.TOKEN_EXPIRED) {\n this._log('connect() - WS failure due to expired token');\n } else if (!error.isWSFailure) {\n // API rejected the connection and we should not retry\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n }\n\n return await this._waitForHealthy(timeout);\n }\n\n /**\n * _waitForHealthy polls the promise connection to see if its resolved until it times out\n * the default 15s timeout allows between 2~3 tries\n * @param timeout duration(ms)\n */\n async _waitForHealthy(timeout = 15000) {\n return Promise.race([\n (async () => {\n const interval = 50; // ms\n for (let i = 0; i <= timeout; i += interval) {\n try {\n return await this.connectionOpen;\n } catch (error: any) {\n if (i === timeout) {\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n await sleep(interval);\n }\n }\n })(),\n (async () => {\n await sleep(timeout);\n this.isConnecting = false;\n throw new Error(\n JSON.stringify({\n code: '',\n StatusCode: '',\n message: 'initial WS connection could not be established',\n isWSFailure: true,\n }),\n );\n })(),\n ]);\n }\n\n /**\n * Builds and returns the url for websocket.\n * @private\n * @returns url string\n */\n _buildUrl = () => {\n const qs = encodeURIComponent(this.client._buildWSPayload(this.requestID));\n const token = this.client.tokenManager.getToken();\n\n let rawURL = `${this.client.wsBaseURL}/connect?json=${qs}&api_key=${\n this.client.apiKey\n }&authorization=${token}&stream-auth-type=${this.client.getAuthType()}&X-Stream-Client=${this.client.getUserAgent()}`;\n rawURL = encodeURI(rawURL);\n return rawURL;\n };\n\n /**\n * disconnect - Disconnect the connection and doesn't recover...\n *\n */\n disconnect(timeout?: number) {\n this._log(`disconnect() - Closing the websocket connection for wsID ${this.wsID}`);\n\n this.wsID += 1;\n this.isConnecting = false;\n this.isDisconnected = true;\n\n // start by removing all the listeners\n if (this.healthCheckTimeoutRef) {\n clearInterval(this.healthCheckTimeoutRef);\n }\n if (this.connectionCheckTimeoutRef) {\n clearInterval(this.connectionCheckTimeoutRef);\n }\n\n removeConnectionEventListeners(this.onlineStatusChanged);\n\n this.isHealthy = false;\n\n // remove ws handlers...\n if (this.ws && this.ws.removeAllListeners) {\n this.ws.removeAllListeners();\n }\n\n let isClosedPromise: Promise<void>;\n // and finally close...\n // Assigning to local here because we will remove it from this before the\n // promise resolves.\n const { ws } = this;\n if (ws && ws.close && ws.readyState === ws.OPEN) {\n isClosedPromise = new Promise((resolve) => {\n const onclose = (event: WebSocket.CloseEvent) => {\n this._log(`disconnect() - resolving isClosedPromise ${event ? 'with' : 'without'} close frame`, { event });\n resolve();\n };\n\n ws.onclose = onclose;\n // In case we don't receive close frame websocket server in time,\n // lets not wait for more than 1 seconds.\n setTimeout(onclose, timeout != null ? timeout : 1000);\n });\n\n this._log(`disconnect() - Manually closed connection by calling client.disconnect()`);\n\n ws.close(chatCodes.WS_CLOSED_SUCCESS, 'Manually closed connection by calling client.disconnect()');\n } else {\n this._log(`disconnect() - ws connection doesn't exist or it is already closed.`);\n isClosedPromise = Promise.resolve();\n }\n\n delete this.ws;\n\n return isClosedPromise;\n }\n\n async _connect() {\n if (this.isConnecting) return; // simply ignore _connect if it's currently trying to connect\n this.isConnecting = true;\n this.requestID = randomId();\n\n let isTokenReady = false;\n try {\n this._log(`_connect() - waiting for token`);\n await this.client.tokenManager.tokenReady();\n isTokenReady = true;\n } catch (e) {\n // token provider has failed before, so try again\n }\n\n try {\n this._setupConnectionPromise();\n const wsURL = this._buildUrl();\n this._log(`_connect() - Connecting to ${wsURL}`, { wsURL, requestID: this.requestID });\n this.ws = new WebSocket(wsURL);\n this.ws.onopen = this.onopen.bind(this, this.wsID);\n this.ws.onclose = this.onclose.bind(this, this.wsID);\n this.ws.onerror = this.onerror.bind(this, this.wsID);\n this.ws.onmessage = this.onmessage.bind(this, this.wsID);\n const response = await this.connectionOpen;\n this.isConnecting = false;\n\n if (response) {\n return response;\n }\n } catch (err: any) {\n this.isConnecting = false;\n this._log(`_connect() - Error - `, err);\n\n throw err;\n }\n }\n\n /**\n * _reconnect - Retry the connection to WS endpoint\n *\n * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available\n *\n * - `interval`\t{int}\t\t\tnumber of ms that function should wait before reconnecting\n * - `refreshToken` {boolean}\treload/refresh user token be refreshed before attempting reconnection.\n */\n async _reconnect(options: { interval?: number; refreshToken?: boolean } = {}): Promise<void> {\n this._log('_reconnect() - Initiating the reconnect');\n\n // only allow 1 connection at the time\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (1) since already connecting or healthy');\n return;\n }\n\n // reconnect in case of on error or on close\n // also reconnect if the health check cycle fails\n let interval = options.interval;\n if (!interval) {\n interval = retryInterval(this.consecutiveFailures);\n }\n // reconnect, or try again after a little while...\n await sleep(interval);\n\n // Check once again if by some other call to _reconnect is active or connection is\n // already restored, then no need to proceed.\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (2) since already connecting or healthy');\n return;\n }\n\n if (this.isDisconnected) {\n this._log('_reconnect() - Abort (3) since disconnect() is called');\n return;\n }\n\n this._log('_reconnect() - Destroying current WS connection');\n\n // cleanup the old connection\n this._destroyCurrentWSConnection();\n\n try {\n await this._connect();\n this._log('_reconnect() - Waiting for recoverCallBack');\n await this.client.recoverState();\n this._log('_reconnect() - Finished recoverCallBack');\n\n this.consecutiveFailures = 0;\n } catch (error: any) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n // reconnect on WS failures, don't reconnect if there is a code bug\n if (error.isWSFailure) {\n this._log('_reconnect() - WS failure, so going to try to reconnect');\n\n this._reconnect();\n }\n }\n this._log('_reconnect() - == END ==');\n }\n\n /**\n * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.\n *\n * @param {Event} event Event with type online or offline\n *\n */\n onlineStatusChanged = (event: Event) => {\n if (event.type === 'offline') {\n // mark the connection as down\n this._log('onlineStatusChanged() - Status changing to offline');\n this._setHealth(false);\n } else if (event.type === 'online') {\n // retry right now...\n // We check this.isHealthy, not sure if it's always\n // smart to create a new WS connection if the old one is still up and running.\n // it's possible we didn't miss any messages, so this process is just expensive and not needed.\n this._log(`onlineStatusChanged() - Status changing to online. isHealthy: ${this.isHealthy}`);\n if (!this.isHealthy) {\n this._reconnect({ interval: 10 });\n }\n }\n };\n\n onopen = (wsID: number) => {\n if (this.wsID !== wsID) return;\n\n this._log('onopen() - onopen callback', { wsID });\n };\n\n onmessage = (wsID: number, event: WebSocket.MessageEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onmessage() - onmessage callback', { event, wsID });\n const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;\n\n // we wait till the first message before we consider the connection open..\n // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately\n // after that a ws.onclose..\n if (!this.isResolved && data) {\n this.isResolved = true;\n if (data.error) {\n this.rejectPromise?.(this._errorFromWSEvent(data, false));\n return;\n }\n\n this.resolvePromise?.(data);\n this._setHealth(true);\n }\n\n // trigger the event..\n this.lastEvent = new Date();\n\n if (data && data.type === 'health.check') {\n this.scheduleNextPing();\n }\n\n this.client.handleEvent(event);\n this.scheduleConnectionCheck();\n };\n\n onclose = (wsID: number, event: WebSocket.CloseEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onclose() - onclose callback - ' + event.code, { event, wsID });\n\n if (event.code === chatCodes.WS_CLOSED_SUCCESS) {\n // this is a permanent error raised by stream..\n // usually caused by invalid auth details\n const error = new Error(`WS connection reject with error ${event.reason}`) as Error & WebSocket.CloseEvent;\n\n error.reason = event.reason;\n error.code = event.code;\n error.wasClean = event.wasClean;\n error.target = event.target;\n\n this.rejectPromise?.(error);\n this._log(`onclose() - WS connection reject with error ${event.reason}`, { event });\n } else {\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n\n this._log(`onclose() - WS connection closed. Calling reconnect ...`, { event });\n\n // reconnect if its an abnormal failure\n this._reconnect();\n }\n };\n\n onerror = (wsID: number, event: WebSocket.ErrorEvent) => {\n if (this.wsID !== wsID) return;\n\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n this._log(`onerror() - WS connection resulted into error`, { event });\n\n this._reconnect();\n };\n\n /**\n * _setHealth - Sets the connection to healthy or unhealthy.\n * Broadcasts an event in case the connection status changed.\n *\n * @param {boolean} healthy boolean indicating if the connection is healthy or not\n *\n */\n _setHealth = (healthy: boolean) => {\n if (healthy === this.isHealthy) return;\n\n this.isHealthy = healthy;\n\n if (this.isHealthy) {\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n return;\n }\n\n // we're offline, wait few seconds and fire and event if still offline\n setTimeout(() => {\n if (this.isHealthy) return;\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n }, 1000);\n };\n\n /**\n * _errorFromWSEvent - Creates an error object for the WS event\n *\n */\n _errorFromWSEvent = (event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent, isWSFailure = true) => {\n let code;\n let statusCode;\n let message;\n if (isCloseEvent(event)) {\n code = event.code;\n statusCode = 'unknown';\n message = event.reason;\n }\n\n if (isErrorEvent(event)) {\n code = event.error.code;\n statusCode = event.error.StatusCode;\n message = event.error.message;\n }\n\n // Keeping this `warn` level log, to avoid cluttering of error logs from ws failures.\n this._log(`_errorFromWSEvent() - WS failed with code ${code}`, { event }, 'warn');\n\n const error = new Error(`WS failed with code ${code} and reason - ${message}`) as Error & {\n code?: string | number;\n isWSFailure?: boolean;\n StatusCode?: string | number;\n };\n error.code = code;\n /**\n * StatusCode does not exist on any event types but has been left\n * as is to preserve JS functionality during the TS implementation\n */\n error.StatusCode = statusCode;\n error.isWSFailure = isWSFailure;\n return error;\n };\n\n /**\n * _destroyCurrentWSConnection - Removes the current WS connection\n *\n */\n _destroyCurrentWSConnection() {\n // increment the ID, meaning we will ignore all messages from the old\n // ws connection from now on.\n this.wsID += 1;\n\n try {\n this?.ws?.removeAllListeners();\n this?.ws?.close();\n } catch (e) {\n // we don't care\n }\n }\n\n /**\n * _setupPromise - sets up the this.connectOpen promise\n */\n _setupConnectionPromise = () => {\n this.isResolved = false;\n /** a promise that is resolved once ws.open is called */\n this.connectionOpen = new Promise<ConnectionOpen<ErmisChatGenerics>>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n };\n\n /**\n * Schedules a next health check ping for websocket.\n */\n scheduleNextPing = () => {\n if (this.healthCheckTimeoutRef) {\n clearTimeout(this.healthCheckTimeoutRef);\n }\n\n // 30 seconds is the recommended interval (messenger uses this)\n this.healthCheckTimeoutRef = setTimeout(() => {\n // send the healthcheck.., server replies with a health check event\n const data = [{ type: 'health.check', client_id: this.client.clientID }];\n // try to send on the connection\n try {\n this.ws?.send(JSON.stringify(data));\n } catch (e) {\n // error will already be detected elsewhere\n }\n }, this.pingInterval);\n };\n\n /**\n * scheduleConnectionCheck - schedules a check for time difference between last received event and now.\n * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs\n * to be reconnected.\n */\n scheduleConnectionCheck = () => {\n if (this.connectionCheckTimeoutRef) {\n clearTimeout(this.connectionCheckTimeoutRef);\n }\n\n this.connectionCheckTimeoutRef = setTimeout(() => {\n const now = new Date();\n if (this.lastEvent && now.getTime() - this.lastEvent.getTime() > this.connectionCheckTimeout) {\n this._log('scheduleConnectionCheck - going to reconnect');\n this._setHealth(false);\n this._reconnect();\n }\n }, this.connectionCheckTimeout);\n };\n}\n","import { ExtendableGenerics, DefaultGenerics, UserResponse } from './types';\n\n/**\n * TokenManager\n *\n * Manages token storage and retrieval for the chat client.\n */\nexport class TokenManager<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n loadTokenPromise: Promise<string> | null;\n token?: string;\n user?: UserResponse<ErmisChatGenerics>;\n\n constructor() {\n this.loadTokenPromise = null;\n }\n\n /**\n * Set the static string token.\n */\n setTokenOrProvider = async (tokenOrProvider: string | null, user: UserResponse<ErmisChatGenerics>) => {\n this.user = user;\n\n if (typeof tokenOrProvider === 'string') {\n this.token = tokenOrProvider;\n }\n\n this.loadTokenPromise = Promise.resolve(this.token as string);\n };\n\n /**\n * Resets the token manager.\n */\n reset = () => {\n this.token = undefined;\n this.user = undefined;\n this.loadTokenPromise = null;\n };\n\n /**\n * Resolves when token is ready.\n */\n tokenReady = () => this.loadTokenPromise;\n\n /** Returns the current token */\n getToken = () => {\n return this.token;\n };\n}\n","import { AxiosResponse } from 'axios';\nimport { APIErrorResponse } from './types';\n\nexport const APIErrorCodes: Record<string, { name: string; retryable: boolean }> = {\n '-1': { name: 'InternalSystemError', retryable: true },\n '2': { name: 'AccessKeyError', retryable: false },\n '3': { name: 'AuthenticationFailedError', retryable: true },\n '4': { name: 'InputError', retryable: false },\n '6': { name: 'DuplicateUsernameError', retryable: false },\n '9': { name: 'RateLimitError', retryable: true },\n '16': { name: 'DoesNotExistError', retryable: false },\n '17': { name: 'NotAllowedError', retryable: false },\n '18': { name: 'EventNotSupportedError', retryable: false },\n '19': { name: 'ChannelFeatureNotSupportedError', retryable: false },\n '20': { name: 'MessageTooLongError', retryable: false },\n '21': { name: 'MultipleNestingLevelError', retryable: false },\n '22': { name: 'PayloadTooBigError', retryable: false },\n '23': { name: 'RequestTimeoutError', retryable: true },\n '24': { name: 'MaxHeaderSizeExceededError', retryable: false },\n '40': { name: 'AuthErrorTokenExpired', retryable: false },\n '41': { name: 'AuthErrorTokenNotValidYet', retryable: false },\n '42': { name: 'AuthErrorTokenUsedBeforeIssuedAt', retryable: false },\n '43': { name: 'AuthErrorTokenSignatureInvalid', retryable: false },\n '44': { name: 'CustomCommandEndpointMissingError', retryable: false },\n '45': { name: 'CustomCommandEndpointCallError', retryable: true },\n '60': { name: 'CoolDownError', retryable: true },\n '69': { name: 'ErrWrongRegion', retryable: false },\n '70': { name: 'ErrQueryChannelPermissions', retryable: false },\n '71': { name: 'ErrTooManyConnections', retryable: true },\n '99': { name: 'AppSuspendedError', retryable: false },\n};\n\ntype APIError = Error & { code: number; isWSFailure?: boolean };\n\nexport function isAPIError(error: Error): error is APIError {\n return (error as APIError).code !== undefined;\n}\n\nexport function isErrorRetryable(error: APIError) {\n if (!error.code) return false;\n const err = APIErrorCodes[`${error.code}`];\n if (!err) return false;\n return err.retryable;\n}\n\nexport function isWSFailure(err: APIError): boolean {\n if (typeof err.isWSFailure === 'boolean') {\n return err.isWSFailure;\n }\n\n try {\n return JSON.parse(err.message).isWSFailure;\n } catch (_) {\n return false;\n }\n}\n\nexport function isErrorResponse(res: AxiosResponse<unknown>): res is AxiosResponse<APIErrorResponse> {\n return !res.status || res.status < 200 || 300 <= res.status;\n}\n","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { StableWSConnection } from './connection';\nimport { EVENT_MAP } from './events';\n\nexport type Role = 'owner' | 'moder' | 'member' | 'pending' | 'skipped' | string;\n\n/* Unknown Record */\nexport type UR = Record<string, unknown>;\nexport type DefaultGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: LiteralStringForUnion;\n eventType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type ExtendableGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: string;\n eventType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\n/**\n * Response Types\n */\n\nexport type APIResponse = {\n duration?: string;\n};\n\nexport type ChannelResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['channelType'] & {\n cid: string;\n id: string;\n type: string;\n created_at?: string;\n created_by?: UserResponse<ErmisChatGenerics> | null;\n deleted_at?: string;\n last_message_at?: string;\n member_count?: number;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n name?: string;\n own_capabilities?: string[];\n updated_at?: string;\n image?: string;\n description?: string;\n member_message_cooldown?: number;\n member_capabilities?: string[];\n is_pinned?: boolean;\n topics_enabled?: boolean;\n is_closed_topic?: boolean;\n };\n\nexport type QueryChannelsAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channels: Omit<ChannelAPIResponse<ErmisChatGenerics>, keyof APIResponse>[];\n};\n\nexport type QueryChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n ChannelAPIResponse<ErmisChatGenerics>;\n\nexport type ChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel: ChannelResponse<ErmisChatGenerics>;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n messages: MessageResponse<ErmisChatGenerics>[];\n pinned_messages: MessageResponse<ErmisChatGenerics>[];\n membership?: ChannelMembership<ErmisChatGenerics> | null;\n read?: ReadResponse<ErmisChatGenerics>[];\n topics?: QueryChannelAPIResponse<ErmisChatGenerics>[];\n watcher_count?: number;\n watchers?: UserResponse<ErmisChatGenerics>[];\n is_pinned?: boolean;\n};\n\nexport type ChannelMemberResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n banned?: boolean;\n blocked?: boolean;\n channel_role?: Role;\n created_at?: string;\n updated_at?: string;\n user?: UserResponse<ErmisChatGenerics>;\n user_id?: string;\n};\n\nexport type ConnectAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n Promise<void | ConnectionOpen<ErmisChatGenerics>>;\n\nexport type FormatMessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<{\n attachmentType: ErmisChatGenerics['attachmentType'];\n channelType: ErmisChatGenerics['channelType'];\n commandType: ErmisChatGenerics['commandType'];\n eventType: ErmisChatGenerics['eventType'];\n messageType: {};\n pollOptionType: ErmisChatGenerics['pollOptionType'];\n pollType: ErmisChatGenerics['pollType'];\n reactionType: ErmisChatGenerics['reactionType'];\n userType: ErmisChatGenerics['userType'];\n }>,\n 'created_at' | 'pinned_at' | 'updated_at' | 'status'\n> &\n ErmisChatGenerics['messageType'] & {\n created_at: Date;\n pinned_at: Date | null;\n status: string;\n updated_at: Date;\n };\n\nexport type MessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n MessageResponseBase<ErmisChatGenerics> & {\n quoted_message?: MessageResponseBase<ErmisChatGenerics>;\n };\n\nexport type MessageResponseBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n MessageBase<ErmisChatGenerics> & {\n type: MessageLabel;\n channel?: ChannelResponse<ErmisChatGenerics>;\n cid?: string;\n created_at?: string;\n deleted_at?: string;\n latest_reactions?: ReactionResponse<ErmisChatGenerics>[];\n mentioned_users?: string[];\n own_reactions?: ReactionResponse<ErmisChatGenerics>[] | null;\n pinned_at?: string | null;\n pinned_by?: UserResponse<ErmisChatGenerics> | null;\n reaction_counts?: { [key: string]: number } | null;\n reaction_scores?: { [key: string]: number } | null;\n reply_count?: number;\n status?: string;\n updated_at?: string;\n };\n\nexport type ReactionAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<ErmisChatGenerics>;\n reaction: ReactionResponse<ErmisChatGenerics>;\n};\n\nexport type ReactionResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n Reaction<ErmisChatGenerics> & {\n created_at: string;\n message_id: string;\n updated_at: string;\n };\n\nexport type ReadResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n last_read: string;\n user: UserResponse<ErmisChatGenerics>;\n last_read_message_id?: string;\n unread_messages?: number;\n last_send?: string;\n};\n\n// Thumb URL(thumb_url) is added considering video attachments as the backend will return the thumbnail in the response.\nexport type SendFileAPIResponse = APIResponse & { file: string; thumb_url?: string };\n\nexport type SendMessageAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<ErmisChatGenerics>;\n};\n\nexport type UpdateChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<ErmisChatGenerics>;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n message?: MessageResponse<ErmisChatGenerics>;\n};\n\nexport type UserResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['userType'] & {\n id: string;\n name?: string;\n avatar?: string;\n about_me?: string;\n project_id?: string;\n email?: string;\n phone?: string;\n };\nexport type Contact = {\n project_id: string;\n user_id: string;\n other_id: string;\n relation_status: string;\n created_at: string;\n updated_at: string;\n};\n\nexport type ContactResponse = APIResponse & {\n project_id_user_ids: {\n [key: string]: Contact[];\n };\n};\n\nexport type ContactResult<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n contact_users: UserResponse<ErmisChatGenerics>[];\n block_users: UserResponse<ErmisChatGenerics>[];\n};\n\nexport type ChannelQueryOptions = {\n messages?: {\n limit?: number;\n id_lt?: string;\n id_gt?: string;\n id_around?: string;\n };\n};\n\nexport type ChannelStateOptions = {\n offlineMode?: boolean;\n skipInitialization?: string[];\n};\n\nexport type ErmisChatOptions = AxiosRequestConfig & {\n /**\n * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.\n */\n allowServerSideConnect?: boolean;\n axiosRequestConfig?: AxiosRequestConfig;\n /**\n * Base url for User BE API (uss/v1). Defaults to baseURL + '/uss/v1' if not provided.\n */\n userBaseURL?: string;\n browser?: boolean;\n enableInsights?: boolean;\n /** experimental feature, please contact support if you want this feature enabled for you */\n logger?: Logger;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n warmUp?: boolean;\n // Set the instance of StableWSConnection on chat client. Its purely for testing purpose and should\n // not be used in production apps.\n wsConnection?: StableWSConnection;\n};\n\n/**\n * Event Types\n */\n\nexport type Event<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['eventType'] & {\n type: EventTypes;\n channel?: ChannelResponse<ErmisChatGenerics>;\n channel_id?: string;\n channel_type?: string;\n cid?: string;\n created_at?: string;\n hard_delete?: boolean;\n last_read_at?: string;\n last_read_message_id?: string;\n me?: UserResponse<ErmisChatGenerics>;\n member?: ChannelMemberResponse<ErmisChatGenerics>;\n message?: MessageResponse<ErmisChatGenerics>;\n online?: boolean;\n parent_id?: string;\n reaction?: ReactionResponse<ErmisChatGenerics>;\n received_at?: string | Date;\n unread_messages?: number;\n user?: UserResponse<ErmisChatGenerics>;\n user_id?: string;\n watcher_count?: number;\n};\n\nexport type EventHandler<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = (\n event: Event<ErmisChatGenerics>,\n) => void;\n\nexport type EventTypes = 'all' | keyof typeof EVENT_MAP;\n\n/**\n * Filter Types\n */\n\nexport type AscDesc = 1 | -1;\n\nexport type ChannelFilters = {\n project_id?: string;\n type: ('messaging' | 'team' | 'topic')[];\n limit?: number;\n offset?: number;\n roles?: string[];\n other_roles?: string[];\n banned?: boolean;\n blocked?: boolean;\n include_pinned_messages?: boolean;\n parent_cid?: string;\n parent_id?: string;\n include_parent?: boolean;\n};\n\nexport type ChannelSort = {\n field: string;\n direction: -1 | 1;\n}[];\n\nexport type Attachment<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['attachmentType'] & {\n // main fields for ermis.\n id?: string;\n thumb_url?: string;\n content_disposition?: string;\n content_length?: number;\n content_type?: string;\n updated_at?: string;\n created_at?: string;\n message_id?: string;\n file_name?: string;\n url?: string;\n cid?: string;\n user_id?: string;\n asset_url?: string;\n author_icon?: string;\n author_link?: string;\n author_name?: string;\n color?: string;\n duration?: number;\n fallback?: string;\n file_size?: number | string;\n footer?: string;\n footer_icon?: string;\n image_url?: string;\n mime_type?: string;\n og_scrape_url?: string;\n original_height?: number;\n original_width?: number;\n pretext?: string;\n text?: string;\n title?: string;\n title_link?: string;\n type?: string;\n waveform_data?: Array<number>;\n link_url?: string;\n };\n\nexport type ChannelData<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['channelType'] & {\n members?: string[];\n name?: string;\n is_pinned?: boolean;\n };\n\nexport type ChannelMembership<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n banned?: boolean;\n blocked?: boolean;\n channel_role?: Role;\n created_at?: string;\n updated_at?: string;\n user?: UserResponse<ErmisChatGenerics>;\n};\n\nexport type ConnectionOpen<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n cid?: string;\n created_at?: string;\n me?: UserResponse<ErmisChatGenerics>;\n type?: string;\n};\n\nexport type LiteralStringForUnion = string & {};\n\nexport type LogLevel = 'info' | 'error' | 'warn';\n\nexport type Logger = (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => void;\n\nexport type Message<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n MessageBase<ErmisChatGenerics>\n> & {\n id?: string;\n mentioned_all?: boolean;\n mentioned_users?: string[];\n cid?: string;\n forward_cid?: string;\n forward_message_id?: string;\n poll_type?: string; // single | multiple\n poll_choices?: string[];\n sticker_url?: string;\n};\n\nexport type EditMessage = {\n text: string;\n mentioned_all?: boolean;\n mentioned_users?: string[];\n};\n\nexport type ForwardMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n forward_cid: string;\n forward_message_id: string;\n id?: string;\n text?: string;\n attachments?: Attachment<ErmisChatGenerics>[];\n sticker_url?: string;\n};\n\nexport type PollMessage = {\n id?: string;\n text: string;\n poll_type: string; // single | multiple\n poll_choices: string[];\n};\n\nexport type MessageBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['messageType'] & {\n id: string;\n attachments?: Attachment[];\n html?: string;\n mml?: string;\n parent_id?: string;\n pinned?: boolean;\n pinned_at?: string | null;\n quoted_message_id?: string;\n text?: string;\n user?: UserResponse | null;\n user_id?: string;\n };\n\nexport type MessageLabel = 'regular' | 'system' | 'signal' | 'poll' | 'sticker' | 'error';\n\nexport type Reaction<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['reactionType'] & {\n type: string;\n message_id?: string;\n score?: number;\n user?: UserResponse | null;\n user_id?: string;\n };\n\nexport type MessageSetType = 'latest' | 'current' | 'new';\n\nexport type APIErrorResponse = {\n code: number;\n duration: string;\n message: string;\n more_info: string;\n StatusCode: number;\n};\n\nexport class ErrorFromResponse<T> extends Error {\n code?: number;\n response?: AxiosResponse<T>;\n status?: number;\n}\n\nexport type UsersResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n data: Array<UserResponse<ErmisChatGenerics>>;\n count: number;\n total: number;\n page: number;\n page_count: number;\n};\n\nexport type AttachmentResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n attachments: Attachment<ErmisChatGenerics>[];\n};\n\nexport type SignalData = {\n cid?: string;\n is_video?: boolean;\n action?: string;\n signal?: Object;\n metadata?: Object;\n};\n\nexport enum CallAction {\n CREATE_CALL = 'create-call',\n ACCEPT_CALL = 'accept-call',\n SIGNAL_CALL = 'signal-call',\n CONNECT_CALL = 'connect-call',\n HEALTH_CALL = 'health-call',\n END_CALL = 'end-call',\n REJECT_CALL = 'reject-call',\n MISS_CALL = 'miss-call',\n UPGRADE_CALL = 'upgrade-call',\n}\n\nexport enum CallStatus {\n RINGING = 'ringing',\n ENDED = 'ended',\n CONNECTED = 'connected',\n ERROR = 'error',\n}\n\nexport type CallEventType = 'incoming' | 'outgoing';\n\nexport type CallEventData = {\n type: CallEventType;\n callType: string;\n cid: string;\n callerInfo: UserCallInfo | undefined;\n receiverInfo: UserCallInfo | undefined;\n metadata?: Object;\n};\n\nexport type UserCallInfo = {\n id: string;\n name?: string;\n avatar?: string;\n};\n\nexport type Metadata = {\n address?: string;\n};\n\nexport type INodeCall = {\n connect: (address: string) => Promise<void>;\n acceptConnection: () => Promise<void>;\n sendControlFrame: (packet: Uint8Array) => Promise<void>;\n sendAudioFrame: (packet: Uint8Array) => Promise<void>; // audio\n sendFrame: (packet: Uint8Array) => Promise<void>; // video delta\n beginWithGop: (packet: Uint8Array) => Promise<void>; // video key\n asyncRecv: () => Promise<Uint8Array>;\n};\n\nexport type VideoConfig = {\n codec: string;\n codedWidth: number;\n codedHeight: number;\n frameRate?: number;\n orientation?: number;\n rotation?: number;\n description?: any;\n};\n\nexport type AudioConfig = {\n codec: string;\n sampleRate: number;\n numberOfChannels: number;\n description?: string;\n};\n\nexport type TransceiverState = {\n audio_enable: boolean;\n video_enable: boolean;\n};\n\nexport interface IMediaReceiverEvents {\n onConnected?: () => void;\n onTransceiverState?: (state: any) => void;\n onRequestConfig?: () => void;\n onRequestKeyFrame?: () => void;\n onEndCall?: () => void;\n}\n\nexport enum FRAME_TYPE {\n VIDEO_CONFIG = 0,\n AUDIO_CONFIG = 1,\n VIDEO_KEY = 2,\n VIDEO_DELTA = 3,\n AUDIO = 4,\n ORIENTATION = 5,\n CONNECTED = 6,\n TRANSCEIVER_STATE = 7,\n REQUEST_CONFIG = 8,\n REQUEST_KEY_FRAME = 9,\n END_CALL = 10,\n}\n","export const EVENT_MAP = {\n 'channel.created': true,\n 'channel.deleted': true,\n 'channel.truncate': true,\n 'channel.updated': true,\n 'channel.pinned': true,\n 'channel.unpinned': true,\n 'health.check': true,\n 'member.added': true,\n 'member.removed': true,\n 'member.updated': true,\n 'member.joined': true,\n 'member.promoted': true,\n 'member.demoted': true,\n 'member.banned': true,\n 'member.unbanned': true,\n 'member.blocked': true,\n 'member.unblocked': true,\n 'message.deleted': true,\n 'message.deleted_for_me': true,\n 'message.new': true,\n 'message.read': true,\n 'message.updated': true,\n 'message.pinned': true,\n 'message.unpinned': true,\n 'notification.channel_deleted': true,\n 'notification.invite_accepted': true,\n 'notification.invite_rejected': true,\n 'notification.invite_messaging_skipped': true,\n 'pollchoice.new': true,\n 'reaction.deleted': true,\n 'reaction.new': true,\n 'typing.start': true,\n 'typing.stop': true,\n 'user.watching.start': true,\n 'user.watching.stop': true,\n 'connection.changed': true,\n 'connection.recovered': true,\n 'capabilities.changed': true,\n 'channel.topic.disabled': true,\n 'channel.topic.enabled': true,\n 'channel.topic.created': true,\n 'channel.topic.closed': true,\n 'channel.topic.reopen': true,\n 'channel.topic.updated': true,\n};\n","let wasm;\n\nlet cachedUint8ArrayMemory0 = null;\n\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nfunction getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n}\n\nlet heap = new Array(128).fill(undefined);\n\nheap.push(undefined, null, true, false);\n\nlet heap_next = heap.length;\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nfunction getObject(idx) { return heap[idx]; }\n\nlet WASM_VECTOR_LEN = 0;\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n }\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nlet cachedDataViewMemory0 = null;\n\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction debugString(val) {\n // primitive types\n const type = typeof val;\n if (type == 'number' || type == 'boolean' || val == null) {\n return `${val}`;\n }\n if (type == 'string') {\n return `\"${val}\"`;\n }\n if (type == 'symbol') {\n const description = val.description;\n if (description == null) {\n return 'Symbol';\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == 'function') {\n const name = val.name;\n if (typeof name == 'string' && name.length > 0) {\n return `Function(${name})`;\n } else {\n return 'Function';\n }\n }\n // objects\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = '[';\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for(let i = 1; i < length; i++) {\n debug += ', ' + debugString(val[i]);\n }\n debug += ']';\n return debug;\n }\n // Test for built-in\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n // Failed to match the standard '[object ClassName]'\n return toString.call(val);\n }\n if (className == 'Object') {\n // we're a user defined class or Object\n // JSON.stringify avoids problems with cycles, and is generally much\n // easier than looping through ownProperties of `val`.\n try {\n return 'Object(' + JSON.stringify(val) + ')';\n } catch (_) {\n return 'Object';\n }\n }\n // errors\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\\n${val.stack}`;\n }\n // TODO we could test for more things here, like `Set`s and `Map`s.\n return className;\n}\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n wasm.__wbindgen_export3(addHeapObject(e));\n }\n}\n\nfunction dropObject(idx) {\n if (idx < 132) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nconst CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(state => state.dtor(state.a, state.b));\n\nfunction makeMutClosure(arg0, arg1, dtor, f) {\n const state = { a: arg0, b: arg1, cnt: 1, dtor };\n const real = (...args) => {\n\n // First up with a closure we increment the internal reference\n // count. This ensures that the Rust closure environment won't\n // be deallocated while we're invoking it.\n state.cnt++;\n const a = state.a;\n state.a = 0;\n try {\n return f(a, state.b, ...args);\n } finally {\n state.a = a;\n real._wbg_cb_unref();\n }\n };\n real._wbg_cb_unref = () => {\n if (--state.cnt === 0) {\n state.dtor(state.a, state.b);\n state.a = 0;\n CLOSURE_DTORS.unregister(state);\n }\n };\n CLOSURE_DTORS.register(real, state, state);\n return real;\n}\n\nfunction makeClosure(arg0, arg1, dtor, f) {\n const state = { a: arg0, b: arg1, cnt: 1, dtor };\n const real = (...args) => {\n\n // First up with a closure we increment the internal reference\n // count. This ensures that the Rust closure environment won't\n // be deallocated while we're invoking it.\n state.cnt++;\n try {\n return f(state.a, state.b, ...args);\n } finally {\n real._wbg_cb_unref();\n }\n };\n real._wbg_cb_unref = () => {\n if (--state.cnt === 0) {\n state.dtor(state.a, state.b);\n state.a = 0;\n CLOSURE_DTORS.unregister(state);\n }\n };\n CLOSURE_DTORS.register(real, state, state);\n return real;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1, 1) >>> 0;\n getUint8ArrayMemory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\nfunction __wasm_bindgen_func_elem_12858(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_12858(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_11688(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_11688(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_6230(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_6230(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_2287(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_2287(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_12912(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_12912(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_5748(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_5748(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_14376(arg0, arg1, arg2, arg3) {\n wasm.__wasm_bindgen_func_elem_14376(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));\n}\n\nconst __wbindgen_enum_BinaryType = [\"blob\", \"arraybuffer\"];\n\nconst __wbindgen_enum_ReadableStreamType = [\"bytes\"];\n\nconst __wbindgen_enum_RequestCache = [\"default\", \"no-store\", \"reload\", \"no-cache\", \"force-cache\", \"only-if-cached\"];\n\nconst __wbindgen_enum_RequestCredentials = [\"omit\", \"same-origin\", \"include\"];\n\nconst __wbindgen_enum_RequestMode = [\"same-origin\", \"no-cors\", \"cors\", \"navigate\"];\n\nconst ConnectionStatsFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_connectionstats_free(ptr >>> 0, 1));\n\nexport class ConnectionStats {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ConnectionStatsFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_connectionstats_free(ptr, 0);\n }\n /**\n * @returns {number | undefined}\n */\n get rtt_ms() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.__wbg_get_connectionstats_rtt_ms(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {number | null} [arg0]\n */\n set rtt_ms(arg0) {\n wasm.__wbg_set_connectionstats_rtt_ms(this.__wbg_ptr, !isLikeNone(arg0), isLikeNone(arg0) ? 0 : arg0);\n }\n /**\n * @returns {number | undefined}\n */\n get packet_loss() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.__wbg_get_connectionstats_packet_loss(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {number | null} [arg0]\n */\n set packet_loss(arg0) {\n wasm.__wbg_set_connectionstats_packet_loss(this.__wbg_ptr, !isLikeNone(arg0), isLikeNone(arg0) ? 0 : arg0);\n }\n /**\n * @param {string | null} [connection_type]\n * @param {number | null} [rtt_ms]\n * @param {number | null} [packet_loss]\n */\n constructor(connection_type, rtt_ms, packet_loss) {\n var ptr0 = isLikeNone(connection_type) ? 0 : passStringToWasm0(connection_type, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len0 = WASM_VECTOR_LEN;\n const ret = wasm.connectionstats_new(ptr0, len0, !isLikeNone(rtt_ms), isLikeNone(rtt_ms) ? 0 : rtt_ms, !isLikeNone(packet_loss), isLikeNone(packet_loss) ? 0 : packet_loss);\n this.__wbg_ptr = ret >>> 0;\n ConnectionStatsFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {string | undefined}\n */\n get connection_type() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.connectionstats_connection_type(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n let v1;\n if (r0 !== 0) {\n v1 = getStringFromWasm0(r0, r1).slice();\n wasm.__wbindgen_export4(r0, r1 * 1, 1);\n }\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {string | null} [value]\n */\n set connection_type(value) {\n var ptr0 = isLikeNone(value) ? 0 : passStringToWasm0(value, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len0 = WASM_VECTOR_LEN;\n wasm.connectionstats_set_connection_type(this.__wbg_ptr, ptr0, len0);\n }\n}\nif (Symbol.dispose) ConnectionStats.prototype[Symbol.dispose] = ConnectionStats.prototype.free;\n\nconst ErmisCallFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_ermiscall_free(ptr >>> 0, 1));\n\nexport class ErmisCall {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ErmisCallFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_ermiscall_free(ptr, 0);\n }\n constructor() {\n const ret = wasm.ermiscall_new();\n this.__wbg_ptr = ret >>> 0;\n ErmisCallFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @param {any} relay_urls\n * @param {Uint8Array | null} [secret_key]\n * @returns {Promise<void>}\n */\n spawn(relay_urls, secret_key) {\n var ptr0 = isLikeNone(secret_key) ? 0 : passArray8ToWasm0(secret_key, wasm.__wbindgen_export);\n var len0 = WASM_VECTOR_LEN;\n const ret = wasm.ermiscall_spawn(this.__wbg_ptr, addHeapObject(relay_urls), ptr0, len0);\n return takeObject(ret);\n }\n /**\n * @returns {Promise<string>}\n */\n getLocalEndpointAddr() {\n const ret = wasm.ermiscall_getLocalEndpointAddr(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {string} addr\n * @returns {Promise<void>}\n */\n connect(addr) {\n const ptr0 = passStringToWasm0(addr, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.ermiscall_connect(this.__wbg_ptr, ptr0, len0);\n return takeObject(ret);\n }\n /**\n * @returns {Promise<void>}\n */\n closeEndpoint() {\n const ret = wasm.ermiscall_closeEndpoint(this.__wbg_ptr);\n return takeObject(ret);\n }\n closeConnection() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_closeConnection(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Promise<void>}\n */\n acceptConnection() {\n const ret = wasm.ermiscall_acceptConnection(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {Uint8Array} data\n */\n sendControlFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendControlFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {Uint8Array} data\n */\n sendAudioFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendAudioFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {Uint8Array} data\n */\n sendFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n notifyNewGop() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_notifyNewGop(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Uint8Array}\n */\n recv() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_recv(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n if (r2) {\n throw takeObject(r1);\n }\n return takeObject(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Promise<Uint8Array>}\n */\n asyncRecv() {\n const ret = wasm.ermiscall_asyncRecv(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {Uint8Array} data\n */\n beginWithGop(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_beginWithGop(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {string | undefined}\n */\n connectionType() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_connectionType(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n let v1;\n if (r0 !== 0) {\n v1 = getStringFromWasm0(r0, r1).slice();\n wasm.__wbindgen_export4(r0, r1 * 1, 1);\n }\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number | undefined}\n */\n roundTripTime() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_roundTripTime(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number | undefined}\n */\n currentPacketLoss() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_currentPacketLoss(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n networkChange() {\n wasm.ermiscall_networkChange(this.__wbg_ptr);\n }\n /**\n * @returns {any}\n */\n getStats() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_getStats(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n if (r2) {\n throw takeObject(r1);\n }\n return takeObject(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n}\nif (Symbol.dispose) ErmisCall.prototype[Symbol.dispose] = ErmisCall.prototype.free;\n\nconst IntoUnderlyingByteSourceFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingbytesource_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingByteSource {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingByteSourceFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingbytesource_free(ptr, 0);\n }\n /**\n * @returns {ReadableStreamType}\n */\n get type() {\n const ret = wasm.intounderlyingbytesource_type(this.__wbg_ptr);\n return __wbindgen_enum_ReadableStreamType[ret];\n }\n /**\n * @returns {number}\n */\n get autoAllocateChunkSize() {\n const ret = wasm.intounderlyingbytesource_autoAllocateChunkSize(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * @param {ReadableByteStreamController} controller\n */\n start(controller) {\n wasm.intounderlyingbytesource_start(this.__wbg_ptr, addHeapObject(controller));\n }\n /**\n * @param {ReadableByteStreamController} controller\n * @returns {Promise<any>}\n */\n pull(controller) {\n const ret = wasm.intounderlyingbytesource_pull(this.__wbg_ptr, addHeapObject(controller));\n return takeObject(ret);\n }\n cancel() {\n const ptr = this.__destroy_into_raw();\n wasm.intounderlyingbytesource_cancel(ptr);\n }\n}\nif (Symbol.dispose) IntoUnderlyingByteSource.prototype[Symbol.dispose] = IntoUnderlyingByteSource.prototype.free;\n\nconst IntoUnderlyingSinkFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingsink_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingSink {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingSinkFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingsink_free(ptr, 0);\n }\n /**\n * @param {any} chunk\n * @returns {Promise<any>}\n */\n write(chunk) {\n const ret = wasm.intounderlyingsink_write(this.__wbg_ptr, addHeapObject(chunk));\n return takeObject(ret);\n }\n /**\n * @returns {Promise<any>}\n */\n close() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.intounderlyingsink_close(ptr);\n return takeObject(ret);\n }\n /**\n * @param {any} reason\n * @returns {Promise<any>}\n */\n abort(reason) {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.intounderlyingsink_abort(ptr, addHeapObject(reason));\n return takeObject(ret);\n }\n}\nif (Symbol.dispose) IntoUnderlyingSink.prototype[Symbol.dispose] = IntoUnderlyingSink.prototype.free;\n\nconst IntoUnderlyingSourceFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingsource_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingSource {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingSourceFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingsource_free(ptr, 0);\n }\n /**\n * @param {ReadableStreamDefaultController} controller\n * @returns {Promise<any>}\n */\n pull(controller) {\n const ret = wasm.intounderlyingsource_pull(this.__wbg_ptr, addHeapObject(controller));\n return takeObject(ret);\n }\n cancel() {\n const ptr = this.__destroy_into_raw();\n wasm.intounderlyingsource_cancel(ptr);\n }\n}\nif (Symbol.dispose) IntoUnderlyingSource.prototype[Symbol.dispose] = IntoUnderlyingSource.prototype.free;\n\nconst EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n\n } catch (e) {\n const validResponse = module.ok && EXPECTED_RESPONSE_TYPES.has(module.type);\n\n if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else {\n throw e;\n }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n\n } else {\n return instance;\n }\n }\n}\n\nfunction __wbg_get_imports() {\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbg_Error_e83987f665cf5504 = function(arg0, arg1) {\n const ret = Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_String_8f0eb39a4a4c2f66 = function(arg0, arg1) {\n const ret = String(getObject(arg1));\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_boolean_get_6d5a1ee65bab5f68 = function(arg0) {\n const v = getObject(arg0);\n const ret = typeof(v) === 'boolean' ? v : undefined;\n return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;\n };\n imports.wbg.__wbg___wbindgen_debug_string_df47ffb5e35e6763 = function(arg0, arg1) {\n const ret = debugString(getObject(arg1));\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function(arg0) {\n const ret = typeof(getObject(arg0)) === 'function';\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_object_c818261d21f283a4 = function(arg0) {\n const val = getObject(arg0);\n const ret = typeof(val) === 'object' && val !== null;\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_string_fbb76cb2940daafd = function(arg0) {\n const ret = typeof(getObject(arg0)) === 'string';\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function(arg0) {\n const ret = getObject(arg0) === undefined;\n return ret;\n };\n imports.wbg.__wbg___wbindgen_jsval_loose_eq_b664b38a2f582147 = function(arg0, arg1) {\n const ret = getObject(arg0) == getObject(arg1);\n return ret;\n };\n imports.wbg.__wbg___wbindgen_number_get_a20bf9b85341449d = function(arg0, arg1) {\n const obj = getObject(arg1);\n const ret = typeof(obj) === 'number' ? obj : undefined;\n getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);\n };\n imports.wbg.__wbg___wbindgen_string_get_e4f06c90489ad01b = function(arg0, arg1) {\n const obj = getObject(arg1);\n const ret = typeof(obj) === 'string' ? obj : undefined;\n var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_throw_b855445ff6a94295 = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n imports.wbg.__wbg__wbg_cb_unref_2454a539ea5790d9 = function(arg0) {\n getObject(arg0)._wbg_cb_unref();\n };\n imports.wbg.__wbg_abort_28ad55c5825b004d = function(arg0, arg1) {\n getObject(arg0).abort(getObject(arg1));\n };\n imports.wbg.__wbg_abort_e7eb059f72f9ed0c = function(arg0) {\n getObject(arg0).abort();\n };\n imports.wbg.__wbg_addEventListener_40dc0fc428fc49e1 = function() { return handleError(function (arg0, arg1, arg2, arg3) {\n getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));\n }, arguments) };\n imports.wbg.__wbg_append_b577eb3a177bc0fa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {\n getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));\n }, arguments) };\n imports.wbg.__wbg_body_587542b2fd8e06c0 = function(arg0) {\n const ret = getObject(arg0).body;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_buffer_ccc4520b36d3ccf4 = function(arg0) {\n const ret = getObject(arg0).buffer;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_byobRequest_2344e6975f27456e = function(arg0) {\n const ret = getObject(arg0).byobRequest;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_byteLength_bcd42e4025299788 = function(arg0) {\n const ret = getObject(arg0).byteLength;\n return ret;\n };\n imports.wbg.__wbg_byteOffset_ca3a6cf7944b364b = function(arg0) {\n const ret = getObject(arg0).byteOffset;\n return ret;\n };\n imports.wbg.__wbg_call_525440f72fbfc0ea = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_call_e762c39fa8ea36bf = function() { return handleError(function (arg0, arg1) {\n const ret = getObject(arg0).call(getObject(arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_cancel_48ab6f9dc366e369 = function(arg0) {\n const ret = getObject(arg0).cancel();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_catch_943836faa5d29bfb = function(arg0, arg1) {\n const ret = getObject(arg0).catch(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_clearTimeout_15dfc3d1dcb635c6 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).clearTimeout(takeObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_clearTimeout_7a42b49784aea641 = function(arg0) {\n const ret = clearTimeout(takeObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_close_5a6caed3231b68cd = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_close_6956df845478561a = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_close_885e277edf06b3fa = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_code_20d453b11b200026 = function(arg0) {\n const ret = getObject(arg0).code;\n return ret;\n };\n imports.wbg.__wbg_code_218f5fdf8c7fcabd = function(arg0) {\n const ret = getObject(arg0).code;\n return ret;\n };\n imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {\n const ret = getObject(arg0).crypto;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_data_ee4306d069f24f2d = function(arg0) {\n const ret = getObject(arg0).data;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_done_2042aa2670fb1db1 = function(arg0) {\n const ret = getObject(arg0).done;\n return ret;\n };\n imports.wbg.__wbg_enqueue_7b18a650aec77898 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).enqueue(getObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_fetch_74a3e84ebd2c9a0e = function(arg0) {\n const ret = fetch(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_fetch_f8ba0e29a9d6de0d = function(arg0, arg1) {\n const ret = getObject(arg0).fetch(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_getRandomValues_1c61fac11405ffdc = function() { return handleError(function (arg0, arg1) {\n globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));\n }, arguments) };\n imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).getRandomValues(getObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_getReader_48e00749fe3f6089 = function() { return handleError(function (arg0) {\n const ret = getObject(arg0).getReader();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_getTime_14776bfb48a1bff9 = function(arg0) {\n const ret = getObject(arg0).getTime();\n return ret;\n };\n imports.wbg.__wbg_get_7bed016f185add81 = function(arg0, arg1) {\n const ret = getObject(arg0)[arg1 >>> 0];\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_get_done_a0463af43a1fc764 = function(arg0) {\n const ret = getObject(arg0).done;\n return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;\n };\n imports.wbg.__wbg_get_efcb449f58ec27c2 = function() { return handleError(function (arg0, arg1) {\n const ret = Reflect.get(getObject(arg0), getObject(arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_get_value_5ce96c9f81ce7398 = function(arg0) {\n const ret = getObject(arg0).value;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_has_787fafc980c3ccdb = function() { return handleError(function (arg0, arg1) {\n const ret = Reflect.has(getObject(arg0), getObject(arg1));\n return ret;\n }, arguments) };\n imports.wbg.__wbg_headers_b87d7eaba61c3278 = function(arg0) {\n const ret = getObject(arg0).headers;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_instanceof_ArrayBuffer_70beb1189ca63b38 = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof ArrayBuffer;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Blob_23b3322f66e5a83b = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Blob;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Response_f4f3e87e07f3135c = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Response;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Uint8Array_20c8e73002f7af98 = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Uint8Array;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_isArray_96e0af9891d0945d = function(arg0) {\n const ret = Array.isArray(getObject(arg0));\n return ret;\n };\n imports.wbg.__wbg_iterator_e5822695327a3c39 = function() {\n const ret = Symbol.iterator;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_length_69bca3cb64fc8748 = function(arg0) {\n const ret = getObject(arg0).length;\n return ret;\n };\n imports.wbg.__wbg_length_cdd215e10d9dd507 = function(arg0) {\n const ret = getObject(arg0).length;\n return ret;\n };\n imports.wbg.__wbg_log_ee0138cca4957740 = function(arg0, arg1) {\n console.log(getStringFromWasm0(arg0, arg1));\n };\n imports.wbg.__wbg_message_bd42dbe3f2f3ed8e = function(arg0, arg1) {\n const ret = getObject(arg1).message;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {\n const ret = getObject(arg0).msCrypto;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_0_f9740686d739025c = function() {\n const ret = new Date();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_1acc0b6eea89d040 = function() {\n const ret = new Object();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_2531773dac38ebb3 = function() { return handleError(function () {\n const ret = new AbortController();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_3c3d849046688a66 = function(arg0, arg1) {\n try {\n var state0 = {a: arg0, b: arg1};\n var cb0 = (arg0, arg1) => {\n const a = state0.a;\n state0.a = 0;\n try {\n return __wasm_bindgen_func_elem_14376(a, state0.b, arg0, arg1);\n } finally {\n state0.a = a;\n }\n };\n const ret = new Promise(cb0);\n return addHeapObject(ret);\n } finally {\n state0.a = state0.b = 0;\n }\n };\n imports.wbg.__wbg_new_5a79be3ab53b8aa5 = function(arg0) {\n const ret = new Uint8Array(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_881c4fe631eee9ad = function() { return handleError(function (arg0, arg1) {\n const ret = new WebSocket(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_9edf9838a2def39c = function() { return handleError(function () {\n const ret = new Headers();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_a7442b4b19c1a356 = function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_e17d9f43105b08be = function() {\n const ret = new Array();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_from_slice_92f4d78ca282a2d2 = function(arg0, arg1) {\n const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_no_args_ee98eee5275000a4 = function(arg0, arg1) {\n const ret = new Function(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_byte_offset_and_length_46e3e6a5e9f9e89b = function(arg0, arg1, arg2) {\n const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_length_01aa0dc35aa13543 = function(arg0) {\n const ret = new Uint8Array(arg0 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_str_and_init_0ae7728b6ec367b1 = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_with_str_sequence_57a88eb77393f23f = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = new WebSocket(getStringFromWasm0(arg0, arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_next_020810e0ae8ebcb0 = function() { return handleError(function (arg0) {\n const ret = getObject(arg0).next();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_next_2c826fe5dfec6b6a = function(arg0) {\n const ret = getObject(arg0).next;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {\n const ret = getObject(arg0).node;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_now_2c95c9de01293173 = function(arg0) {\n const ret = getObject(arg0).now();\n return ret;\n };\n imports.wbg.__wbg_now_793306c526e2e3b6 = function() {\n const ret = Date.now();\n return ret;\n };\n imports.wbg.__wbg_performance_7a3ffd0b17f663ad = function(arg0) {\n const ret = getObject(arg0).performance;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {\n const ret = getObject(arg0).process;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_prototypesetcall_2a6620b6922694b2 = function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));\n };\n imports.wbg.__wbg_push_df81a39d04db858c = function(arg0, arg1) {\n const ret = getObject(arg0).push(getObject(arg1));\n return ret;\n };\n imports.wbg.__wbg_queueMicrotask_34d692c25c47d05b = function(arg0) {\n const ret = getObject(arg0).queueMicrotask;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_queueMicrotask_9d76cacb20c84d58 = function(arg0) {\n queueMicrotask(getObject(arg0));\n };\n imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).randomFillSync(takeObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_read_48f1593df542f968 = function(arg0) {\n const ret = getObject(arg0).read();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_readyState_97984f126080aeda = function(arg0) {\n const ret = getObject(arg0).readyState;\n return ret;\n };\n imports.wbg.__wbg_reason_1cced37e3a93763e = function(arg0, arg1) {\n const ret = getObject(arg1).reason;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_releaseLock_5d0b5a68887b891d = function(arg0) {\n getObject(arg0).releaseLock();\n };\n imports.wbg.__wbg_removeEventListener_924d9db66a4f775d = function() { return handleError(function (arg0, arg1, arg2, arg3) {\n getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));\n }, arguments) };\n imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {\n const ret = module.require;\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_resolve_caf97c30b83f7053 = function(arg0) {\n const ret = Promise.resolve(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_respond_0f4dbf5386f5c73e = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).respond(arg1 >>> 0);\n }, arguments) };\n imports.wbg.__wbg_send_171576d2f7487517 = function() { return handleError(function (arg0, arg1, arg2) {\n getObject(arg0).send(getStringFromWasm0(arg1, arg2));\n }, arguments) };\n imports.wbg.__wbg_send_3d2cf376613294f0 = function() { return handleError(function (arg0, arg1, arg2) {\n getObject(arg0).send(getArrayU8FromWasm0(arg1, arg2));\n }, arguments) };\n imports.wbg.__wbg_setTimeout_4eb823e8b72fbe79 = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = getObject(arg0).setTimeout(takeObject(arg1), arg2);\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_setTimeout_7bb3429662ab1e70 = function(arg0, arg1) {\n const ret = setTimeout(getObject(arg0), arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {\n getObject(arg0)[takeObject(arg1)] = takeObject(arg2);\n };\n imports.wbg.__wbg_set_9e6516df7b7d0f19 = function(arg0, arg1, arg2) {\n getObject(arg0).set(getArrayU8FromWasm0(arg1, arg2));\n };\n imports.wbg.__wbg_set_binaryType_9d839cea8fcdc5c3 = function(arg0, arg1) {\n getObject(arg0).binaryType = __wbindgen_enum_BinaryType[arg1];\n };\n imports.wbg.__wbg_set_body_3c365989753d61f4 = function(arg0, arg1) {\n getObject(arg0).body = getObject(arg1);\n };\n imports.wbg.__wbg_set_cache_2f9deb19b92b81e3 = function(arg0, arg1) {\n getObject(arg0).cache = __wbindgen_enum_RequestCache[arg1];\n };\n imports.wbg.__wbg_set_credentials_f621cd2d85c0c228 = function(arg0, arg1) {\n getObject(arg0).credentials = __wbindgen_enum_RequestCredentials[arg1];\n };\n imports.wbg.__wbg_set_handle_event_b2de49ad6c81e3c8 = function(arg0, arg1) {\n getObject(arg0).handleEvent = getObject(arg1);\n };\n imports.wbg.__wbg_set_headers_6926da238cd32ee4 = function(arg0, arg1) {\n getObject(arg0).headers = getObject(arg1);\n };\n imports.wbg.__wbg_set_method_c02d8cbbe204ac2d = function(arg0, arg1, arg2) {\n getObject(arg0).method = getStringFromWasm0(arg1, arg2);\n };\n imports.wbg.__wbg_set_mode_52ef73cfa79639cb = function(arg0, arg1) {\n getObject(arg0).mode = __wbindgen_enum_RequestMode[arg1];\n };\n imports.wbg.__wbg_set_onclose_c09e4f7422de8dae = function(arg0, arg1) {\n getObject(arg0).onclose = getObject(arg1);\n };\n imports.wbg.__wbg_set_onerror_337a3a2db9517378 = function(arg0, arg1) {\n getObject(arg0).onerror = getObject(arg1);\n };\n imports.wbg.__wbg_set_onmessage_8661558551a89792 = function(arg0, arg1) {\n getObject(arg0).onmessage = getObject(arg1);\n };\n imports.wbg.__wbg_set_onopen_efccb9305427b907 = function(arg0, arg1) {\n getObject(arg0).onopen = getObject(arg1);\n };\n imports.wbg.__wbg_set_signal_dda2cf7ccb6bee0f = function(arg0, arg1) {\n getObject(arg0).signal = getObject(arg1);\n };\n imports.wbg.__wbg_signal_4db5aa055bf9eb9a = function(arg0) {\n const ret = getObject(arg0).signal;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function() {\n const ret = typeof global === 'undefined' ? null : global;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function() {\n const ret = typeof globalThis === 'undefined' ? null : globalThis;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function() {\n const ret = typeof self === 'undefined' ? null : self;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function() {\n const ret = typeof window === 'undefined' ? null : window;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_status_de7eed5a7a5bfd5d = function(arg0) {\n const ret = getObject(arg0).status;\n return ret;\n };\n imports.wbg.__wbg_stringify_b5fb28f6465d9c3e = function() { return handleError(function (arg0) {\n const ret = JSON.stringify(getObject(arg0));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_subarray_480600f3d6a9f26c = function(arg0, arg1, arg2) {\n const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_then_4f46f6544e6b4a28 = function(arg0, arg1) {\n const ret = getObject(arg0).then(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_then_70d05cf780a18d77 = function(arg0, arg1, arg2) {\n const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_url_9bd0af1cd8643de7 = function(arg0, arg1) {\n const ret = getObject(arg1).url;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_url_b36d2a5008eb056f = function(arg0, arg1) {\n const ret = getObject(arg1).url;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_value_692627309814bb8c = function(arg0) {\n const ret = getObject(arg0).value;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {\n const ret = getObject(arg0).versions;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_view_f6c15ac9fed63bbd = function(arg0) {\n const ret = getObject(arg0).view;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_wasClean_3d7c0cf05bd0a123 = function(arg0) {\n const ret = getObject(arg0).wasClean;\n return ret;\n };\n imports.wbg.__wbindgen_cast_0b4723bb5ff7475b = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2388, function: Function { arguments: [NamedExternref(\"MessageEvent\")], shim_idx: 2389, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_11664, __wasm_bindgen_func_elem_11688);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {\n // Cast intrinsic for `Ref(String) -> Externref`.\n const ret = getStringFromWasm0(arg0, arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_253c73f2760a05aa = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 1351, function: Function { arguments: [], shim_idx: 1352, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_6219, __wasm_bindgen_func_elem_6230);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_343835dd8f264af2 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 1255, function: Function { arguments: [], shim_idx: 1256, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.\n const ret = makeClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_5735, __wasm_bindgen_func_elem_5748);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_7bacc9fa7d2c65f4 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2465, function: Function { arguments: [], shim_idx: 2466, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_12841, __wasm_bindgen_func_elem_12858);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_88fdcfb6b716b7f8 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2473, function: Function { arguments: [Externref], shim_idx: 2474, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_12896, __wasm_bindgen_func_elem_12912);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_c43a1cf1b94f2e7c = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 544, function: Function { arguments: [NamedExternref(\"CloseEvent\")], shim_idx: 545, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_2083, __wasm_bindgen_func_elem_2287);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref(\"Uint8Array\")`.\n const ret = getArrayU8FromWasm0(arg0, arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_d6cd19b81560fd6e = function(arg0) {\n // Cast intrinsic for `F64 -> Externref`.\n const ret = arg0;\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_object_clone_ref = function(arg0) {\n const ret = getObject(arg0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_object_drop_ref = function(arg0) {\n takeObject(arg0);\n };\n\n return imports;\n}\n\nfunction __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n __wbg_init.__wbindgen_wasm_module = module;\n cachedDataViewMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n\n\n\n return wasm;\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module !== 'undefined') {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n console.warn('using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n\n const instance = new WebAssembly.Instance(module, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module_or_path !== 'undefined') {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n console.warn('using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n if (typeof module_or_path === 'undefined') {\n module_or_path = new URL('ermis_call_node_wasm_bg.wasm', import.meta.url);\n }\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync };\nexport default __wbg_init;\n","import { base64Encode, createPacketWithHeader } from './utils';\nimport { AudioConfig, INodeCall, TransceiverState, VideoConfig } from './types';\n\nexport class MediaStreamSender {\n private videoEncoder: VideoEncoder | null = null;\n private audioEncoder: AudioEncoder | null = null;\n private videoReader: ReadableStreamDefaultReader<VideoFrame> | null = null;\n\n private localStream: MediaStream | null = null;\n\n private videoConfig: VideoConfig | null = null;\n private audioConfig: AudioConfig | null = null;\n\n private videoConfigSent: boolean = false;\n private audioConfigSent: boolean = false;\n\n private hasVideo: boolean = false;\n private hasAudio: boolean = false;\n\n private forceKeyFrame: boolean = false;\n\n private nodeCall: INodeCall;\n\n constructor(nodeCall: INodeCall) {\n this.nodeCall = nodeCall;\n }\n\n /**\n * Bắt đầu xử lý MediaStream\n */\n public async connect(address: string): Promise<void> {\n try {\n await this.nodeCall.connect(address);\n await this.sendConnected();\n await this.sendConfigs();\n } catch (error) {\n console.error('Error starting MediaStreamSender:', error);\n }\n }\n\n public async sendConfigs(): Promise<void> {\n try {\n await this.sendTransceiverState(this.hasAudio, this.hasVideo);\n await this.sendAudioConfig();\n\n const videoTrack = this.localStream?.getVideoTracks()[0];\n if (videoTrack) {\n await this.sendVideoConfig();\n }\n } catch (error) {\n console.error('Error sending configs:', error);\n }\n }\n\n /**\n * Dừng và reset encoders\n */\n public stop = (): void => {\n if (this.videoReader) {\n try {\n this.videoReader.cancel('Stream stopped').catch(() => {});\n } catch (e) {}\n this.videoReader = null;\n }\n\n if (this.videoEncoder) {\n try {\n if (this.videoEncoder.state !== 'closed') {\n this.videoEncoder.reset(); // Xả frame\n this.videoEncoder.close();\n }\n } catch (e) {}\n this.videoEncoder = null;\n }\n\n // Reset and close audio encoder\n if (this.audioEncoder) {\n try {\n if (this.audioEncoder.state !== 'closed') {\n this.audioEncoder.reset();\n this.audioEncoder.close();\n }\n } catch (e) {}\n this.audioEncoder = null;\n }\n\n // Reset configs and flags\n this.videoConfig = null;\n this.audioConfig = null;\n\n this.videoConfigSent = false;\n this.audioConfigSent = false;\n this.hasVideo = false;\n this.hasAudio = false;\n\n if (this.localStream) {\n this.localStream.getTracks().forEach((track) => track.stop());\n this.localStream = null;\n }\n };\n\n public initAudioEncoder = (audioTrack: MediaStreamTrack): void => {\n this.localStream = new MediaStream([audioTrack]);\n this.audioConfigSent = false;\n this.hasAudio = !!audioTrack;\n\n const audioEncoder = new AudioEncoder({\n output: (chunk, metadata) => {\n if (metadata?.decoderConfig && !this.audioConfigSent) {\n let description: string | undefined = undefined;\n if (metadata.decoderConfig.description) {\n description = base64Encode(metadata.decoderConfig.description as ArrayBuffer);\n }\n\n this.audioConfig = {\n codec: metadata.decoderConfig.codec ?? 'opus',\n sampleRate: metadata.decoderConfig.sampleRate ?? 48000,\n numberOfChannels: metadata.decoderConfig.numberOfChannels ?? 1,\n ...(description && { description }),\n };\n }\n\n if (chunk && this.isReadyToSendData('audio')) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(data);\n // const timestamp = Math.floor(chunk.timestamp / 1000);\n const timestamp = chunk.timestamp;\n\n const packet = createPacketWithHeader(data, timestamp, 'audio', null);\n this.sendPacketOrQueue(packet, 'audio', null);\n }\n },\n error: (e) => console.error('AudioEncoder error:', e),\n });\n\n audioEncoder.configure({\n codec: 'mp4a.40.2',\n sampleRate: 48000,\n numberOfChannels: 1,\n bitrate: 128000,\n });\n\n this.audioEncoder = audioEncoder;\n this.processAudioFrames(audioTrack);\n };\n\n public initVideoEncoder(videoTrack: MediaStreamTrack): void {\n if (this.localStream) {\n this.localStream.addTrack(videoTrack);\n }\n\n this.videoConfigSent = false;\n this.hasVideo = !!videoTrack;\n\n const settings = videoTrack.getSettings();\n const videoWidth = settings.width || 1280;\n const videoHeight = settings.height || 720;\n\n const videoEncoder = new VideoEncoder({\n output: async (chunk, metadata) => {\n if (metadata?.decoderConfig && !this.videoConfigSent) {\n let description: string | undefined = undefined;\n if (metadata.decoderConfig.description) {\n description = base64Encode(metadata.decoderConfig.description as ArrayBuffer);\n }\n\n this.videoConfig = {\n codec: metadata.decoderConfig.codec ?? 'hev1.1.6.L93.B0',\n codedWidth: metadata.decoderConfig.codedWidth ?? videoWidth,\n codedHeight: metadata.decoderConfig.codedHeight ?? videoHeight,\n frameRate: 30.0,\n orientation: 0,\n ...(description && { description }),\n };\n\n await this.sendVideoConfig();\n }\n\n if (chunk && this.isReadyToSendData('video')) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(data);\n const frameType = chunk.type === 'key' ? 'video-key' : 'video-delta';\n // const timestamp = Math.floor(chunk.timestamp / 1000);\n const timestamp = chunk.timestamp;\n\n const packet = createPacketWithHeader(data, timestamp, frameType, null);\n this.sendPacketOrQueue(packet, 'video', frameType);\n }\n },\n error: (e) => console.error('VideoEncoder error:', e),\n });\n\n videoEncoder.configure({\n codec: 'hev1.1.6.L93.B0',\n width: videoWidth,\n height: videoHeight,\n bitrate: 500_000,\n framerate: 30,\n latencyMode: 'realtime',\n hardwareAcceleration: 'prefer-hardware',\n });\n\n this.videoEncoder = videoEncoder;\n this.processVideoFrames(videoTrack);\n }\n\n public initEncoders = (stream: MediaStream): void => {\n const videoTrack = stream.getVideoTracks()[0];\n const audioTrack = stream.getAudioTracks()[0];\n\n if (audioTrack) {\n this.initAudioEncoder(audioTrack);\n }\n\n if (videoTrack) {\n this.initVideoEncoder(videoTrack);\n }\n };\n\n public sendTransceiverState = async (audioEnable: boolean, videoEnable: boolean) => {\n const state: TransceiverState = {\n audio_enable: !!audioEnable,\n video_enable: !!videoEnable,\n };\n const configPacket = createPacketWithHeader(null, null, 'transciverState', state);\n await this.nodeCall.sendControlFrame(configPacket);\n };\n\n public async replaceVideoTrack(track: MediaStreamTrack): Promise<void> {\n // 1. Dừng reader của track cũ (quan trọng)\n if (this.videoReader) {\n try {\n // Việc gọi cancel sẽ làm Promise tại dòng await read() bên dưới throw lỗi hoặc trả về done\n await this.videoReader.cancel('Replacing track');\n } catch (e) {\n // Bỏ qua lỗi khi cancel\n }\n this.videoReader = null;\n }\n\n if (track) {\n this.processVideoFrames(track);\n }\n }\n\n public async replaceAudioTrack(track: MediaStreamTrack): Promise<void> {\n if (track) {\n this.processAudioFrames(track);\n }\n }\n\n /**\n * Yêu cầu gửi keyframe ngay lập tức (được gọi khi nhận REQUEST_KEY_FRAME từ receiver)\n */\n public requestKeyFrame = (): void => {\n console.log('📥 KeyFrame requested');\n this.forceKeyFrame = true;\n };\n\n // ================= PRIVATE METHODS =================\n\n private processVideoFrames = async (videoTrack: MediaStreamTrack) => {\n try {\n // @ts-ignore: MediaStreamTrackProcessor is explicitly defined in WebCodecs types\n const videoProcessor = new MediaStreamTrackProcessor({ track: videoTrack });\n this.videoReader = videoProcessor.readable.getReader();\n\n let frameCounter = 0;\n while (true) {\n if (!this.videoReader) break;\n\n const { done, value: frame } = await this.videoReader.read();\n if (done) break;\n\n if (!this.videoEncoder) {\n frame?.close();\n break;\n }\n\n if (frame) {\n frameCounter += 1;\n const keyFrame = frameCounter % 60 === 0 || this.forceKeyFrame;\n if (this.forceKeyFrame) {\n console.log('📤 Sending forced KeyFrame');\n this.forceKeyFrame = false;\n }\n try {\n this.videoEncoder.encode(frame, { keyFrame });\n } catch (err) {\n console.error('Encode error:', err);\n } finally {\n frame.close();\n }\n }\n }\n } catch (error: any) {\n console.error(`Error processing video frames: ${error.message}`);\n } finally {\n if (this.videoReader) {\n try {\n this.videoReader.releaseLock();\n } catch (e) {}\n // this.videoReader = null;\n }\n }\n };\n\n private processAudioFrames = async (audioTrack: MediaStreamTrack) => {\n // @ts-ignore\n const audioProcessor = new MediaStreamTrackProcessor({ track: audioTrack });\n const audioReader = audioProcessor.readable.getReader();\n\n try {\n while (true) {\n const { done, value: frame } = await audioReader.read();\n if (done) break;\n\n if (!this.audioEncoder) {\n frame?.close();\n break;\n }\n\n if (frame) {\n try {\n this.audioEncoder.encode(frame);\n } catch (err) {\n console.error('Audio Encoding error:', err);\n } finally {\n frame.close();\n }\n }\n }\n } catch (error: any) {\n console.error(`Error processing audio frames: ${error.message}`);\n }\n };\n\n private isReadyToSendData = (type: 'video' | 'audio'): boolean => {\n const videoReady = !this.hasVideo || this.videoConfigSent;\n const audioReady = !this.hasAudio || this.audioConfigSent;\n const allConfigsSent = videoReady && audioReady;\n\n if (type === 'video') {\n return allConfigsSent && this.videoConfigSent;\n } else if (type === 'audio') {\n return allConfigsSent && this.audioConfigSent;\n }\n\n return false;\n };\n\n private sendVideoConfig = async () => {\n if (this.videoConfig && !this.videoConfigSent) {\n try {\n const configPacket = createPacketWithHeader(null, null, 'videoConfig', this.videoConfig);\n await this.nodeCall.sendControlFrame(configPacket);\n this.videoConfigSent = true;\n } catch (error) {\n console.error('Error sending video config:', error);\n }\n }\n };\n\n private sendAudioConfig = async () => {\n if (this.audioConfig && !this.audioConfigSent) {\n try {\n const configPacket = createPacketWithHeader(null, null, 'audioConfig', this.audioConfig);\n await this.nodeCall.sendControlFrame(configPacket);\n this.audioConfigSent = true;\n } catch (error) {\n console.error('Error sending audio config:', error);\n }\n }\n };\n\n public sendConnected = async () => {\n const configPacket = createPacketWithHeader(null, null, 'connected', null);\n await this.nodeCall.sendControlFrame(configPacket);\n };\n\n private sendPacketOrQueue = async (\n packet: Uint8Array,\n type: 'video' | 'audio',\n frameType: 'video-key' | 'video-delta' | null,\n ) => {\n if (!this.isReadyToSendData(type)) {\n return;\n }\n\n if (type === 'audio') {\n await this.nodeCall.sendAudioFrame(packet);\n } else if (type === 'video') {\n if (frameType === 'video-key') {\n await this.nodeCall.beginWithGop(packet);\n } else if (frameType === 'video-delta') {\n await this.nodeCall.sendFrame(packet);\n }\n }\n };\n}\n","// 1. Định nghĩa các hằng số NAL Unit\nexport const NALUnitType = {\n VPS_NUT: 32,\n SPS_NUT: 33,\n PPS_NUT: 34,\n PREFIX_SEI_NUT: 39,\n SUFFIX_SEI_NUT: 40,\n\n fromValue(value: number): string | number {\n const types: Record<number, string> = {\n 32: 'VPS_NUT',\n 33: 'SPS_NUT',\n 34: 'PPS_NUT',\n 39: 'PREFIX_SEI_NUT',\n 40: 'SUFFIX_SEI_NUT',\n };\n return types[value] || value;\n },\n} as const;\n\n// 2. Interface cho mảng NAL Unit bên trong config\nexport interface INALArray {\n arrayCompleteness: boolean;\n nalUnitType: string | number;\n nalus: Uint8Array[];\n}\n\n// 3. Interface cho cấu hình HEVC (giúp strict type checking)\nexport interface IHEVCConfig {\n generalProfileSpace: number;\n generalTierFlag: boolean;\n generalProfileIdc: number;\n generalProfileCompatibilityFlags: number;\n generalConstraintIndicatorFlags: number;\n generalLevelIdc: number;\n minSpatialSegmentationIdc: number;\n parallelismType: number;\n chromaFormatIdc: number;\n bitDepthLumaMinus8: number;\n bitDepthChromaMinus8: number;\n avgFrameRate: number;\n constantFrameRate: number;\n numTemporalLayers: number;\n temporalIdNested: boolean;\n lengthSizeMinusOne: number;\n arrays: INALArray[];\n}\n\nexport class HEVCDecoderConfigurationRecord implements IHEVCConfig {\n // Khai báo các thuộc tính của class\n public generalProfileSpace: number = 0;\n public generalTierFlag: boolean = false;\n public generalProfileIdc: number = 0;\n public generalProfileCompatibilityFlags: number = 0;\n public generalConstraintIndicatorFlags: number = 0;\n public generalLevelIdc: number = 0;\n public minSpatialSegmentationIdc: number = 0;\n public parallelismType: number = 0;\n public chromaFormatIdc: number = 0;\n public bitDepthLumaMinus8: number = 0;\n public bitDepthChromaMinus8: number = 0;\n public avgFrameRate: number = 0;\n public constantFrameRate: number = 0;\n public numTemporalLayers: number = 0;\n public temporalIdNested: boolean = false;\n public lengthSizeMinusOne: number = 0;\n public arrays: INALArray[] = [];\n\n constructor(config: IHEVCConfig) {\n Object.assign(this, config);\n }\n\n /**\n * Demuxes an HEVCDecoderConfigurationRecord from a byte buffer.\n * @param data - The byte data to parse\n */\n static demux(data: ArrayBuffer | Uint8Array): HEVCDecoderConfigurationRecord {\n const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n let offset = 0;\n let bitOffset = 0;\n\n // Helper to read bits\n const readBits = (numBits: number): number => {\n let result = 0;\n for (let i = 0; i < numBits; i++) {\n if (offset >= buffer.length) throw new Error('End of buffer');\n const bit = (buffer[offset] >> (7 - bitOffset)) & 1;\n result = (result << 1) | bit;\n bitOffset++;\n if (bitOffset === 8) {\n bitOffset = 0;\n offset++;\n }\n }\n return result;\n };\n\n // Helper to read a byte\n const readU8 = (): number => {\n if (bitOffset !== 0) return readBits(8);\n if (offset >= buffer.length) throw new Error('End of buffer');\n return buffer[offset++];\n };\n\n // Helper to read 16-bit big-endian\n const readU16BE = (): number => {\n if (bitOffset !== 0) return readBits(16);\n const val = view.getUint16(offset, false);\n offset += 2;\n return val;\n };\n\n // Helper to read 32-bit big-endian\n const readU32BE = (): number => {\n if (bitOffset !== 0) return readBits(32);\n const val = view.getUint32(offset, false);\n offset += 4;\n return val;\n };\n\n // Helper to read 48-bit big-endian\n const readU48BE = (): number => {\n const high = readU16BE();\n const low = readU32BE();\n return high * 0x100000000 + low;\n };\n\n // Helper to read exact bytes\n const readExact = (length: number): Uint8Array => {\n if (bitOffset !== 0) {\n const result = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = readBits(8);\n }\n return result;\n }\n if (offset + length > buffer.length) throw new Error('End of buffer');\n const result = buffer.slice(offset, offset + length);\n offset += length;\n return result;\n };\n\n // Parse configuration version\n const configurationVersion = readU8();\n if (configurationVersion !== 1) {\n throw new Error('Invalid configuration version');\n }\n\n // Parse profile information\n const generalProfileSpace = readBits(2);\n const generalTierFlag = readBits(1) === 1;\n const generalProfileIdc = readBits(5);\n const generalProfileCompatibilityFlags = readU32BE();\n const generalConstraintIndicatorFlags = readU48BE();\n const generalLevelIdc = readU8();\n\n // Parse spatial segmentation\n readBits(4); // reserved_4bits\n const minSpatialSegmentationIdc = readBits(12);\n\n // Parse parallelism type\n readBits(6); // reserved_6bits\n const parallelismType = readBits(2);\n\n // Parse chroma format\n readBits(6); // reserved_6bits\n const chromaFormatIdc = readBits(2);\n\n // Parse bit depth (luma)\n readBits(5); // reserved_5bits\n const bitDepthLumaMinus8 = readBits(3);\n\n // Parse bit depth (chroma)\n readBits(5); // reserved_5bits\n const bitDepthChromaMinus8 = readBits(3);\n\n // Parse frame rate and temporal information\n const avgFrameRate = readU16BE();\n const constantFrameRate = readBits(2);\n const numTemporalLayers = readBits(3);\n const temporalIdNested = readBits(1) === 1;\n const lengthSizeMinusOne = readBits(2);\n\n if (lengthSizeMinusOne === 2) {\n throw new Error('length_size_minus_one must be 0, 1, or 3');\n }\n\n // Parse NALU arrays\n const numOfArrays = readU8();\n const arrays: INALArray[] = [];\n\n for (let i = 0; i < numOfArrays; i++) {\n const arrayCompleteness = readBits(1) === 1;\n readBits(1); // reserved\n const nalUnitType = readBits(6);\n const nalUnitTypeName = NALUnitType.fromValue(nalUnitType);\n\n if (\n nalUnitType !== NALUnitType.VPS_NUT &&\n nalUnitType !== NALUnitType.SPS_NUT &&\n nalUnitType !== NALUnitType.PPS_NUT &&\n nalUnitType !== NALUnitType.PREFIX_SEI_NUT &&\n nalUnitType !== NALUnitType.SUFFIX_SEI_NUT\n ) {\n // Có thể comment dòng này nếu muốn hỗ trợ các loại NALU khác không chuẩn\n // throw new Error('Invalid nal_unit_type');\n }\n\n const numNalus = readU16BE();\n const nalus: Uint8Array[] = [];\n\n for (let j = 0; j < numNalus; j++) {\n const nalUnitLength = readU16BE();\n const naluData = readExact(nalUnitLength);\n nalus.push(naluData);\n }\n\n arrays.push({\n arrayCompleteness,\n nalUnitType: nalUnitTypeName,\n nalus,\n });\n }\n\n return new HEVCDecoderConfigurationRecord({\n generalProfileSpace,\n generalTierFlag,\n generalProfileIdc,\n generalProfileCompatibilityFlags,\n generalConstraintIndicatorFlags,\n generalLevelIdc,\n minSpatialSegmentationIdc,\n parallelismType,\n chromaFormatIdc,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n avgFrameRate,\n constantFrameRate,\n numTemporalLayers,\n temporalIdNested,\n lengthSizeMinusOne,\n arrays,\n });\n }\n\n /**\n * Converts the HEVC configuration to a codec string (RFC 6381 format).\n * @returns Codec string like \"hev1.1.6.L93.B0\"\n */\n toCodecString(): string {\n const profileSpaceMap: Record<number, string> = { 0: '', 1: 'A', 2: 'B', 3: 'C' };\n const generalProfileSpace = profileSpaceMap[this.generalProfileSpace];\n\n if (generalProfileSpace === undefined) {\n throw new Error('Unknown profile space');\n }\n\n const profileAndSpace = `${generalProfileSpace}${this.generalProfileIdc}`;\n\n // Format profile compatibility flags (reverse hex and strip trailing zeros)\n let profileCompatibilityFlagsUnfiltered = this.generalProfileCompatibilityFlags\n .toString(16)\n .padStart(8, '0')\n .split('')\n .reverse()\n .join('');\n\n let profileCompatibilityFlags = '';\n for (let i = 0; i < profileCompatibilityFlagsUnfiltered.length; i++) {\n const char = profileCompatibilityFlagsUnfiltered[i];\n if (char !== '0' || i === 0) {\n profileCompatibilityFlags += char;\n }\n }\n\n // Format tier and level\n const generalTierFlag = this.generalTierFlag ? 'H' : 'L';\n const tierAndLevel = `${generalTierFlag}${this.generalLevelIdc}`;\n\n // Format constraint flags (skip first 2 bytes of 48-bit value)\n let constraintFlags = '';\n\n // Convert 48-bit number to 6 bytes\n const constraint = this.generalConstraintIndicatorFlags;\n const bytes = [\n Math.floor(constraint / 0x10000000000) & 0xff,\n Math.floor(constraint / 0x100000000) & 0xff,\n Math.floor(constraint / 0x1000000) & 0xff,\n Math.floor(constraint / 0x10000) & 0xff,\n Math.floor(constraint / 0x100) & 0xff,\n constraint & 0xff,\n ];\n\n // Skip first 2 bytes (bytes[0] and bytes[1]) per Logic\n for (let i = 2; i < 6; i++) {\n if (bytes[i] !== 0) {\n constraintFlags += `.${bytes[i].toString(16).padStart(2, '0')}`;\n }\n }\n\n return `hev1.${profileAndSpace}.${profileCompatibilityFlags}.${tierAndLevel}${constraintFlags}`;\n }\n}\n","import { replaceCodecNumber } from './utils';\nimport { FRAME_TYPE, IMediaReceiverEvents, INodeCall, VideoConfig } from './types';\nimport { HEVCDecoderConfigurationRecord } from './hevc_decoder_config';\n\n// Các biến cấu hình Audio Sync\nconst MAX_AUDIO_LATENCY = 0.1; // 100ms\nconst MIN_BUFFER_AHEAD = 0.02; // 20ms\n\nexport class MediaStreamReceiver {\n private videoDecoder: VideoDecoder | null = null;\n private audioDecoder: AudioDecoder | null = null;\n\n // WritableStreamDefaultWriter<VideoFrame> là type chuẩn của WebCodecs\n private videoWriter: WritableStreamDefaultWriter<VideoFrame> | null = null;\n\n private audioContext: AudioContext | null = null;\n private mediaDestination: MediaStreamAudioDestinationNode | null = null;\n\n private isWaitingForKeyFrame: boolean = true;\n private nextStartTime: number = 0;\n private lastVideoConfig: VideoConfig | null = null;\n\n private nodeCall: INodeCall;\n private events: IMediaReceiverEvents;\n\n private generatedStream: MediaStream | null = null;\n\n constructor(nodeCall: INodeCall, events: IMediaReceiverEvents = {}) {\n this.nodeCall = nodeCall;\n this.events = events;\n }\n\n public async acceptConnection(): Promise<void> {\n try {\n await this.nodeCall.acceptConnection();\n } catch (error) {\n console.error('❌ Error starting MediaStreamReceiver:', error);\n }\n }\n\n public getRemoteStream = (): MediaStream | null => {\n return this.generatedStream;\n };\n\n /**\n * Dừng toàn bộ quá trình và giải phóng tài nguyên\n */\n public stop = (): void => {\n this.resetDecoders();\n };\n\n // ================= PRIVATE METHODS =================\n\n private initAudioContext = async (): Promise<void> => {\n if (!this.audioContext || this.audioContext.state === 'closed') {\n const AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;\n this.audioContext = new AudioContextClass({\n sampleRate: 48000,\n latencyHint: 'interactive',\n });\n\n this.mediaDestination = this.audioContext.createMediaStreamDestination();\n\n if (this.audioContext.state === 'suspended') {\n await this.audioContext.resume();\n }\n this.nextStartTime = this.audioContext.currentTime + MIN_BUFFER_AHEAD;\n }\n };\n\n public initDecoders = (callType: string): void => {\n // 1. Audio Decoder Setup\n if (this.audioDecoder) this.audioDecoder.close();\n\n // 2. Setup Audio Context & Streams\n this.initAudioContext();\n\n // Đảm bảo mediaDestination đã được tạo trong initAudioContext\n if (this.mediaDestination) {\n const audioTrack = this.mediaDestination.stream.getAudioTracks()[0];\n\n // Khởi tạo stream với 1 track audio\n this.generatedStream = new MediaStream([audioTrack]);\n }\n\n this.isWaitingForKeyFrame = true;\n\n // 3. Init AudioDecoder\n this.audioDecoder = new AudioDecoder({\n output: (audioData) => this.playDecodedAudio(audioData),\n error: (err) => console.error('AudioDecoder error:', err),\n });\n\n if (callType === 'video') {\n // 4. Setup VideoDecoder\n this.setupVideoDecoder();\n }\n\n this.receiveLoop();\n };\n\n public setupVideoDecoder = (): void => {\n if (!this.videoWriter) return;\n\n if (this.videoDecoder) {\n try {\n if (this.videoDecoder.state !== 'closed') this.videoDecoder.close();\n } catch (e) {\n /* ignore */\n }\n }\n\n const videoDecoder = new VideoDecoder({\n output: async (frame) => {\n try {\n if (!this.videoWriter) {\n frame.close();\n return;\n }\n\n // Backpressure check: Nếu writer đang bận, drop frame để tránh overflow\n if (this.videoWriter.desiredSize! <= 0) {\n frame.close();\n return;\n }\n\n await this.videoWriter.write(frame);\n } catch (err) {\n frame.close();\n // console.error('Frame write error:', err);\n } finally {\n frame.close();\n }\n },\n error: (err) => {\n console.error('❌ VideoDecoder CRASHED:', err);\n this.isWaitingForKeyFrame = true;\n\n if (this.videoWriter) {\n // Chỉ hồi sinh nếu Writer vẫn còn sống\n console.log('♻️ Attempting to respawn VideoDecoder...');\n this.setupVideoDecoder();\n if (this.lastVideoConfig && this.videoDecoder) {\n try {\n this.videoDecoder.configure(this.lastVideoConfig);\n } catch (configErr) {}\n }\n }\n },\n });\n\n this.videoDecoder = videoDecoder;\n };\n\n private playDecodedAudio = (audioData: AudioData): void => {\n try {\n if (!this.audioContext || !this.mediaDestination) {\n audioData.close();\n return;\n }\n\n const { numberOfChannels, numberOfFrames, sampleRate } = audioData;\n const duration = numberOfFrames / sampleRate;\n const currentTime = this.audioContext.currentTime;\n\n // --- XỬ LÝ LATENCY & SYNC ---\n if (this.nextStartTime < currentTime) {\n this.nextStartTime = currentTime;\n } else if (this.nextStartTime > currentTime + MAX_AUDIO_LATENCY) {\n // Nếu buffer quá lớn (latency cao), reset về thời điểm hiện tại\n this.nextStartTime = currentTime + MIN_BUFFER_AHEAD;\n }\n\n const audioBuffer = this.audioContext.createBuffer(numberOfChannels, numberOfFrames, sampleRate);\n const size = numberOfChannels * numberOfFrames;\n const tempBuffer = new Float32Array(size);\n\n audioData.copyTo(tempBuffer, { planeIndex: 0, format: 'f32-planar' });\n\n for (let ch = 0; ch < numberOfChannels; ch++) {\n const channelData = tempBuffer.subarray(ch * numberOfFrames, (ch + 1) * numberOfFrames);\n audioBuffer.copyToChannel(channelData, ch);\n }\n\n const source = this.audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(this.mediaDestination);\n\n source.start(this.nextStartTime);\n this.nextStartTime += duration;\n\n audioData.close();\n } catch (err) {\n console.error('Error in playDecodedAudio:', err);\n audioData?.close();\n }\n };\n\n private newCodecFromDescription = (buffer: ArrayBuffer, receivedCodec: string): string => {\n // Chỉ check nếu codec là HEVC (hvc1 hoặc hev1)\n if (!receivedCodec.toLowerCase().includes('hvc') && !receivedCodec.toLowerCase().includes('hev')) return '';\n\n try {\n const record = HEVCDecoderConfigurationRecord.demux(buffer);\n return record.toCodecString();\n } catch (error) {\n return '';\n }\n };\n\n // Vòng lặp chính xử lý dữ liệu\n public receiveLoop = async (): Promise<void> => {\n const textDecoder = new TextDecoder();\n\n while (true) {\n try {\n if (!this.nodeCall) break;\n\n // Gọi hàm nhận dữ liệu async\n const data = await this.nodeCall.asyncRecv();\n\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const frameType = dataView.getUint8(0);\n\n // const frameTypeName =\n // {\n // [FRAME_TYPE.VIDEO_CONFIG]: 'VIDEO_CONFIG',\n // [FRAME_TYPE.AUDIO_CONFIG]: 'AUDIO_CONFIG',\n // [FRAME_TYPE.VIDEO_KEY]: 'VIDEO_KEY',\n // [FRAME_TYPE.VIDEO_DELTA]: 'VIDEO_DELTA',\n // [FRAME_TYPE.AUDIO]: 'AUDIO',\n // [FRAME_TYPE.CONNECTED]: 'CONNECTED',\n // [FRAME_TYPE.TRANSCEIVER_STATE]: 'TRANSCEIVER_STATE',\n // [FRAME_TYPE.ORIENTATION]: 'ORIENTATION',\n // [FRAME_TYPE.REQUEST_CONFIG]: 'REQUEST_CONFIG',\n // [FRAME_TYPE.REQUEST_KEY_FRAME]: 'REQUEST_KEY_FRAME',\n // [FRAME_TYPE.END_CALL]: 'END_CALL',\n // }[frameType] || 'UNKNOWN';\n\n // console.log(`----frameType ${frameTypeName}----`, frameType);\n\n const payloadOffset = (\n [\n FRAME_TYPE.VIDEO_CONFIG,\n FRAME_TYPE.AUDIO_CONFIG,\n FRAME_TYPE.CONNECTED,\n FRAME_TYPE.TRANSCEIVER_STATE,\n FRAME_TYPE.ORIENTATION,\n FRAME_TYPE.REQUEST_CONFIG,\n FRAME_TYPE.REQUEST_KEY_FRAME,\n FRAME_TYPE.END_CALL,\n ] as number[]\n ).includes(frameType)\n ? 1\n : 9; // 1 byte type + 8 bytes timestamp\n\n const payload = new Uint8Array(data.buffer, data.byteOffset + payloadOffset, data.byteLength - payloadOffset);\n\n switch (frameType) {\n // --- VIDEO CONFIG ---\n case FRAME_TYPE.VIDEO_CONFIG: {\n try {\n const videoConfigStr = textDecoder.decode(payload);\n const videoConfig = JSON.parse(videoConfigStr);\n console.log('--videoConfig--', videoConfig);\n\n // Setup Video Track Writer & Combine Streams\n if (!this.videoWriter) {\n // @ts-ignore: MediaStreamTrackGenerator types\n const videoTrackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });\n this.videoWriter = videoTrackGenerator.writable.getWriter();\n\n // MERGE: Add Video Track vào Stream Audio đã có sẵn\n if (this.generatedStream) {\n this.generatedStream.addTrack(videoTrackGenerator);\n }\n }\n\n if (!this.videoDecoder) {\n this.setupVideoDecoder();\n }\n\n this.isWaitingForKeyFrame = true;\n\n let descriptionBuffer: ArrayBuffer | undefined = undefined;\n if (videoConfig.description) {\n try {\n const binaryString = atob(videoConfig.description);\n const desc = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n desc[i] = binaryString.charCodeAt(i);\n }\n descriptionBuffer = desc.buffer;\n } catch (e) {}\n }\n\n // const newCodec = replaceCodecNumber(videoConfig.codec);\n\n let newCodec: string = '';\n if (descriptionBuffer) {\n newCodec =\n this.newCodecFromDescription(descriptionBuffer, videoConfig.codec) ||\n replaceCodecNumber(videoConfig.codec);\n }\n\n const decoderConfig: VideoConfig = {\n codec: newCodec,\n frameRate: videoConfig.frameRate,\n codedWidth: videoConfig.codedWidth,\n codedHeight: videoConfig.codedHeight,\n ...(videoConfig.orientation && { rotation: videoConfig.orientation }),\n ...(descriptionBuffer && { description: descriptionBuffer }),\n };\n\n this.lastVideoConfig = decoderConfig;\n\n if (this.videoDecoder && this.videoDecoder.state !== 'closed') {\n const support = await VideoDecoder.isConfigSupported(decoderConfig);\n if (support.supported) {\n this.videoDecoder.configure(decoderConfig);\n this.isWaitingForKeyFrame = true;\n } else {\n console.error('❌ Browser does not support this video config:', decoderConfig);\n }\n }\n } catch (error) {\n console.error('❌ Error processing VIDEO_CONFIG:', error);\n }\n break;\n }\n\n // --- AUDIO CONFIG ---\n case FRAME_TYPE.AUDIO_CONFIG: {\n const audioConfig = JSON.parse(textDecoder.decode(payload));\n console.log('--audioConfig--', audioConfig);\n\n if (this.audioDecoder?.state !== 'closed') {\n this.audioDecoder?.configure({\n codec: audioConfig.codec,\n sampleRate: audioConfig.sampleRate,\n numberOfChannels: audioConfig.numberOfChannels,\n });\n }\n break;\n }\n\n // --- VIDEO DATA ---\n case FRAME_TYPE.VIDEO_KEY:\n case FRAME_TYPE.VIDEO_DELTA: {\n if (!this.videoDecoder || this.videoDecoder.state !== 'configured') break;\n const isKeyFrame = frameType === FRAME_TYPE.VIDEO_KEY;\n\n if (this.isWaitingForKeyFrame) {\n if (!isKeyFrame) break;\n console.log('✅ Resumed decoding at KeyFrame');\n this.isWaitingForKeyFrame = false;\n }\n\n if (!isKeyFrame && this.videoDecoder.decodeQueueSize > 15) {\n console.warn('⚠️ Queue > 15. Dropping & Waiting for KeyFrame...');\n // Nếu drop bất kỳ frame nào, ta phải chờ Key Frame tiếp theo mới decode được\n this.isWaitingForKeyFrame = true;\n break;\n }\n\n // const timestamp = dataView.getUint32(1, false);\n const timestampBigInt = dataView.getBigUint64(1, false);\n const timestamp = Number(timestampBigInt);\n\n try {\n this.videoDecoder.decode(\n new EncodedVideoChunk({\n type: isKeyFrame ? 'key' : 'delta',\n timestamp: timestamp,\n data: payload,\n }),\n );\n } catch (decodeErr) {\n console.error('Video decode failed:', decodeErr);\n if ((this.videoDecoder as VideoDecoder).state === 'closed') {\n // this.setupVideoDecoder();\n // if (this.lastVideoConfig) {\n // this.videoDecoder?.configure(this.lastVideoConfig);\n // }\n this.isWaitingForKeyFrame = true;\n }\n }\n break;\n }\n\n // --- AUDIO DATA ---\n case FRAME_TYPE.AUDIO: {\n if (this.audioDecoder?.state === 'configured') {\n // const timestamp = dataView.getUint32(1, false);\n const timestampBigInt = dataView.getBigUint64(1, false);\n const timestamp = Number(timestampBigInt);\n this.audioDecoder.decode(\n new EncodedAudioChunk({\n type: 'key',\n timestamp: timestamp,\n data: payload,\n }),\n );\n }\n break;\n }\n\n case FRAME_TYPE.CONNECTED:\n if (this.events.onConnected) {\n this.events.onConnected();\n }\n break;\n\n case FRAME_TYPE.TRANSCEIVER_STATE:\n const transceiverState = JSON.parse(textDecoder.decode(payload));\n if (this.events.onTransceiverState) {\n this.events.onTransceiverState(transceiverState);\n }\n break;\n\n case FRAME_TYPE.ORIENTATION: {\n const orientation = dataView.getInt32(1, false);\n if (this.videoDecoder && this.lastVideoConfig && this.lastVideoConfig.rotation !== orientation) {\n this.lastVideoConfig.rotation = orientation;\n try {\n // 1. Configure lại với rotation mới\n this.videoDecoder.configure(this.lastVideoConfig);\n\n // 2. QUAN TRỌNG: Phải chờ KeyFrame mới để tránh lỗi decode Delta frame sau khi reset\n this.isWaitingForKeyFrame = true;\n\n console.log('🔄 Reconfigured rotation to', orientation, '- Waiting for next KeyFrame');\n } catch (configErr) {\n console.error('Error reconfiguring VideoDecoder with new orientation:', configErr);\n }\n }\n break;\n }\n\n case FRAME_TYPE.REQUEST_CONFIG:\n console.log('📥 Received REQUEST_CONFIG');\n if (this.events.onRequestConfig) {\n this.events.onRequestConfig();\n }\n break;\n\n case FRAME_TYPE.REQUEST_KEY_FRAME:\n console.log('📥 Received REQUEST_KEY_FRAME');\n if (this.events.onRequestKeyFrame) {\n this.events.onRequestKeyFrame();\n }\n break;\n\n case FRAME_TYPE.END_CALL:\n console.log('📥 Received END_CALL');\n if (this.events.onEndCall) {\n this.events.onEndCall();\n }\n break;\n\n default:\n console.warn('❓ Unknown frame type received:', frameType);\n break;\n }\n } catch (error) {\n console.error('Stream loop error', error);\n // Có thể thêm delay nhỏ ở đây để tránh spam error nếu loop lỗi liên tục\n await new Promise((r) => setTimeout(r, 200));\n }\n }\n };\n\n private resetDecoders = (): void => {\n if (this.videoWriter) {\n try {\n this.videoWriter.abort('Stream stopped').catch(() => {});\n this.videoWriter.releaseLock();\n } catch (e) {\n console.warn('Error closing video writer:', e);\n }\n this.videoWriter = null;\n }\n\n if (this.videoDecoder) {\n try {\n if (this.videoDecoder.state !== 'closed') {\n this.videoDecoder.reset();\n this.videoDecoder.close();\n }\n } catch (e) {}\n this.videoDecoder = null;\n }\n\n if (this.audioDecoder) {\n try {\n if (this.audioDecoder.state !== 'closed') {\n this.audioDecoder.reset();\n this.audioDecoder.close();\n }\n } catch (e) {}\n this.audioDecoder = null;\n }\n\n // Đóng AudioContext\n if (this.audioContext) {\n try {\n this.audioContext.close();\n } catch (e) {\n console.warn('Error closing audio context:', e);\n }\n this.audioContext = null;\n }\n\n // Reset các biến\n this.isWaitingForKeyFrame = true;\n this.mediaDestination = null;\n this.nextStartTime = 0;\n this.lastVideoConfig = null;\n\n if (this.generatedStream) {\n this.generatedStream.getTracks().forEach((track) => track.stop());\n this.generatedStream = null;\n }\n };\n}\n","import { ErmisChat } from './client';\nimport init, { ErmisCall } from './wasm/ermis_call_node_wasm';\nimport {\n CallAction,\n CallEventData,\n CallStatus,\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n Metadata,\n SignalData,\n UserCallInfo,\n} from './types';\nimport { MediaStreamSender } from './media_stream_sender';\nimport { MediaStreamReceiver } from './media_stream_receiver';\n\nexport class ErmisCallNode<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n wasmPath: string;\n\n relayUrl = 'https://test-iroh.ermis.network.:8443';\n\n /** Reference to the Ermis Chat client instance */\n _client: ErmisChat<ErmisChatGenerics>;\n\n /** Unique identifier for the current call session */\n sessionID: string;\n\n /** Channel ID for communication between users */\n cid?: string;\n\n /** Type of call: 'audio' or 'video' */\n callType?: string;\n\n /** ID of the current user */\n userID?: string | undefined;\n\n /** Current status of the call */\n callStatus? = '';\n\n metadata?: Metadata;\n\n callNode: ErmisCall | null = null;\n\n /** Local media stream from user's camera/microphone */\n localStream?: MediaStream | null = null;\n\n /** Remote media stream from the other participant */\n remoteStream?: MediaStream | null = null;\n\n /** Information about the caller */\n callerInfo?: UserCallInfo;\n\n /** Information about the call receiver */\n receiverInfo?: UserCallInfo;\n\n /** Callback triggered when call events occur (incoming/outgoing) */\n onCallEvent?: (data: CallEventData) => void;\n\n /** Callback triggered when local stream is available */\n onLocalStream?: (stream: MediaStream) => void;\n\n /** Callback triggered when remote stream is available */\n onRemoteStream?: (stream: MediaStream) => void;\n\n /** Callback for connection status message changes */\n onConnectionMessageChange?: (message: string | null) => void;\n\n /** Callback for call status changes */\n onCallStatus?: (status: string | null) => void;\n\n /** Callback for messages received through WebRTC data channel */\n onDataChannelMessage?: (data: any) => void;\n\n /** Callback for when a call is upgraded (e.g., audio to video) */\n onUpgradeCall?: (upgraderInfo: UserCallInfo) => void;\n\n /** Callback for screen sharing status changes */\n onScreenShareChange?: (isSharing: boolean) => void;\n\n /** Callback for error handling */\n onError?: (error: string) => void;\n\n /** Callback for device list changes */\n onDeviceChange?: (audioDevices: MediaDeviceInfo[], videoDevices: MediaDeviceInfo[]) => void;\n\n /** Available audio input devices */\n private availableAudioDevices: MediaDeviceInfo[] = [];\n\n /** Available video input devices */\n private availableVideoDevices: MediaDeviceInfo[] = [];\n\n /** Currently selected audio device ID */\n private selectedAudioDeviceId?: string;\n\n /** Currently selected video device ID */\n private selectedVideoDeviceId?: string;\n\n /** Timeout for ending call if not answered after a period */\n private missCallTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Interval for sending health check via WebRTC */\n private healthCallInterval: ReturnType<typeof setInterval> | null = null;\n\n /** Interval for sending health check via server */\n private healthCallServerInterval: ReturnType<typeof setInterval> | null = null;\n\n /** Timeout for detecting if remote peer has disconnected */\n private healthCallTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Timeout for showing warning when connection becomes unstable */\n private healthCallWarningTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Handler for signal events */\n private signalHandler: any;\n\n /** Handler for connection change events */\n private connectionChangedHandler: any;\n\n /** Handler for message updated events */\n private messageUpdatedHandler: any;\n\n /** Flag indicating if the user is offline */\n private isOffline: boolean = false;\n\n /**\n * True if this call instance is destroyed (e.g., when another device accepts the call).\n * When true, SIGNAL_CALL events will be ignored.\n */\n private isDestroyed = false;\n\n public mediaSender: MediaStreamSender | null = null;\n public mediaReceiver: MediaStreamReceiver | null = null;\n\n constructor(client: ErmisChat<ErmisChatGenerics>, sessionID: string, wasmPath: string, relayUrl: string) {\n this._client = client;\n this.cid = '';\n this.callType = '';\n this.sessionID = sessionID;\n this.userID = client.userID;\n this.metadata = {};\n this.wasmPath = wasmPath;\n this.relayUrl = relayUrl;\n\n this.listenSocketEvents();\n this.setupDeviceChangeListener();\n this.loadWasm();\n }\n\n private async loadWasm(): Promise<void> {\n try {\n await init(this.wasmPath);\n } catch (error) {\n console.error('Failed to load ErmisCall WASM module:', error);\n throw error;\n }\n }\n\n private async initialize(): Promise<ErmisCall> {\n try {\n const node = new ErmisCall();\n await node.spawn([this.relayUrl]);\n this.callNode = node;\n\n // 1. Init Sender\n this.mediaSender = new MediaStreamSender(node as any);\n\n // 2. Init Receiver\n this.mediaReceiver = new MediaStreamReceiver(node as any, {\n onConnected: () => {\n this.setCallStatus(CallStatus.CONNECTED);\n this.connectCall();\n if (this.missCallTimeout) {\n clearTimeout(this.missCallTimeout);\n this.missCallTimeout = null;\n }\n if (this.healthCallServerInterval) clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = setInterval(() => {\n this.healthCall();\n }, 10000);\n\n const remoteStream = this.mediaReceiver?.getRemoteStream();\n\n if (remoteStream && this.onRemoteStream) {\n this.onRemoteStream(remoteStream);\n }\n },\n\n onTransceiverState: (state) => {\n if (typeof this.onDataChannelMessage === 'function') {\n this.onDataChannelMessage(state);\n }\n },\n\n onRequestConfig: () => {\n console.log('📤 Responding to REQUEST_CONFIG by sending configs');\n this.mediaSender?.sendConfigs();\n },\n\n onRequestKeyFrame: () => {\n console.log('📤 Responding to REQUEST_KEY_FRAME by forcing key frame');\n this.mediaSender?.requestKeyFrame();\n },\n\n onEndCall: () => {\n console.log('📥 Received END_CALL from remote peer');\n this.destroy();\n },\n });\n\n return node;\n } catch (error) {\n console.error('Failed to initialize Ermis SDK:', error);\n throw error;\n }\n }\n\n public async getLocalEndpointAddr(): Promise<string | null> {\n try {\n await this.initialize();\n\n if (!this.callNode) {\n console.error('ErmisCall is not initialized.');\n return null;\n }\n\n const address = await this.callNode.getLocalEndpointAddr();\n if (this.metadata) {\n this.metadata.address = address;\n }\n return address;\n } catch (error) {\n console.error('Failed to get address from ErmisCall:', error);\n return null;\n }\n }\n\n private getClient(): ErmisChat<ErmisChatGenerics> {\n return this._client;\n }\n\n private async _sendSignal(payload: SignalData) {\n try {\n return await this.getClient().post(this.getClient().baseURL + '/signal', {\n ...payload,\n cid: this.cid || payload.cid,\n is_video: this.callType === 'video' || payload.is_video,\n ios: false,\n session_id: this.sessionID,\n });\n } catch (error: any) {\n const action = payload.action;\n\n // Skip error message for HEALTH_CALL action\n if (action === CallAction.HEALTH_CALL) {\n return;\n }\n\n if (typeof this.onError === 'function') {\n if (error.code === 'ERR_NETWORK') {\n if (action === CallAction.CREATE_CALL) {\n this.onError('Unable to make the call. Please check your network connection');\n }\n } else {\n if (error.response.data.ermis_code === 20) {\n this.onError('Recipient was busy');\n } else {\n const errMsg = error.response.data?.message ? error.response.data?.message : 'Call failed';\n this.onError(errMsg);\n }\n }\n }\n }\n }\n\n private async getAvailableDevices(): Promise<{ audioDevices: MediaDeviceInfo[]; videoDevices: MediaDeviceInfo[] }> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const audioDevices = devices.filter((device) => device.kind === 'audioinput');\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n this.availableAudioDevices = audioDevices;\n this.availableVideoDevices = videoDevices;\n\n return { audioDevices, videoDevices };\n } catch (error) {\n console.error('Error enumerating devices:', error);\n return { audioDevices: [], videoDevices: [] };\n }\n }\n\n private async getMediaConstraints() {\n // Get available devices first\n const { audioDevices, videoDevices } = await this.getAvailableDevices();\n\n // Notify UI about available devices\n if (this.onDeviceChange) {\n this.onDeviceChange(audioDevices, videoDevices);\n }\n\n // Auto-select default devices if none selected\n if (!this.selectedAudioDeviceId && audioDevices.length > 0) {\n this.selectedAudioDeviceId = audioDevices[0].deviceId;\n }\n if (!this.selectedVideoDeviceId && videoDevices.length > 0) {\n this.selectedVideoDeviceId = videoDevices[0].deviceId;\n }\n\n // Build constraints with specific device IDs if selected\n const audioConstraints = {\n deviceId: this.selectedAudioDeviceId ? { exact: this.selectedAudioDeviceId } : undefined,\n echoCancellation: true,\n noiseSuppression: true,\n sampleRate: 48000,\n };\n\n const videoConstraints =\n this.callType === 'video'\n ? {\n deviceId: this.selectedVideoDeviceId ? { exact: this.selectedVideoDeviceId } : undefined,\n width: 640,\n height: 360,\n }\n : false;\n\n const finalConstraints: MediaStreamConstraints = {\n audio: audioConstraints,\n video: videoConstraints,\n };\n\n return finalConstraints;\n }\n\n public async startLocalStream() {\n const mediaConstraints = await this.getMediaConstraints();\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n return this.applyLocalStream(stream);\n } catch (error: any) {\n console.warn('Error getting user media:', error?.message);\n\n // Video call: try fallback to audio-only (camera not available)\n if (this.callType === 'video' && mediaConstraints.video) {\n try {\n const audioOnlyStream = await navigator.mediaDevices.getUserMedia({\n audio: mediaConstraints.audio,\n video: false,\n });\n this.setConnectionMessage('Camera not available, using audio only');\n return this.applyLocalStream(audioOnlyStream);\n } catch {\n // Audio fallback also failed\n }\n }\n\n // No device found at all — report error\n if (typeof this.onError === 'function') {\n this.onError('No microphone or camera found. Please check your device.');\n }\n return null;\n }\n }\n\n private applyLocalStream(stream: MediaStream) {\n if (this.callStatus === CallStatus.ENDED) {\n stream.getTracks().forEach((track) => track.stop());\n this.destroy();\n return;\n }\n if (this.onLocalStream) {\n this.onLocalStream(stream);\n }\n this.localStream = stream;\n return stream;\n }\n\n private setConnectionMessage(message: string | null) {\n if (typeof this.onConnectionMessageChange === 'function') {\n this.onConnectionMessageChange(message);\n }\n }\n\n private setCallStatus(status: CallStatus) {\n this.callStatus = status;\n if (typeof this.onCallStatus === 'function') {\n this.onCallStatus(status);\n }\n }\n\n private setUserInfo(cid: string | undefined, eventUserId: string | undefined) {\n if (!cid || !eventUserId) return;\n\n // Get caller and receiver userId from activeChannels\n const channel = cid ? this.getClient().activeChannels[cid] : undefined;\n const members = channel?.state?.members || {};\n const memberIds = Object.keys(members);\n\n // callerId is eventUserId, receiverId is the other user in the channel\n const callerId = eventUserId || '';\n const receiverId = memberIds.find((id) => id !== callerId) || '';\n\n // Get user info from client.state.users\n const callerUser = this.getClient().state.users[callerId];\n const receiverUser = this.getClient().state.users[receiverId];\n\n this.callerInfo = {\n id: callerId,\n name: callerUser?.name,\n avatar: callerUser?.avatar || '',\n };\n this.receiverInfo = {\n id: receiverId,\n name: receiverUser?.name,\n avatar: receiverUser?.avatar || '',\n };\n }\n\n private listenSocketEvents() {\n this.signalHandler = async (event: Event<ErmisChatGenerics>) => {\n const { action, user_id: eventUserId, session_id: eventSessionId, cid, is_video, signal, metadata } = event;\n\n switch (action) {\n case CallAction.CREATE_CALL:\n if (eventUserId === this.userID && eventSessionId !== this.sessionID) {\n // If the event is triggered by the current user but the session ID is different,\n // it means another device (or tab) of the same user has started a call.\n // In this case, mark this call instance as destroyed and ignore further events.\n this.isDestroyed = true;\n this.destroy();\n return;\n }\n this.isDestroyed = false;\n this.callStatus = '';\n this.callType = is_video ? 'video' : 'audio';\n\n this.setUserInfo(cid, eventUserId);\n this.setCallStatus(CallStatus.RINGING);\n this.cid = cid || '';\n this.metadata = metadata || {};\n\n if (typeof this.onCallEvent === 'function') {\n this.onCallEvent({\n type: eventUserId !== this.userID ? 'incoming' : 'outgoing',\n callType: is_video ? 'video' : 'audio',\n cid: cid || '',\n callerInfo: this.callerInfo,\n receiverInfo: this.receiverInfo,\n metadata: this.metadata,\n });\n }\n\n await this.startLocalStream();\n if (this.callStatus === CallStatus.ENDED) return;\n\n if (eventUserId !== this.userID) {\n await this.initialize();\n }\n\n if (this.localStream && this.mediaSender && this.mediaReceiver) {\n this.mediaSender?.initEncoders(this.localStream);\n this.mediaReceiver?.initDecoders(this.callType);\n }\n\n if (eventUserId === this.userID) {\n // Set missCall timeout if no connection after 60s\n if (this.missCallTimeout) clearTimeout(this.missCallTimeout);\n this.missCallTimeout = setTimeout(async () => {\n await this.missCall();\n }, 60000);\n }\n break;\n\n case CallAction.ACCEPT_CALL:\n if (eventUserId === this.userID && eventSessionId !== this.sessionID) {\n this.isDestroyed = true;\n this.destroy();\n return;\n }\n\n if (eventUserId !== this.userID && !this.isDestroyed) {\n if (this.mediaReceiver && this.mediaSender) {\n await this.mediaReceiver.acceptConnection();\n await this.mediaSender.sendConnected();\n await this.mediaSender.sendConfigs();\n }\n }\n break;\n\n case CallAction.END_CALL:\n case CallAction.REJECT_CALL:\n case CallAction.MISS_CALL:\n // this.setCallStatus(CallStatus.ENDED);\n this.destroy();\n break;\n }\n };\n\n this.connectionChangedHandler = (event: Event<ErmisChatGenerics>) => {\n const online = event.online;\n this.isOffline = !online;\n if (!online) {\n this.setConnectionMessage('Your network connection is unstable');\n\n // Clear health_call intervals when offline\n if (this.healthCallInterval) {\n clearInterval(this.healthCallInterval);\n this.healthCallInterval = null;\n }\n if (this.healthCallServerInterval) {\n clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = null;\n }\n } else {\n this.setConnectionMessage(null);\n\n // When back online, if CONNECTED, set up health_call intervals again\n if (this.callStatus === CallStatus.CONNECTED) {\n if (!this.healthCallServerInterval) {\n this.healthCallServerInterval = setInterval(() => {\n this.healthCall();\n }, 10000);\n }\n }\n }\n };\n\n this.messageUpdatedHandler = (event: Event<ErmisChatGenerics>) => {\n if (this.callStatus === CallStatus.CONNECTED && event.cid === this.cid) {\n const upgradeUserId = event.user?.id;\n\n let upgraderInfo: UserCallInfo | undefined;\n\n if (upgradeUserId === this.callerInfo?.id) {\n upgraderInfo = this.callerInfo;\n } else if (upgradeUserId === this.receiverInfo?.id) {\n upgraderInfo = this.receiverInfo;\n }\n\n if (upgraderInfo && typeof this.onUpgradeCall === 'function') {\n this.onUpgradeCall(upgraderInfo);\n }\n }\n };\n\n this._client.on('signal', this.signalHandler);\n this._client.on('connection.changed', this.connectionChangedHandler);\n this._client.on('message.updated', this.messageUpdatedHandler);\n }\n\n private cleanupCall() {\n if (this.mediaSender) {\n this.mediaSender?.stop();\n this.mediaSender = null;\n }\n if (this.mediaReceiver) {\n this.mediaReceiver.stop();\n this.mediaReceiver = null;\n }\n\n if (this.callNode) {\n this.callNode?.closeEndpoint();\n\n if (this.callStatus === CallStatus.CONNECTED) {\n this.callNode?.closeConnection();\n }\n\n this.callNode = null;\n }\n\n // Clear all timeouts and intervals\n if (this.missCallTimeout) {\n clearTimeout(this.missCallTimeout);\n this.missCallTimeout = null;\n }\n\n if (this.healthCallInterval) {\n clearInterval(this.healthCallInterval);\n this.healthCallInterval = null;\n }\n\n if (this.healthCallServerInterval) {\n clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = null;\n }\n\n if (this.healthCallTimeout) {\n clearTimeout(this.healthCallTimeout);\n this.healthCallTimeout = null;\n }\n\n if (this.healthCallWarningTimeout) {\n clearTimeout(this.healthCallWarningTimeout);\n this.healthCallWarningTimeout = null;\n }\n\n // this.setCallStatus(CallStatus.ENDED);\n this.setConnectionMessage(null);\n this.cid = '';\n this.callType = '';\n this.metadata = {};\n\n if (this.localStream) {\n this.localStream.getTracks().forEach((track) => track.stop());\n this.localStream = null;\n }\n\n if (this.remoteStream) {\n this.remoteStream.getTracks().forEach((track) => track.stop());\n this.remoteStream = null;\n }\n\n this.setCallStatus(CallStatus.ENDED);\n }\n\n private destroy() {\n // if (this.signalHandler) this._client.off('signal', this.signalHandler);\n // if (this.connectionChangedHandler) this._client.off('connection.changed', this.connectionChangedHandler);\n // if (this.messageUpdatedHandler) this._client.off('message.updated', this.messageUpdatedHandler);\n this.cleanupCall();\n }\n\n public async getDevices(): Promise<{ audioDevices: MediaDeviceInfo[]; videoDevices: MediaDeviceInfo[] }> {\n // Return cached devices if available, otherwise fetch new ones\n if (this.availableAudioDevices.length > 0 || this.availableVideoDevices.length > 0) {\n return {\n audioDevices: this.availableAudioDevices,\n videoDevices: this.availableVideoDevices,\n };\n }\n return await this.getAvailableDevices();\n }\n\n // Get current selected devices info\n public getSelectedDevices(): { audioDevice?: MediaDeviceInfo; videoDevice?: MediaDeviceInfo } {\n const audioDevice = this.selectedAudioDeviceId\n ? this.availableAudioDevices.find((device) => device.deviceId === this.selectedAudioDeviceId)\n : undefined;\n\n const videoDevice = this.selectedVideoDeviceId\n ? this.availableVideoDevices.find((device) => device.deviceId === this.selectedVideoDeviceId)\n : undefined;\n\n return { audioDevice, videoDevice };\n }\n\n // Get default devices (first available device)\n public getDefaultDevices(): { audioDevice?: MediaDeviceInfo; videoDevice?: MediaDeviceInfo } {\n return {\n audioDevice: this.availableAudioDevices[0],\n videoDevice: this.availableVideoDevices[0],\n };\n }\n\n public async createCall(callType: string, cid: string) {\n try {\n this.cid = cid;\n\n const address = await this.getLocalEndpointAddr();\n\n await this._sendSignal({\n action: CallAction.CREATE_CALL,\n cid,\n is_video: callType === 'video',\n metadata: { address },\n });\n } catch (error) {\n console.error('Failed to create call:', error);\n throw error;\n }\n }\n\n public async acceptCall() {\n try {\n await this._sendSignal({ action: CallAction.ACCEPT_CALL });\n\n if (this.mediaSender) {\n const address = this.metadata?.address || '';\n await this.mediaSender.connect(address);\n }\n } catch (error) {\n console.error('Failed to accept call:', error);\n throw error;\n }\n }\n\n public async endCall() {\n await this._sendSignal({ action: CallAction.END_CALL });\n this.destroy();\n }\n\n public async rejectCall() {\n await this._sendSignal({ action: CallAction.REJECT_CALL });\n this.destroy();\n }\n\n private async missCall() {\n await this._sendSignal({ action: CallAction.MISS_CALL });\n this.destroy();\n }\n\n private async connectCall() {\n return await this._sendSignal({ action: CallAction.CONNECT_CALL });\n }\n\n private async healthCall() {\n return await this._sendSignal({ action: CallAction.HEALTH_CALL });\n }\n\n private async addVideoTrackToLocalStream() {\n const mediaConstraints = await this.getMediaConstraints();\n const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n const newVideoTrack = stream.getVideoTracks()[0];\n if (this.localStream) {\n this.localStream.addTrack(newVideoTrack);\n\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n } else {\n this.localStream = stream;\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n }\n }\n\n public async upgradeCall() {\n try {\n this.callType = 'video';\n await this.addVideoTrackToLocalStream();\n await this._sendSignal({ action: CallAction.UPGRADE_CALL });\n\n if (this.localStream) {\n this.mediaSender?.initVideoEncoder(this.localStream?.getVideoTracks()[0]);\n const audioEnable = !!this.localStream?.getAudioTracks().some((track) => track.enabled);\n const videoEnable = !!this.localStream?.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n } catch (error) {\n console.error('Failed to upgrade call:', error);\n throw error;\n }\n }\n\n public async requestUpgradeCall(enabled: boolean) {\n if (enabled) {\n this.callType = 'video';\n await this.addVideoTrackToLocalStream();\n\n if (this.localStream) {\n this.mediaSender?.initVideoEncoder(this.localStream?.getVideoTracks()[0]);\n const audioEnable = !!this.localStream?.getAudioTracks().some((track) => track.enabled);\n const videoEnable = !!this.localStream?.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n }\n\n public async startScreenShare() {\n // @ts-ignore\n if (!navigator.mediaDevices.getDisplayMedia) {\n throw new Error('Screen sharing is not supported in this browser.');\n }\n\n // @ts-ignore\n const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });\n const screenTrack = screenStream.getVideoTracks()[0];\n\n // Replace video track in localStream\n if (this.localStream) {\n // Stop old track\n this.localStream.getVideoTracks().forEach((track) => track.stop());\n // Add new track to localStream\n this.localStream.removeTrack(this.localStream.getVideoTracks()[0]);\n this.localStream.addTrack(screenTrack);\n } else {\n // If no localStream, create new one\n this.localStream = screenStream;\n }\n\n // When screen sharing stops, automatically switch back to camera\n screenTrack.onended = () => {\n this.stopScreenShare();\n };\n\n // Call callback if UI needs to update\n if (this.onLocalStream) {\n // @ts-ignore\n this.onLocalStream(this.localStream);\n\n this.mediaSender?.replaceVideoTrack(this.localStream.getVideoTracks()[0]);\n }\n\n // Call callback when screen sharing starts\n if (typeof this.onScreenShareChange === 'function') {\n this.onScreenShareChange(true);\n }\n }\n\n public async stopScreenShare() {\n const mediaConstraints = await this.getMediaConstraints();\n\n try {\n // Only request video; we already have an active audio track in localStream\n const cameraStream = await navigator.mediaDevices.getUserMedia({\n video: mediaConstraints.video,\n audio: false,\n });\n const cameraTrack = cameraStream.getVideoTracks()[0];\n\n // Replace video track in localStream\n if (this.localStream) {\n // Stop old screen tracks\n this.localStream.getVideoTracks().forEach((track) => {\n track.stop();\n this.localStream?.removeTrack(track);\n });\n \n // Add new camera track\n this.localStream.addTrack(cameraTrack);\n } else {\n this.localStream = cameraStream;\n }\n\n // Call callback if UI needs to update\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n this.mediaSender?.replaceVideoTrack(this.localStream.getVideoTracks()[0]);\n }\n\n // Call callback when screen sharing stops\n if (typeof this.onScreenShareChange === 'function') {\n this.onScreenShareChange(false);\n }\n } catch (error) {\n console.error('Error stopping screen share and reverting to camera:', error);\n }\n }\n\n public async toggleMic(enabled: boolean) {\n if (this.localStream) {\n this.localStream.getAudioTracks().forEach((track) => {\n track.enabled = enabled;\n });\n\n const audioEnable = enabled;\n const videoEnable = this.localStream.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n\n public async toggleCamera(enabled: boolean) {\n if (this.localStream) {\n this.localStream.getVideoTracks().forEach((track) => {\n track.enabled = enabled;\n });\n\n const audioEnable = this.localStream.getAudioTracks().some((track) => track.enabled);\n const videoEnable = enabled;\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n\n // Public method to switch audio device\n public async switchAudioDevice(deviceId: string): Promise<boolean> {\n try {\n // Validate device exists in available devices\n const targetDevice = this.availableAudioDevices.find((device) => device.deviceId === deviceId);\n if (!targetDevice) {\n console.error('Audio device not found:', deviceId);\n if (this.onError) {\n this.onError('Selected microphone not found');\n }\n return false;\n }\n\n this.selectedAudioDeviceId = deviceId;\n\n if (!this.localStream) return false;\n\n // Get new audio stream with selected device\n const newStream = await navigator.mediaDevices.getUserMedia({\n audio: { deviceId: { exact: deviceId } },\n video: false,\n });\n\n const newAudioTrack = newStream.getAudioTracks()[0];\n const oldAudioTrack = this.localStream.getAudioTracks()[0];\n\n // Replace audio track in peer connection\n // if (this.peer && oldAudioTrack) {\n // const sender = this.peer.getSenders().find((s) => s.track === oldAudioTrack);\n // if (sender) {\n // await sender.replaceTrack(newAudioTrack);\n // }\n // }\n\n // Replace audio track in local stream\n if (oldAudioTrack) {\n this.localStream.removeTrack(oldAudioTrack);\n oldAudioTrack.stop();\n }\n this.localStream.addTrack(newAudioTrack);\n\n // Update UI\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n\n return true;\n } catch (error) {\n console.error('Error switching audio device:', error);\n if (this.onError) {\n this.onError('Failed to switch microphone');\n }\n return false;\n }\n }\n\n // Public method to switch video device\n public async switchVideoDevice(deviceId: string): Promise<boolean> {\n try {\n // Validate device exists in available devices\n const targetDevice = this.availableVideoDevices.find((device) => device.deviceId === deviceId);\n if (!targetDevice) {\n console.error('Video device not found:', deviceId);\n if (this.onError) {\n this.onError('Selected camera not found');\n }\n return false;\n }\n\n this.selectedVideoDeviceId = deviceId;\n\n if (!this.localStream) return false;\n\n // Get new video stream with selected device\n const newStream = await navigator.mediaDevices.getUserMedia({\n audio: false,\n video: { deviceId: { exact: deviceId } },\n });\n\n const newVideoTrack = newStream.getVideoTracks()[0];\n const oldVideoTrack = this.localStream.getVideoTracks()[0];\n\n // Replace video track in local stream\n if (oldVideoTrack) {\n this.localStream.removeTrack(oldVideoTrack);\n oldVideoTrack.stop();\n }\n this.localStream.addTrack(newVideoTrack);\n\n // Update UI\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n\n return true;\n } catch (error) {\n console.error('Error switching video device:', error);\n if (this.onError) {\n this.onError('Failed to switch camera');\n }\n return false;\n }\n }\n\n // Listen for device changes\n private setupDeviceChangeListener() {\n navigator.mediaDevices.addEventListener('devicechange', async () => {\n const { audioDevices, videoDevices } = await this.getAvailableDevices();\n if (this.onDeviceChange) {\n this.onDeviceChange(audioDevices, videoDevices);\n }\n });\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { APIErrorResponse, ErmisChatOptions, ErrorFromResponse, Logger } from './types';\nimport { chatCodes, isFunction, randomId, retryInterval, sleep } from './utils';\nimport https from 'https';\nimport { isErrorResponse } from './errors';\n\nexport class ErmisAuthProvider {\n apiKey: string;\n baseURL?: string;\n options?: ErmisChatOptions;\n axiosInstance: AxiosInstance;\n disconnected: boolean;\n browser: boolean;\n node: boolean;\n logger: Logger;\n consecutiveFailures: number;\n userAgent?: string;\n /** Last identifier (phone or email) used for OTP */\n lastIdentifier?: string;\n /**\n * The last OTP method used ('Sms', 'Voice', or 'Email').\n * Used to verify OTP for the correct method.\n */\n lastMethod?: 'Sms' | 'Voice' | 'Email';\n /** Wallet address used for wallet authentication */\n address?: string;\n\n constructor(apiKey: string, baseURL: string, options?: ErmisChatOptions) {\n const inputOptions = options || {};\n this.apiKey = apiKey;\n this.baseURL = options?.userBaseURL || baseURL + '/uss/v1';\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n this.options = {\n // timeout: 3000,\n withCredentials: false, // making sure cookies are not sent\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n this.axiosInstance = axios.create(this.options);\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.consecutiveFailures = 0;\n this.disconnected = false;\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger(\n 'info',\n `client: ${type} - Request - ${url}- ${JSON.stringify(data)} - ${JSON.stringify(config.params)}`,\n {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n },\n );\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown, options: unknown) {\n this.logger(\n 'error',\n `client:${type} - Error: ${JSON.stringify(error)} - url: ${url} - options: ${JSON.stringify(options)}`,\n {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n },\n );\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n const requestConfig = this._enrichAxiosOptions(options);\n\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e, options);\n this.consecutiveFailures += 1;\n if (e.response) {\n /** connection_fallback depends on this token expiration logic */\n if (e.response.data.code === chatCodes.TOKEN_EXPIRED) {\n if (this.consecutiveFailures > 1) {\n await sleep(retryInterval(this.consecutiveFailures));\n }\n return await this.doAxiosRequest<T>(type, url, data, requestConfig);\n }\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('post', url, data, { params });\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`ErmisChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`ErmisChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n getUserAgent() {\n return (\n this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n let signal: AbortSignal | null = null;\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n const {\n params: axiosRequestConfigParams,\n headers: axiosRequestConfigHeaders,\n ...axiosRequestConfigRest\n } = this.options?.axiosRequestConfig || {};\n\n let user_service_params = {\n // api_key: this.key,\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n };\n\n return {\n params: user_service_params,\n headers: {\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n ...(signal ? { signal } : {}),\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n /**\n * Send OTP to a phone number.\n * @param identifier Phone number\n * @param language Language code (e.g. 'En', 'Vi')\n * @param method Method type (e.g. 'Sms', 'Voice')\n */\n async sendOtpToPhone(identifier: string, method: 'Sms' | 'Voice'): Promise<{ success: boolean; message?: string }> {\n this.lastIdentifier = identifier;\n this.lastMethod = method;\n const data = {\n apikey: this.apiKey,\n identifier,\n language: 'Vi',\n method,\n otp_type: 'Login',\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/get_otp_new', data);\n }\n\n /**\n * Send OTP to a email.\n * @param identifier Email address\n * @param language Language code (e.g. 'En', 'Vi')\n * @param method Method type (e.g. 'Email')\n */\n async sendOtpToEmail(identifier: string): Promise<{ success: boolean; message?: string }> {\n this.lastIdentifier = identifier;\n this.lastMethod = 'Email';\n const data = {\n apikey: this.apiKey,\n identifier,\n language: 'Vi',\n method: 'Email',\n otp_type: 'Login',\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/get_otp_new', data);\n }\n\n /**\n * Verify OTP for phone or email.\n * @param otp OTP code\n */\n async verifyOtp(otp: string): Promise<{ success: boolean; message?: string }> {\n const data = {\n identifier: this.lastIdentifier,\n method: this.lastMethod,\n apikey: this.apiKey,\n otp,\n };\n\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/otp_login', data);\n }\n\n /**\n * Login with Google.\n * @param token Google OAuth token\n * @param apikey API key\n */\n async loginWithGoogle(token: string): Promise<{ success: boolean; message?: string }> {\n const data = {\n token,\n apikey: this.apiKey,\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/google_login', data);\n }\n\n /**\n * Get challenge for wallet login.\n * @param address Wallet address\n * @param apiKey API key\n */\n async getWalletChallenge(address: string): Promise<any> {\n this.address = address;\n const response = await this.post<{ challenge: string }>(this.baseURL + '/auth/get_challenge', {\n address,\n apikey: this.apiKey,\n });\n const challenge = JSON.parse(response.challenge);\n return challenge;\n }\n\n private createNonce(length: number): string {\n let result = '';\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const charactersLength = characters.length;\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength));\n }\n return result;\n }\n\n /**\n * Verify wallet signature after receiving the challenge.\n * @param address Wallet address\n * @param signature Signature generated by the wallet\n * @param nonce Nonce used in the challenge\n * @returns Verification result and token if successful\n */\n async verifyWalletSignature(signature: string): Promise<{ success: boolean; token?: string; message?: string }> {\n const data = {\n address: this.address,\n signature,\n nonce: this.createNonce(20),\n apikey: this.apiKey,\n };\n return this.post<{ success: boolean; token?: string; message?: string }>(\n this.baseURL + '/auth/verify_signature',\n data,\n );\n }\n}\n","/**\n * Duration lookup: milliseconds → human-readable text.\n */\nconst DURATION_MAP: Record<string, string> = {\n '10000': '10 seconds',\n '30000': '30 seconds',\n '60000': '1 minute',\n '300000': '5 minutes',\n '900000': '15 minutes',\n '3600000': '60 minutes',\n};\n\n/**\n * Resolve a user ID to a display name using the provided map.\n * Falls back to the raw userId if no entry is found.\n */\nfunction resolveUser(userId: string, userMap: Record<string, string>): string {\n return userMap[userId] ?? userId;\n}\n\n/**\n * Parse a raw system message string into a human-readable English sentence.\n *\n * The raw format is: `\"<formatId> <userID> [<param1> <param2> ...]\"`\n *\n * @param value - Raw system message string from the server\n * @param userMap - Mapping of user IDs → display names\n * @returns Parsed English text, or the original string if the format is unknown\n */\nexport function parseSystemMessage(\n value: string,\n userMap: Record<string, string>,\n): string {\n if (!value || typeof value !== 'string') return value ?? '';\n\n const trimmed = value.trim();\n if (!trimmed) return '';\n\n const parts = trimmed.split(' ');\n const formatId = parts[0];\n const userId = parts[1] ?? '';\n const userName = userId ? resolveUser(userId, userMap) : 'User';\n\n switch (formatId) {\n // 1: userName changed the channel name to channelName (may contain spaces)\n case '1': {\n const channelName = parts.slice(2).join(' ');\n return `${userName} changed the channel name to ${channelName}.`;\n }\n\n // 2–13, 16–17: single-user actions\n case '2':\n return `${userName} changed the channel avatar.`;\n case '3':\n return `${userName} changed the channel description.`;\n case '4':\n return `${userName} was removed from the channel.`;\n case '5':\n return `${userName} was banned.`;\n case '6':\n return `${userName} was unbanned.`;\n case '7':\n return `${userName} was promoted to moderator.`;\n case '8':\n return `${userName} was demoted from moderator.`;\n case '9':\n return `${userName}'s permissions were updated.`;\n case '10':\n return `${userName} joined the channel.`;\n case '11':\n return `${userName} declined the channel invitation.`;\n case '12':\n return `${userName} left the channel.`;\n case '13':\n return `${userName} cleared the chat history.`;\n\n // 14: channel type change (true = public, false = private)\n case '14': {\n const rawType = parts[2] ?? '';\n const channelType = rawType === 'true' ? 'public' : 'private';\n return `${userName} changed the channel to ${channelType}.`;\n }\n\n // 15: cooldown toggle / duration\n case '15': {\n const duration = parts[2] ?? '0';\n if (duration === '0') {\n return `${userName} disabled cooldown.`;\n }\n const durationText = DURATION_MAP[duration] ?? `${duration}ms`;\n return `${userName} enabled cooldown for ${durationText}.`;\n }\n\n case '16':\n return `${userName} updated the banned words.`;\n case '17':\n return `${userName} was added to the channel.`;\n\n // 18: admin transfer (two user IDs)\n case '18': {\n const oldUserId = parts[1] ?? '';\n const newUserId = parts[2] ?? '';\n const oldUserName = oldUserId ? resolveUser(oldUserId, userMap) : 'User';\n const newUserName = newUserId ? resolveUser(newUserId, userMap) : 'User';\n return `Admin ${oldUserName} left and assigned ${newUserName} as the new admin.`;\n }\n\n // 19–20: pin / unpin (userId + msgID)\n case '19':\n return `${userName} pinned a message.`;\n case '20':\n return `${userName} unpinned a message.`;\n\n default:\n return trimmed;\n }\n}\n","/**\n * Call type constants for signal messages.\n */\nexport const CallType = {\n AUDIO: 'audio',\n VIDEO: 'video',\n} as const;\n\nexport type CallTypeValue = (typeof CallType)[keyof typeof CallType];\n\n/**\n * Result of parsing a signal message.\n */\nexport interface SignalMessageResult {\n text: string;\n duration: string;\n callType: CallTypeValue | '';\n color: string;\n}\n\n/**\n * Format duration from milliseconds to \"X min, Y sec\" format.\n */\nfunction formatDuration(durationMs: string): string {\n if (!durationMs) return '';\n const ms = parseInt(durationMs, 10);\n if (isNaN(ms) || ms <= 0) return '';\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes} min, ${seconds} sec`;\n}\n\n/**\n * Parse a raw signal message string into a structured object\n * containing text, duration, call type, and color.\n *\n * Signal messages represent call events. The raw format is:\n * `\"<formatId> <callerId> [<enderId> <duration>]\"`\n *\n * @param value - Raw signal message string from the server\n * @param myUserId - The current user's ID (from client.userID)\n * @returns Parsed signal message object, or null if input is empty\n */\nexport function parseSignalMessage(\n value: string,\n myUserId: string,\n): SignalMessageResult | null {\n if (!value || typeof value !== 'string') return null;\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(' ');\n const number = parseInt(parts[0], 10);\n const callerId = parts[1] ?? '';\n const isMe = myUserId === callerId;\n\n let enderId = '';\n let duration = '';\n let callType: CallTypeValue | '' = '';\n let color = '';\n\n if (number === 3 || number === 6) {\n enderId = parts[2] ?? '';\n duration = parts[3] === '0' ? '' : (parts[3] ?? '');\n }\n\n let text: string;\n switch (number) {\n case 1: // AudioCallStarted\n text = isMe ? 'Calling...' : 'Incoming audio call...';\n callType = CallType.AUDIO;\n color = '#54D62C';\n break;\n case 2: // AudioCallMissed\n text = isMe ? 'Outgoing audio call' : 'You missed audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 3: // AudioCallEnded\n if (duration) {\n text = isMe ? 'Outgoing audio call' : 'Incoming audio call';\n color = '#54D62C';\n } else {\n if (enderId === myUserId) {\n text = 'You cancel audio call';\n } else {\n text = 'You missed audio call';\n }\n color = '#FF4842';\n }\n callType = CallType.AUDIO;\n break;\n case 4: // VideoCallStarted\n text = isMe ? 'Calling...' : 'Incoming video call...';\n callType = CallType.VIDEO;\n color = '#54D62C';\n break;\n case 5: // VideoCallMissed\n text = isMe ? 'Outgoing video call' : 'You missed video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n case 6: // VideoCallEnded\n if (duration) {\n text = isMe ? 'Outgoing video call' : 'Incoming video call';\n color = '#54D62C';\n } else {\n if (enderId === myUserId) {\n text = 'You cancel video call';\n } else {\n text = 'You missed video call';\n }\n color = '#FF4842';\n }\n callType = CallType.VIDEO;\n break;\n case 7: // AudioCallRejected\n text = isMe ? 'Recipient rejected audio call' : 'You rejected audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 8: // VideoCallRejected\n text = isMe ? 'Recipient rejected video call' : 'You rejected video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n case 9: // AudioCallBusy\n text = isMe ? 'Recipient was busy' : 'You missed audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 10: // VideoCallBusy\n text = isMe ? 'Recipient was busy' : 'You missed video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n default:\n text = trimmed;\n callType = '';\n color = '';\n }\n\n return { text, duration: formatDuration(duration), callType, color };\n}\n"],"mappings":"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","names":["FormData","user","hardDelete","user","WebSocket","WebSocket","CallAction","CallStatus","FRAME_TYPE","channel","ptr","module","arg0","arg1","module","result","axios","axios"]}
|
|
1
|
+
{"version":3,"sources":["../src/client.ts","../src/shims/empty.ts","../src/utils.ts","../src/channel_state.ts","../src/attachment_utils.ts","../src/channel.ts","../src/client_state.ts","../src/connection.ts","../src/token_manager.ts","../src/errors.ts","../src/types.ts","../src/events.ts","../src/wasm/ermis_call_node_wasm.js","../src/media_stream_sender.ts","../src/hevc_decoder_config.ts","../src/media_stream_receiver.ts","../src/ermis_call_node.ts","../src/auth.ts","../src/system_message.ts","../src/signal_message.ts"],"sourcesContent":["/* eslint no-unused-vars: \"off\" */\n/* global process */\n\nimport axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport https from 'https';\nimport WebSocket from 'isomorphic-ws';\n\nimport { Channel } from './channel';\nimport { ClientState } from './client_state';\nimport { StableWSConnection } from './connection';\n\nimport { TokenManager } from './token_manager';\n\nimport { isErrorResponse } from './errors';\nimport { EventSourcePolyfill } from 'event-source-polyfill';\nimport {\n addFileToFormData,\n axiosParamsSerializer,\n enrichWithUserInfo,\n ensureMembersUserInfoLoaded,\n getDirectChannelImage,\n getDirectChannelName,\n getLatestCreatedAt,\n isFunction,\n randomId,\n} from './utils';\n\nimport {\n APIErrorResponse,\n APIResponse,\n ChannelAPIResponse,\n ChannelData,\n ChannelFilters,\n ChannelSort,\n ChannelStateOptions,\n ConnectAPIResponse,\n DefaultGenerics,\n ErrorFromResponse,\n Event,\n EventHandler,\n ExtendableGenerics,\n Logger,\n QueryChannelsAPIResponse,\n SendFileAPIResponse,\n ErmisChatOptions,\n UserResponse,\n ContactResponse,\n UsersResponse,\n ContactResult,\n Contact,\n} from './types';\n\nfunction isString(x: unknown): x is string {\n return typeof x === 'string' || x instanceof String;\n}\n/**\n * The ErmisChat Client represents the connection securely established between your application\n * and the Ermis core servers. It acts as the primary access point for real-time messaging,\n * presence updates, call management, and channel querying.\n *\n * It is highly recommended to instantiate this class as a Singleton via `ErmisChat.getInstance()`.\n */\nexport class ErmisChat<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n private static _instance?: unknown | ErmisChat; // type is undefined|ErmisChat, unknown is due to TS limitations with statics\n\n /** A map of active channels currently tracked by the client, keyed by Channel ID. */\n activeChannels: {\n [key: string]: Channel<ErmisChatGenerics>;\n };\n /** The internal configured Axios instance used for REST API requests. */\n axiosInstance: AxiosInstance;\n /** The primary base URL for REST API communication. */\n baseURL?: string;\n /** The specific base URL for standard user-focused REST calls. */\n userBaseURL?: string;\n /** True when the SDK is executed inside a browser environment. */\n browser: boolean;\n cleaningIntervalRef?: NodeJS.Timeout;\n clientID?: string;\n apiKey: string;\n projectId: string;\n /** Internal mapped registry of event listeners. */\n listeners: Record<string, Array<(event: Event<ErmisChatGenerics>) => void>>;\n logger: Logger;\n /** Whether the client should automatically fetch missing messages upon unexpected disconnects. */\n recoverStateOnReconnect?: boolean;\n /** True when the SDK is executed in a NodeJS environment constraint. */\n node: boolean;\n /** Custom options passed during client initialization. */\n options: ErmisChatOptions;\n setUserPromise: ConnectAPIResponse<ErmisChatGenerics> | null;\n /** Centralized global state orchestrating user and client metadata. */\n state: ClientState<ErmisChatGenerics>;\n tokenManager: TokenManager<ErmisChatGenerics>;\n /** The globally authenticated current user object. */\n user?: UserResponse<ErmisChatGenerics>;\n userAgent?: string;\n /** The unique ID of the current authenticated user. */\n userID?: string;\n /** The configured WebSocket endpoint base URL for realtime subscriptions. */\n wsBaseURL?: string;\n /** The active WebSocket connection controller. */\n wsConnection: StableWSConnection<ErmisChatGenerics> | null;\n wsPromise: ConnectAPIResponse<ErmisChatGenerics> | null;\n /** Tracks consecutive REST API failures for exponential backoff purposes. */\n consecutiveFailures: number;\n defaultWSTimeout: number;\n\n private eventSource: EventSourcePolyfill | null = null;\n\n /**\n * Initializes a new Ermis Chat Client instance.\n *\n * @param apiKey - Your public Ermis Network API Key.\n * @param projectId - Your specific Project UUID pointing to the app config.\n * @param baseURL - The API base endpoint assigned to your project.\n * @param options - Additional connection rules and configuration options.\n */\n constructor(apiKey: string, projectId: string, baseURL: string, options?: ErmisChatOptions) {\n this.apiKey = apiKey;\n this.projectId = projectId;\n this.listeners = {};\n this.state = new ClientState<ErmisChatGenerics>();\n\n const inputOptions = options || {};\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n\n this.options = {\n withCredentials: false,\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n\n this.axiosInstance = axios.create(this.options);\n\n this.setBaseURL(baseURL);\n\n // WS connection is initialized when setUser is called\n this.wsConnection = null;\n this.wsPromise = null;\n this.setUserPromise = null;\n // keeps a reference to all the channels that are in use\n this.activeChannels = {};\n\n this.tokenManager = new TokenManager();\n this.consecutiveFailures = 0;\n this.defaultWSTimeout = 15000;\n\n this.axiosInstance.defaults.paramsSerializer = axiosParamsSerializer;\n\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.recoverStateOnReconnect = this.options.recoverStateOnReconnect;\n }\n\n /**\n * Retrieves the globally registered Singleton instance of the ErmisChat client.\n * If the instance lacks existence, it initializes a new one.\n *\n * @param key - Your public Ermis Network API Key.\n * @param projectId - Your specific Project UUID.\n * @param baseURL - The API base endpoint.\n * @param options - Connection options.\n * @returns The shared ErmisChat client instance.\n */\n public static getInstance<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n key: string,\n projectId: string,\n baseURL: string,\n options?: ErmisChatOptions,\n ): ErmisChat<ErmisChatGenerics> {\n if (!ErmisChat._instance) {\n ErmisChat._instance = new ErmisChat<ErmisChatGenerics>(key, projectId, baseURL, options);\n }\n\n return ErmisChat._instance as ErmisChat<ErmisChatGenerics>;\n }\n\n async refreshNewToken(refresh_token: string) {\n return await this.post<APIResponse>(this.userBaseURL + '/refresh_token', { refresh_token });\n }\n\n getAuthType() {\n return 'jwt';\n }\n\n setBaseURL(baseURL: string) {\n this.baseURL = baseURL;\n this.userBaseURL = this.options.userBaseURL || baseURL + '/uss/v1';\n this.wsBaseURL = this.baseURL.replace('http', 'ws').replace(':3030', ':8800');\n }\n\n async getExternalAuthToken(user: UserResponse<ErmisChatGenerics>, token: string | null) {\n const params: any = { apikey: this.apiKey, name: user.name };\n if (user.avatar) {\n params.avatar = user.avatar;\n }\n const url = this.userBaseURL + '/get_token/external_auth';\n const query = new URLSearchParams(params).toString();\n const headers: Record<string, string> = {\n 'Content-Type': 'application/json',\n };\n if (token) {\n const tokenStr = typeof token === 'string' && token.startsWith('Bearer ') ? token : `Bearer ${token}`;\n headers['Authorization'] = tokenStr;\n }\n const response = await fetch(`${url}?${query}`, {\n method: 'GET',\n headers,\n });\n if (!response.ok) {\n let errorMsg = '';\n try {\n const errorData = await response.json();\n errorMsg = errorData.message || JSON.stringify(errorData);\n } catch {\n errorMsg = await response.text();\n }\n throw new Error(errorMsg);\n }\n return await response.json();\n }\n\n /**\n * Connects a user to the Ermis network and establishes the WebSocket connection.\n * This is the primary method to authenticate your client application.\n *\n * @param user - The User object containing `id`, `name`, and optional `avatar`.\n * @param userTokenOrProvider - The JWT token or an async token provider function.\n * @param extenal_auth - Set to `true` to use your custom backend external authentication flow.\n * @returns A promise resolving to the API connection response once authenticated.\n */\n connectUser = async (\n user: UserResponse<ErmisChatGenerics>,\n userTokenOrProvider: string | null,\n extenal_auth?: boolean, // pass true if you are using external auth\n ) => {\n this.logger('info', 'client:connectUser() - started', {\n tags: ['connection', 'client'],\n });\n if (!user.id) {\n throw new Error('The \"id\" field on the user is missing');\n }\n\n // If external auth is enabled, get the token from the server\n if (extenal_auth) {\n const external_auth_token = await this.getExternalAuthToken(user, userTokenOrProvider);\n\n userTokenOrProvider = external_auth_token.token;\n user.id = external_auth_token.user_id;\n }\n\n /**\n * Calling connectUser multiple times is potentially the result of a bad integration, however,\n * If the user id remains the same we don't throw error\n */\n if (this.userID === user.id && this.setUserPromise) {\n console.warn(\n 'Consecutive calls to connectUser is detected, ideally you should only call this function once in your app.',\n );\n return this.setUserPromise;\n }\n\n if (this.userID) {\n throw new Error(\n 'Use client.disconnect() before trying to connect as a different user. connectUser was called twice.',\n );\n }\n\n if (this.node && !this.options.allowServerSideConnect) {\n console.warn(\n 'Please do not use connectUser server side. connectUser impacts MAU and concurrent connection usage and thus your bill. If you have a valid use-case, add \"allowServerSideConnect: true\" to the client options to disable this warning.',\n );\n }\n\n // we generate the client id client side\n this.userID = user.id;\n\n const setTokenPromise = this._setToken(user, userTokenOrProvider);\n this._setUser(user);\n this.state.updateUser({ id: user.id, name: user?.name || user.id, avatar: user?.avatar || '' });\n\n const wsPromise = this.openConnection();\n\n this.setUserPromise = Promise.all([setTokenPromise, wsPromise]).then(\n (result) => result[1], // We only return connection promise;\n );\n\n try {\n const result = await this.setUserPromise;\n // Call SSE after successful connect\n await this.connectToSSE();\n return result;\n } catch (err) {\n this.disconnectUser();\n throw err;\n }\n };\n\n setUser = this.connectUser;\n\n _setToken = (user: UserResponse<ErmisChatGenerics>, userTokenOrProvider: string | null) =>\n this.tokenManager.setTokenOrProvider(userTokenOrProvider, user);\n\n _setUser(user: UserResponse<ErmisChatGenerics>) {\n this.user = { ...user };\n this.userID = user.id;\n }\n\n closeConnection = async (timeout?: number) => {\n if (this.cleaningIntervalRef != null) {\n clearInterval(this.cleaningIntervalRef);\n this.cleaningIntervalRef = undefined;\n }\n\n await this.wsConnection?.disconnect(timeout);\n return Promise.resolve();\n };\n\n openConnection = async () => {\n if (!this.userID) {\n throw Error('User is not set on client, use client.connectUser instead');\n }\n\n if (this.wsConnection?.isConnecting && this.wsPromise) {\n this.logger('info', 'client:openConnection() - connection already in progress', {\n tags: ['connection', 'client'],\n });\n return this.wsPromise;\n }\n\n if (this.wsConnection?.isHealthy) {\n this.logger('info', 'client:openConnection() - openConnection called twice, healthy connection already exists', {\n tags: ['connection', 'client'],\n });\n\n return Promise.resolve();\n }\n\n this.clientID = `${this.userID}--${randomId()}`;\n this.wsPromise = this.connect();\n this._startCleaning();\n return this.wsPromise;\n };\n\n _setupConnection = this.openConnection;\n\n /**\n * Gracefully disconnects the current user, terminates the WebSocket connection,\n * cleans up listeners, and resets the client's internal references.\n *\n * @param timeout - Optional timeout in milliseconds before forcing the disconnect.\n */\n disconnectUser = async (timeout?: number) => {\n this.logger('info', 'client:disconnect() - Disconnecting the client', {\n tags: ['connection', 'client'],\n });\n\n // remove the user specific fields\n delete this.user;\n delete this.userID;\n\n const closePromise = this.closeConnection(timeout);\n\n for (const channel of Object.values(this.activeChannels)) {\n channel._disconnect();\n }\n // ensure we no longer return inactive channels\n this.activeChannels = {};\n // reset client state\n this.state = new ClientState();\n // reset token manager\n setTimeout(this.tokenManager.reset); // delay reseting to use token for disconnect calls\n\n // close the WS connection\n return closePromise;\n };\n\n disconnect = this.disconnectUser;\n\n /**\n * Attaches an event listener to the client connection.\n * Listeners can be scoped to specific event types (e.g. `message.new`) or listen to `all` events.\n *\n * @param callback - The handler invoked when the event is emitted.\n * @returns An object containing an `unsubscribe` method to detach the listener.\n */\n on(callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n /**\n * Attaches an event listener filtered by a specific event type.\n *\n * @param eventType - The specific event name to listen for (e.g., `'notification.message_new'`).\n * @param callback - The handler invoked when the event is emitted.\n * @returns An object containing an `unsubscribe` method to detach the listener.\n */\n on(eventType: string, callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<ErmisChatGenerics> | string,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<ErmisChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this.logger('info', `Attaching listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key].push(callback);\n return {\n unsubscribe: () => {\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n /**\n * Detaches a previously registered general event listener.\n * @param callback - The original handler reference to remove.\n */\n off(callback: EventHandler<ErmisChatGenerics>): void;\n /**\n * Detaches a previously registered event listener scoped to a specific event type.\n * @param eventType - The specific event name.\n * @param callback - The original handler reference to remove.\n */\n off(eventType: string, callback: EventHandler<ErmisChatGenerics>): void;\n off(callbackOrString: EventHandler<ErmisChatGenerics> | string, callbackOrNothing?: EventHandler<ErmisChatGenerics>) {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : (callbackOrString as EventHandler<ErmisChatGenerics>);\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this.logger('info', `Removing listener for ${key} event`, {\n tags: ['event', 'client'],\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger(\n 'info',\n `client: ${type} - Request - ${url}- ${JSON.stringify(data)} - ${JSON.stringify(config.params)}`,\n {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n },\n );\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown, options: unknown) {\n this.logger(\n 'error',\n `client:${type} - Error: ${JSON.stringify(error)} - url: ${url} - options: ${JSON.stringify(options)}`,\n {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n },\n );\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n await this.tokenManager.tokenReady();\n\n const requestConfig = this._enrichAxiosOptions(options);\n\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e, options);\n this.consecutiveFailures += 1;\n if (e.response) {\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('post', url, data, { params });\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n\n sendFile(\n url: string,\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<ErmisChatGenerics>,\n ) {\n const data = addFileToFormData(uri, name, contentType || 'multipart/form-data');\n if (user != null) data.append('user', JSON.stringify(user));\n\n return this.doAxiosRequest<SendFileAPIResponse>('postForm', url, data, {\n headers: data.getHeaders ? data.getHeaders() : {}, // node vs browser\n config: {\n timeout: 0,\n maxContentLength: Infinity,\n maxBodyLength: Infinity,\n },\n });\n }\n\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`ErmisChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`ErmisChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n dispatchEvent = (event: Event<ErmisChatGenerics>) => {\n if (!event.received_at) event.received_at = new Date();\n\n // If the event is channel.created, handle it asynchronously\n if (event.type === 'channel.created') {\n this._handleChannelCreatedEvent(event).then(() => {\n this._afterDispatchEvent(event);\n });\n } else {\n const postListenerCallbacks = this._handleClientEvent(event);\n\n // channel event handlers\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n }\n };\n\n _afterDispatchEvent(event: Event<ErmisChatGenerics>) {\n const postListenerCallbacks = this._handleClientEvent(event);\n\n const cid = event.cid;\n const channel = cid ? this.activeChannels[cid] : undefined;\n if (channel) {\n channel._handleChannelEvent(event);\n }\n\n this._callClientListeners(event);\n\n if (channel) {\n channel._callChannelListeners(event);\n }\n\n postListenerCallbacks.forEach((c) => c());\n }\n\n private async _handleChannelCreatedEvent(event: Event<ErmisChatGenerics>) {\n const members = event.channel?.members || [];\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this, members);\n\n // Get the latest users after updating\n const updatedUsers = Object.values(this.state.users);\n\n const enrichedMembers = enrichWithUserInfo(members, updatedUsers);\n const channelName =\n event.channel_type === 'messaging'\n ? getDirectChannelName(enrichedMembers, this.userID || '')\n : event.channel?.name;\n const channel = {\n ...event.channel,\n members: enrichedMembers,\n name: channelName,\n };\n const channelState: any = {\n channel,\n members: enrichedMembers,\n messages: [],\n pinned_messages: [],\n };\n const c = this.channel(event.channel_type || '', event.channel_id || '');\n c.data = channel;\n c._initializeState(channelState, 'latest');\n }\n\n handleEvent = (messageEvent: WebSocket.MessageEvent) => {\n // dispatch the event to the channel listeners\n const jsonString = messageEvent.data as string;\n const event = JSON.parse(jsonString) as Event<ErmisChatGenerics>;\n this.dispatchEvent(event);\n };\n\n _updateMemberWatcherReferences = (user: UserResponse<ErmisChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n if (channel?.state) {\n if (channel.state.members[user.id]) {\n channel.state.members[user.id].user = user;\n }\n if (channel.state.watchers[user.id]) {\n channel.state.watchers[user.id] = user;\n }\n if (channel.state.read[user.id]) {\n channel.state.read[user.id].user = user;\n }\n }\n }\n };\n\n _updateUserReferences = this._updateMemberWatcherReferences;\n\n _updateUserMessageReferences = (user: UserResponse<ErmisChatGenerics>) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n\n if (!channel) continue;\n\n const state = channel.state;\n\n /** update the messages from this user. */\n state?.updateUserMessages(user);\n }\n };\n\n _deleteUserMessageReference = (user: UserResponse<ErmisChatGenerics>, hardDelete = false) => {\n const refMap = this.state.userChannelReferences[user.id] || {};\n\n for (const channelID in refMap) {\n const channel = this.activeChannels[channelID];\n const state = channel.state;\n\n /** deleted the messages from this user. */\n state?.deleteUserMessages(user, hardDelete);\n }\n };\n\n _handleClientEvent(event: Event<ErmisChatGenerics>) {\n const client = this;\n const postListenerCallbacks = [];\n this.logger('info', `client:_handleClientEvent - Received event of type { ${event.type} }`, {\n tags: ['event', 'client'],\n event,\n });\n\n if (event.type === 'health.check' && event.me) {\n }\n\n if ((event.type === 'channel.deleted' || event.type === 'notification.channel_deleted') && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n\n for (const channel of Object.values(this.activeChannels)) {\n if (channel.type === 'team' && channel.state.topics?.some((t) => t.cid === event.cid)) {\n // Remove the topic with matching cid from the topics array\n channel.state.topics = channel.state.topics.filter((t) => t.cid !== event.cid);\n }\n }\n }\n if (event.type === 'notification.invite_rejected') {\n if (event.member?.user_id === this.userID && event.cid) {\n client.state.deleteAllChannelReference(event.cid);\n this.activeChannels[event.cid]?._disconnect();\n\n postListenerCallbacks.push(() => {\n if (!event.cid) return;\n\n delete this.activeChannels[event.cid];\n });\n }\n }\n if (event.type === 'notification.invite_accepted') {\n //TODO handle channel list and invited channels here\n }\n\n if (event.type === 'member.added') {\n if (event.member?.user_id === this.userID) {\n const c = this.channel(event.channel_type || '', event.channel_id || '');\n // Gọi watch để lấy đầy đủ thông tin channel từ server\n c.watch().catch((err) => {\n this.logger('error', 'Failed to watch channel after member.added', { err, event });\n });\n }\n }\n\n if (event.type === 'connection.recovered') {\n postListenerCallbacks.push(() => {\n // Auto-resend offline failed messages\n Object.values(this.activeChannels).forEach((channel) => {\n if (!channel.state?.messages) return;\n const offlineFailedMsgs = channel.state.messages.filter(\n (m) =>\n m.status === 'failed_offline' &&\n m.user?.id === this.userID &&\n (!m.attachments || m.attachments.length === 0),\n );\n offlineFailedMsgs.forEach((msg) => {\n if (msg.id) {\n channel.retryMessage(msg.id).catch((err) => {\n this.logger('error', `Failed to auto-resend offline message ${msg.id}`, {\n tags: ['offline', 'retry'],\n err,\n });\n });\n }\n });\n });\n });\n }\n\n return postListenerCallbacks;\n }\n\n _callClientListeners = (event: Event<ErmisChatGenerics>) => {\n const client = this;\n // gather and call the listeners\n const listeners: Array<(event: Event<ErmisChatGenerics>) => void> = [];\n if (client.listeners.all) {\n listeners.push(...client.listeners.all);\n }\n if (client.listeners[event.type]) {\n listeners.push(...client.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n listener(event);\n }\n };\n\n recoverState = async () => {\n this.logger('info', 'client:recoverState() - Start of recoverState', {\n tags: ['connection'],\n });\n\n const cids = Object.keys(this.activeChannels);\n if (cids.length && this.recoverStateOnReconnect) {\n this.logger('info', `client:recoverState() - Start the querying of ${cids.length} channels`, {\n tags: ['connection', 'client'],\n });\n\n const filter: ChannelFilters = {\n type: ['messaging', 'team'],\n };\n const sort: [] = [];\n const options = {\n message_limit: 25,\n };\n\n await this.queryChannels(filter, sort, options);\n\n this.logger('info', 'client:recoverState() - Querying channels finished', { tags: ['connection', 'client'] });\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<ErmisChatGenerics>);\n } else {\n this.dispatchEvent({\n type: 'connection.recovered',\n } as Event<ErmisChatGenerics>);\n }\n\n this.wsPromise = Promise.resolve();\n this.setUserPromise = Promise.resolve();\n };\n\n async connect() {\n if (!this.userID || !this.user) {\n throw Error('Call connectUser before starting the connection');\n }\n if (!this.wsBaseURL) {\n throw Error('Websocket base url not set');\n }\n if (!this.clientID) {\n throw Error('clientID is not set');\n }\n\n // if (!this.wsConnection && (this.options.warmUp || this.options.enableInsights)) {\n // this._sayHi();\n // }\n // The StableWSConnection handles all the reconnection logic.\n if (this.options.wsConnection && this.node) {\n // Intentionally avoiding adding ts generics on wsConnection in options since its only useful for unit test purpose.\n (this.options.wsConnection as unknown as StableWSConnection<ErmisChatGenerics>).setClient(this);\n this.wsConnection = this.options.wsConnection as unknown as StableWSConnection<ErmisChatGenerics>;\n } else {\n this.wsConnection = new StableWSConnection<ErmisChatGenerics>({\n client: this,\n });\n }\n\n try {\n return await this.wsConnection.connect(this.defaultWSTimeout);\n } catch (err: any) {\n throw err;\n }\n }\n public async connectToSSE(onCallBack?: (data: any) => void): Promise<void> {\n if (this.eventSource) {\n this.logger('info', 'client:connectToSSE() - SSE connection already established', {});\n return;\n }\n let token = this._getToken();\n\n if (!token?.startsWith('Bearer ')) {\n token = `Bearer ${token}`;\n }\n const headers = {\n method: 'GET',\n Authorization: token,\n };\n this.eventSource = new EventSourcePolyfill(this.userBaseURL + '/sse/subscribe', {\n headers,\n heartbeatTimeout: 60000,\n });\n this.eventSource.onopen = () => {\n this.logger('info', 'client:connectToSSE() - SSE connection established', {});\n };\n this.eventSource.onmessage = (event) => {\n const data = JSON.parse(event.data);\n\n this.logger('info', `client:connectToSSE() - SSE message received event : ${JSON.stringify(data)}`, { event });\n\n if (data.type === 'AccountUserChainProjects') {\n let user: UserResponse = {\n name: data.name,\n id: data.id,\n avatar: data.avatar,\n about_me: data.about_me,\n project_id: data.project_id,\n };\n\n if (this.user?.id === user.id) {\n this.user = { ...this.user, ...user };\n }\n\n this.state.updateUser(user);\n\n const userInfo = {\n id: user.id,\n name: user.name ? user.name : user.id,\n avatar: user?.avatar || '',\n };\n\n this._updateMemberWatcherReferences(userInfo);\n this._updateUserMessageReferences(userInfo);\n\n Object.values(this.activeChannels).forEach((channel) => {\n if (channel.data?.type === 'messaging' && Object.keys(channel.state.members).length === 2) {\n const otherMember = Object.values(channel.state.members).find((member) => member.user?.id !== this.userID);\n if (otherMember && otherMember.user?.id === user.id) {\n // Cập nhật tên và avatar channel theo user vừa đổi thông tin\n channel.data.name = user.name || user.id;\n channel.data.image = user.avatar || '';\n }\n }\n });\n\n if (onCallBack) {\n onCallBack(data);\n }\n }\n };\n this.eventSource.onerror = (event: any) => {\n this.logger('error', `client:connectToSSE() - SSE connection error : ${JSON.stringify(event.data)} `, { event });\n if (event.status === 401) {\n this.logger('error', 'client:connectToSSE() - Unauthorized (401). Aborting the connection.', {});\n this.disconnectFromSSE();\n } else if (\n this.eventSource?.readyState === EventSourcePolyfill.CLOSED ||\n this.eventSource?.readyState === EventSourcePolyfill.CONNECTING\n ) {\n this.eventSource.close();\n setTimeout(() => {\n this.logger('info', 'client:connectToSSE() - Reconnecting to SSE', {});\n this.connectToSSE(onCallBack);\n }, 3000);\n }\n };\n }\n public async disconnectFromSSE(): Promise<void> {\n if (this.eventSource) {\n this.eventSource.close();\n this.eventSource = null;\n this.logger('info', 'client:disconnectFromSSE() - SSE connection closed', {});\n } else {\n this.logger('info', 'client:disconnectFromSSE() - SSE connection already closed', {});\n }\n }\n\n async queryUsers(page_size?: string, page?: number): Promise<UsersResponse> {\n const defaultOptions = {\n presence: false,\n };\n\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n let project_id = this.projectId;\n // Return a list of users\n const data = await this.get<UsersResponse>(this.userBaseURL + '/users', {\n project_id,\n page,\n page_size,\n });\n\n this.state.updateUsers(data.data);\n\n return data;\n }\n\n async queryUser(user_id: string): Promise<UserResponse<ErmisChatGenerics>> {\n const project_id = this.projectId;\n\n const userResponse = await this.get<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/' + user_id, {\n project_id,\n });\n\n this.state.updateUser(userResponse);\n return userResponse;\n }\n\n async getBatchUsers(users: string[], page?: number, page_size?: number) {\n let project_id = this.projectId;\n\n const usersRepsonse = await this.post<UsersResponse>(\n this.userBaseURL + '/users/batch?page=1&page_size=10000',\n { users, project_id },\n { page, page_size },\n );\n\n this.state.updateUsers(usersRepsonse.data);\n\n return usersRepsonse.data || [];\n }\n\n async searchUsers(page: number, page_size: number, name?: string): Promise<UsersResponse> {\n let project_id = this.projectId;\n\n const usersResponse = await this.post<UsersResponse>(this.userBaseURL + '/users/search', undefined, {\n page,\n page_size,\n name,\n project_id,\n });\n\n // this.state.updateUsers(usersResponse.data);\n\n return usersResponse;\n }\n\n async queryContacts(): Promise<ContactResult> {\n let project_id = this.projectId;\n const contactResponse = await this.post<ContactResponse>(this.baseURL + '/contacts/list', { project_id });\n const userIds = contactResponse.project_id_user_ids[project_id];\n const contact_users: UserResponse<ErmisChatGenerics>[] = [];\n const block_users: UserResponse<ErmisChatGenerics>[] = [];\n\n userIds.forEach((contact: Contact) => {\n const userID = contact.other_id;\n const state_user = this.state.users[userID];\n const user = state_user ? state_user : { id: userID };\n switch (contact.relation_status) {\n case 'blocked':\n block_users.push(user);\n break;\n case 'normal':\n contact_users.push(user);\n break;\n default:\n }\n });\n\n return {\n contact_users,\n block_users,\n };\n }\n\n _updateProjectID(project_id: string) {\n this.projectId = project_id;\n }\n\n async uploadFile(file: File) {\n const formData = new FormData();\n formData.append('avatar', file);\n let response = await this.post<{ avatar: string }>(this.userBaseURL + '/users/upload', formData, {\n headers: {\n 'Content-Type': 'multipart/form-data',\n },\n });\n if (this.user) {\n this.user.avatar = response.avatar;\n const new_user = { ...this.user, avatar: response.avatar };\n this.state.updateUser(new_user);\n }\n\n return response;\n }\n async updateProfile(name: string, about_me: string) {\n let body = {\n name,\n about_me,\n };\n let response = await this.patch<UserResponse<ErmisChatGenerics>>(this.userBaseURL + '/users/update', body);\n this.user = response;\n this.state.updateUser(response);\n return response;\n }\n\n /**\n * Queries the API for a list of channels based on provided search filters and sort conditions.\n * Also hydrates these channels into the local SDK state memory.\n *\n * @param filterConditions - Specific criteria to filter channels (e.g. `{ type: 'messaging', members: { $in: ['user1'] } }`).\n * @param sort - The sorting hierarchy applied to the channel results.\n * @param options - Pagination and message limit parameters.\n * @param stateOptions - Defines whether to skip state initialization or offline usage.\n * @returns An array of hydrated and locally manageable `Channel` objects.\n */\n async queryChannels(\n filterConditions: ChannelFilters,\n sort: ChannelSort = [],\n options: { message_limit?: number } = {},\n stateOptions: ChannelStateOptions = {},\n ) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.wsPromise;\n\n let project_id = this.projectId;\n\n // Return a list of channels\n const payload = {\n filter_conditions: { ...filterConditions, project_id },\n sort,\n ...options,\n };\n\n const data = await this.post<QueryChannelsAPIResponse<ErmisChatGenerics>>(this.baseURL + '/channels', payload);\n\n // Sort channels by latest message created_at (including topics if present)\n data.channels.sort((a, b) => {\n // Get latest message created_at in channel a\n let aLatest = getLatestCreatedAt(a.messages);\n\n // If channel a has topics, check messages in topics\n if (a.channel.type === 'team' && Array.isArray(a.topics)) {\n for (const topic of a.topics) {\n aLatest = Math.max(aLatest, getLatestCreatedAt(topic.messages));\n }\n }\n\n // Get latest message created_at in channel b\n let bLatest = getLatestCreatedAt(b.messages);\n\n // If channel b has topics, check messages in topics\n if (b.channel.type === 'team' && Array.isArray(b.topics)) {\n for (const topic of b.topics) {\n bLatest = Math.max(bLatest, getLatestCreatedAt(topic.messages));\n }\n }\n\n // Descending order (newest first)\n return bLatest - aLatest;\n });\n\n const memberIds =\n Array.from(\n new Set(data.channels.flatMap((c) => (c.channel.members || []).map((member: any) => member.user.id))),\n ) || [];\n\n const membersInfo = filterConditions.parent_cid\n ? Object.values(this.state.users)\n : await this.getBatchUsers(memberIds);\n data.channels.forEach((c) => {\n c.channel.members = enrichWithUserInfo(c.channel.members, membersInfo);\n c.messages = enrichWithUserInfo(c.messages, membersInfo);\n c.read = enrichWithUserInfo(c.read || [], membersInfo);\n c.channel.name =\n c.channel.type === 'messaging' ? getDirectChannelName(c.channel.members, this.userID || '') : c.channel.name;\n c.channel.image =\n c.channel.type === 'messaging' ? getDirectChannelImage(c.channel.members, this.userID || '') : c.channel.image;\n\n if (c.channel.type === 'team' && Array.isArray(c.topics)) {\n c.topics.sort((a, b) => {\n const aLatest = getLatestCreatedAt(a.messages);\n const bLatest = getLatestCreatedAt(b.messages);\n return bLatest - aLatest;\n });\n }\n\n if (c.pinned_messages) {\n c.pinned_messages = enrichWithUserInfo(c.pinned_messages || [], membersInfo);\n }\n });\n\n const { channels, userIds } = this.hydrateChannels(data.channels, stateOptions);\n\n // if (userIds.length > 0) {\n // await this.getBatchUsers(userIds);\n // }\n\n console.log('---channels---', channels);\n\n return channels;\n }\n\n hydrateChannels(\n channelsFromApi: ChannelAPIResponse<ErmisChatGenerics>[] = [],\n stateOptions: ChannelStateOptions = {},\n ) {\n const { skipInitialization, offlineMode = false } = stateOptions;\n\n const channels: Channel<ErmisChatGenerics>[] = [];\n const userIds: string[] = [];\n for (const channelState of channelsFromApi) {\n const c = this.channel(channelState.channel.type, channelState.channel.id);\n c.data = { ...channelState.channel, is_pinned: channelState.is_pinned || false };\n c.offlineMode = offlineMode;\n c.initialized = !offlineMode;\n\n if (skipInitialization === undefined) {\n c._initializeState(channelState, 'latest', (id) => {\n if (!userIds.includes(id)) {\n userIds.push(id);\n }\n });\n } else if (!skipInitialization.includes(channelState.channel.id)) {\n c.state.clearMessages();\n c._initializeState(channelState, 'latest', (id) => {\n if (!userIds.includes(id)) {\n userIds.push(id);\n }\n });\n }\n\n channels.push(c);\n }\n\n // const sortedChannels = channels.sort((a: any, b: any) => {\n // const aTime = a.state.last_message_at\n // ? new Date(a.state.last_message_at).getTime()\n // : a.data.created_at\n // ? new Date(a.data.created_at).getTime()\n // : 0;\n // const bTime = b.state.last_message_at\n // ? new Date(b.state.last_message_at).getTime()\n // : b.data.created_at\n // ? new Date(b.data.created_at).getTime()\n // : 0;\n // return bTime - aTime; // Descending order\n // });\n\n // ensure we have the users for all the channels we just added\n\n return { channels, userIds };\n }\n\n async searchPublicChannel(search_term: string, offset = 0, limit = 25) {\n let project_id = this.projectId;\n\n return await this.post<APIResponse>(this.baseURL + `/channels/public/search`, {\n project_id,\n search_term,\n limit: limit,\n offset: offset,\n });\n }\n\n async pinChannel(channelType: string, channelId: string) {\n return await this.post<APIResponse>(this.baseURL + `/channels/${channelType}/${channelId}/pin`);\n }\n\n async unpinChannel(channelType: string, channelId: string) {\n return await this.post<APIResponse>(this.baseURL + `/channels/${channelType}/${channelId}/unpin`);\n }\n\n /**\n * Creates or instantiates an interactive `Channel` object locally based on type and custom data.\n * This does NOT immediately ping the API unless `channel.watch()` or `channel.create()` is subsequently called.\n *\n * @param type - The strict channel type descriptor (e.g., `'messaging'`, `'team'`, `'livestream'`).\n * @param custom - Initial metadata or specific members to include in the channel.\n * @returns A newly instantiated `Channel` object.\n */\n channel(type: string, custom?: ChannelData<ErmisChatGenerics>): Channel<ErmisChatGenerics>;\n /**\n * Creates or instantiates an interactive `Channel` object locally using a specific ID.\n *\n * @param type - The strict channel type descriptor.\n * @param id - The unique identifer (UUID / slug) for the channel.\n * @param custom - Initial metadata or specific members to include in the channel.\n * @returns A newly instantiated `Channel` object.\n */\n channel(type: string, id: string, custom?: ChannelData<ErmisChatGenerics>): Channel<ErmisChatGenerics>;\n channel(\n channelType: string,\n channelIDOrCustom?: string | ChannelData<ErmisChatGenerics>,\n custom?: ChannelData<ErmisChatGenerics>,\n ): Channel<ErmisChatGenerics> {\n if (!this.userID) {\n throw Error('Call connectUser before creating a channel');\n }\n\n if (~channelType.indexOf(':')) {\n throw Error(`Invalid channel group ${channelType}, can't contain the : character`);\n }\n\n let channelID: string | undefined = undefined;\n let customData = custom || ({} as ChannelData<ErmisChatGenerics>);\n\n if (typeof channelIDOrCustom === 'string') {\n channelID = channelIDOrCustom;\n } else if (typeof channelIDOrCustom === 'object' && channelIDOrCustom !== null) {\n customData = channelIDOrCustom as ChannelData<ErmisChatGenerics>;\n }\n\n return this.getChannelById(channelType, channelID, customData);\n }\n\n getChannelById = (channelType: string, channelID: string | undefined, custom: ChannelData<ErmisChatGenerics>) => {\n const cid = `${channelType}:${channelID || ''}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = custom;\n channel._data = custom;\n }\n return channel;\n }\n const channel = new Channel<ErmisChatGenerics>(this, channelType, channelID, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n getChannel = (channelType: string, custom: ChannelData<ErmisChatGenerics>) => {\n const uuid = randomId();\n const id = `${this.projectId}:${uuid}`;\n // only allow 1 channel object per cid\n const cid = `${channelType}:${id}`;\n if (cid in this.activeChannels && !this.activeChannels[cid].disconnected) {\n const channel = this.activeChannels[cid];\n if (Object.keys(custom).length > 0) {\n channel.data = custom;\n channel._data = custom;\n }\n return channel;\n }\n const channel = new Channel<ErmisChatGenerics>(this, channelType, id, custom);\n this.activeChannels[channel.cid] = channel;\n\n return channel;\n };\n\n _normalizeExpiration(timeoutOrExpirationDate?: null | number | string | Date) {\n let pinExpires: null | string = null;\n if (typeof timeoutOrExpirationDate === 'number') {\n const now = new Date();\n now.setSeconds(now.getSeconds() + timeoutOrExpirationDate);\n pinExpires = now.toISOString();\n } else if (isString(timeoutOrExpirationDate)) {\n pinExpires = timeoutOrExpirationDate;\n } else if (timeoutOrExpirationDate instanceof Date) {\n pinExpires = timeoutOrExpirationDate.toISOString();\n }\n return pinExpires;\n }\n\n getUserAgent() {\n return (\n this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n let token = this._getToken();\n\n if (!token?.startsWith('Bearer ')) {\n token = `Bearer ${token}`;\n }\n\n const authorization = token ? { Authorization: token } : undefined;\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n const {\n params: axiosRequestConfigParams,\n headers: axiosRequestConfigHeaders,\n ...axiosRequestConfigRest\n } = this.options.axiosRequestConfig || {};\n\n let user_service_params = {\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n };\n\n return {\n params: user_service_params,\n headers: {\n ...authorization,\n 'stream-auth-type': this.getAuthType(),\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n _getToken() {\n if (!this.tokenManager) return null;\n\n return this.tokenManager.getToken();\n }\n\n _startCleaning() {\n const that = this;\n if (this.cleaningIntervalRef != null) {\n return;\n }\n this.cleaningIntervalRef = setInterval(() => {\n // call clean on the channel, used for calling the stop.typing event etc.\n for (const channel of Object.values(that.activeChannels)) {\n channel.clean();\n }\n }, 500);\n }\n\n _buildWSPayload = (client_request_id?: string) => {\n return JSON.stringify({\n user_id: this.userID,\n user_details: this.user,\n client_request_id,\n });\n };\n}\n","export default null;\n","import FormData from 'form-data';\nimport { ExtendableGenerics, DefaultGenerics, MessageResponse, FormatMessageResponse, ForwardMessage } from './types';\nimport { AxiosRequestConfig } from 'axios';\nimport { ErmisChat } from './client';\n\n/**\n * logChatPromiseExecution - utility function for logging the execution of a promise..\n * use this when you want to run the promise and handle errors by logging a warning\n *\n * @param {Promise<T>} promise The promise you want to run and log\n * @param {string} name A descriptive name of what the promise does for log output\n *\n */\nexport function logChatPromiseExecution<T>(promise: Promise<T>, name: string) {\n promise.then().catch((error) => {\n console.warn(`failed to do ${name}, ran into error: `, error);\n });\n}\n\nexport const sleep = (m: number): Promise<void> => new Promise((r) => setTimeout(r, m));\n\nexport function isFunction<T>(value: Function | T): value is Function {\n return (\n value &&\n (Object.prototype.toString.call(value) === '[object Function]' ||\n 'function' === typeof value ||\n value instanceof Function)\n );\n}\n\nexport const chatCodes = {\n TOKEN_EXPIRED: 40,\n WS_CLOSED_SUCCESS: 1000,\n};\n\nfunction isReadableStream(obj: unknown): obj is NodeJS.ReadStream {\n return (\n obj !== null &&\n typeof obj === 'object' &&\n ((obj as NodeJS.ReadStream).readable || typeof (obj as NodeJS.ReadStream)._read === 'function')\n );\n}\n\nfunction isBuffer(obj: unknown): obj is Buffer {\n return (\n obj != null &&\n (obj as Buffer).constructor != null &&\n // @ts-expect-error\n typeof obj.constructor.isBuffer === 'function' &&\n // @ts-expect-error\n obj.constructor.isBuffer(obj)\n );\n}\n\nfunction isFileWebAPI(uri: unknown): uri is File {\n return typeof window !== 'undefined' && 'File' in window && uri instanceof File;\n}\n\nfunction isBlobWebAPI(uri: unknown): uri is Blob {\n return typeof window !== 'undefined' && 'Blob' in window && uri instanceof Blob;\n}\n\nexport function addFileToFormData(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n) {\n const data = new FormData();\n\n if (isReadableStream(uri) || isBuffer(uri) || isFileWebAPI(uri) || isBlobWebAPI(uri)) {\n if (name) data.append('file', uri, name);\n else data.append('file', uri);\n } else {\n data.append('file', {\n uri,\n name: name || (uri as string).split('/').reverse()[0],\n contentType: contentType || undefined,\n type: contentType || undefined,\n });\n }\n\n return data;\n}\n\n\n/**\n * retryInterval - A retry interval which increases acc to number of failures\n *\n * @return {number} Duration to wait in milliseconds\n */\nexport function retryInterval(numberOfFailures: number) {\n // try to reconnect in 0.25-25 seconds (random to spread out the load from failures)\n const max = Math.min(500 + numberOfFailures * 2000, 25000);\n const min = Math.min(Math.max(250, (numberOfFailures - 1) * 2000), 25000);\n return Math.floor(Math.random() * (max - min) + min);\n}\n\nexport function randomId() {\n return generateUUIDv4();\n}\n\nfunction hex(bytes: Uint8Array): string {\n let s = '';\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i].toString(16).padStart(2, '0');\n }\n return s;\n}\n\n// https://tools.ietf.org/html/rfc4122\nexport function generateUUIDv4() {\n const bytes = getRandomBytes(16);\n bytes[6] = (bytes[6] & 0x0f) | 0x40; // version\n bytes[8] = (bytes[8] & 0xbf) | 0x80; // variant\n\n return (\n hex(bytes.subarray(0, 4)) +\n '-' +\n hex(bytes.subarray(4, 6)) +\n '-' +\n hex(bytes.subarray(6, 8)) +\n '-' +\n hex(bytes.subarray(8, 10)) +\n '-' +\n hex(bytes.subarray(10, 16))\n );\n}\n\nfunction getRandomValuesWithMathRandom(bytes: Uint8Array): void {\n const max = Math.pow(2, (8 * bytes.byteLength) / bytes.length);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = Math.random() * max;\n }\n}\ndeclare const msCrypto: Crypto;\n\nconst getRandomValues = (() => {\n if (typeof crypto !== 'undefined' && typeof crypto?.getRandomValues !== 'undefined') {\n return crypto.getRandomValues.bind(crypto);\n } else if (typeof msCrypto !== 'undefined') {\n return msCrypto.getRandomValues.bind(msCrypto);\n } else {\n return getRandomValuesWithMathRandom;\n }\n})();\n\nfunction getRandomBytes(length: number): Uint8Array {\n const bytes = new Uint8Array(length);\n getRandomValues(bytes);\n return bytes;\n}\n\n\n\n\n\n/**\n * listenForConnectionChanges - Adds an event listener fired on browser going online or offline\n */\nexport function addConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.addEventListener) {\n window.addEventListener('offline', cb);\n window.addEventListener('online', cb);\n }\n}\n\nexport function removeConnectionEventListeners(cb: (e: Event) => void) {\n if (typeof window !== 'undefined' && window.removeEventListener) {\n window.removeEventListener('offline', cb);\n window.removeEventListener('online', cb);\n }\n}\n\nexport const axiosParamsSerializer: AxiosRequestConfig['paramsSerializer'] = (params) => {\n const newParams = [];\n for (const k in params) {\n // Ermis backend doesn't treat \"undefined\" value same as value not being present.\n // So, we need to skip the undefined values.\n if (params[k] === undefined) continue;\n\n if (Array.isArray(params[k]) || typeof params[k] === 'object') {\n newParams.push(`${k}=${encodeURIComponent(JSON.stringify(params[k]))}`);\n } else {\n newParams.push(`${k}=${encodeURIComponent(params[k])}`);\n }\n }\n\n return newParams.join('&');\n};\n\n/**\n * formatMessage - Takes the message object. Parses the dates, sets __html\n * and sets the status to received if missing. Returns a message object\n *\n * @param {MessageResponse<ErmisChatGenerics>} message a message object\n *\n */\nexport function formatMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: MessageResponse<ErmisChatGenerics>,\n): FormatMessageResponse<ErmisChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the date..\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : new Date(),\n status: message.status || 'received',\n };\n}\n\nexport function addToMessageList<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n messages: Array<FormatMessageResponse<ErmisChatGenerics>>,\n message: FormatMessageResponse<ErmisChatGenerics>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n) {\n const addMessageToList = addIfDoesNotExist || timestampChanged;\n let messageArr = messages;\n\n // if created_at has changed, message should be filtered and re-inserted in correct order\n // slow op but usually this only happens for a message inserted to state before actual response with correct timestamp\n if (timestampChanged) {\n messageArr = messageArr.filter((msg) => !(msg.id && message.id === msg.id));\n }\n\n // Get array length after filtering\n const messageArrayLength = messageArr.length;\n\n // for empty list just concat and return unless it's an update or deletion\n if (messageArrayLength === 0 && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageArrayLength === 0) {\n return [...messageArr];\n }\n\n if (sortBy === 'pinned_at') {\n return messageArr.concat(message);\n }\n\n const messageTime = (message[sortBy] as Date).getTime();\n const messageIsNewest = (messageArr[messageArrayLength - 1][sortBy] as Date).getTime() < messageTime;\n\n // if message is newer than last item in the list concat and return unless it's an update or deletion\n if (messageIsNewest && addMessageToList) {\n return messageArr.concat(message);\n } else if (messageIsNewest) {\n return [...messageArr];\n }\n\n // find the closest index to push the new message\n let left = 0;\n let middle = 0;\n let right = messageArrayLength - 1;\n while (left <= right) {\n middle = Math.floor((right + left) / 2);\n if ((messageArr[middle][sortBy] as Date).getTime() <= messageTime) left = middle + 1;\n else right = middle - 1;\n }\n\n // message already exists and not filtered due to timestampChanged, update and return\n if (!timestampChanged && message.id) {\n if (messageArr[left] && message.id === messageArr[left].id) {\n messageArr[left] = message;\n return [...messageArr];\n }\n\n if (messageArr[left - 1] && message.id === messageArr[left - 1].id) {\n messageArr[left - 1] = message;\n return [...messageArr];\n }\n }\n\n // Do not add updated or deleted messages to the list if they do not already exist\n // or have a timestamp change.\n if (addMessageToList) {\n messageArr.splice(left, 0, message);\n }\n\n // Remove duplicate messages by ID\n const map = new Map();\n const uniqueMessages = [];\n\n for (const msg of messageArr) {\n if (!map.has(msg.id)) {\n map.set(msg.id, true);\n uniqueMessages.push(msg);\n }\n }\n return uniqueMessages;\n}\n\nexport const enrichWithUserInfo = (items: any[], users: any[]) => {\n if (items.length === 0) return [];\n\n if (users.length === 0) {\n return items.map((item) => {\n item.user = { id: item.user?.id, name: item.user?.id, avatar: '' };\n return item;\n });\n }\n\n return items.map((item) => {\n const userId = item.user?.id;\n const lastestReactionMsg = item?.latest_reactions;\n const quotedMsg = item?.quoted_message;\n const user = users.find((u) => u.id === userId);\n if (user) {\n item.user = { id: user.id, name: user.name || user.id, avatar: user.avatar || '' };\n }\n\n if (lastestReactionMsg) {\n item.latest_reactions = lastestReactionMsg.map((reaction: any) => {\n const reactionUser = users.find((u) => u.id === reaction.user_id);\n return {\n ...reaction,\n user: {\n id: reactionUser?.id || reaction.user_id,\n name: reactionUser?.name || reaction.user_id,\n avatar: reactionUser?.avatar || '',\n },\n };\n });\n }\n\n if (quotedMsg) {\n const quotedUser = users.find((u) => u.id === quotedMsg.user?.id);\n item.quoted_message.user = {\n id: quotedUser?.id || quotedMsg.user?.id,\n name: quotedUser?.name || quotedMsg.user?.id,\n avatar: quotedUser?.avatar || '',\n };\n }\n\n return item;\n });\n};\n\nexport const getUserInfo = (id: string, users: any[]) => {\n if (users.length === 0) {\n return {\n id,\n name: id,\n avatar: '',\n };\n }\n\n const user = users.find((u) => u.id === id);\n return {\n id,\n name: user?.name || id,\n avatar: user?.avatar || '',\n };\n};\n\nexport const getDirectChannelName = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return 'Empty channel';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.name || otherMember.user.id;\n }\n return 'Empty channel';\n};\n\nexport const getDirectChannelImage = (members: any[], currentUserId: string) => {\n if (members.length === 0) {\n return '';\n }\n\n const otherMember = members.find((member) => member.user.id !== currentUserId);\n if (otherMember) {\n return otherMember.user.avatar || '';\n }\n return '';\n};\n\n/**\n * Ensure all members' user info are loaded in state.users.\n * @param client ErmisChat client instance\n * @param members Array of channel members (each member must have user?.id)\n */\nexport async function ensureMembersUserInfoLoaded<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n client: ErmisChat<ErmisChatGenerics>,\n members: any[],\n) {\n // Get all memberIds\n const memberIds = (members || []).map((m: any) => m.user?.id).filter((id: string | undefined) => !!id);\n\n // Filter out ids that do not exist in users\n const users = client.state.users;\n const missingUserIds = memberIds.filter((id: string) => !users[id]);\n\n // If there are users missing, fetch and update them into state\n if (missingUserIds.length > 0) {\n await client.getBatchUsers(missingUserIds);\n }\n}\n\nexport const getLatestCreatedAt = (messages: any[] = []) =>\n messages.length > 0 ? Math.max(...messages.map((msg) => new Date(msg.created_at).getTime())) : 0;\n\nexport const createPacketWithHeader = (\n data: ArrayBuffer | null,\n timestamp: number | null,\n type: string,\n configMsg: any,\n): Uint8Array => {\n let HEADER_SIZE: number;\n let payload: Uint8Array;\n\n // Config messages\n if (['videoConfig', 'audioConfig', 'transciverState'].includes(type) && configMsg) {\n HEADER_SIZE = 1;\n const jsonString = JSON.stringify(configMsg);\n const encoder = new TextEncoder();\n payload = encoder.encode(jsonString);\n } else if (type === 'connected') {\n HEADER_SIZE = 1;\n payload = new Uint8Array(0);\n } else {\n // Data packets\n // HEADER_SIZE = 5;\n HEADER_SIZE = 9;\n payload = new Uint8Array(data!);\n }\n\n const packet = new Uint8Array(HEADER_SIZE + payload.byteLength);\n\n let typeCode: number = 0;\n switch (type) {\n case 'videoConfig':\n typeCode = 0;\n break;\n case 'audioConfig':\n typeCode = 1;\n break;\n case 'video-key':\n typeCode = 2;\n break;\n case 'video-delta':\n typeCode = 3;\n break;\n case 'audio':\n typeCode = 4;\n break;\n case 'connected':\n typeCode = 6;\n break;\n case 'transciverState':\n typeCode = 7;\n break;\n }\n\n // Byte 0: Type code\n packet[0] = typeCode;\n\n // Byte 1-8: Timestamp\n if (timestamp !== null) {\n const view = new DataView(packet.buffer);\n // view.setUint32(1, timestamp, false); // Little-endian = false (Big-endian)\n view.setBigUint64(1, BigInt(timestamp), false);\n }\n\n packet.set(payload, HEADER_SIZE);\n\n return packet;\n};\n\nexport const base64Encode = (arrayBuffer: ArrayBuffer): string => {\n let binary = '';\n const bytes = new Uint8Array(arrayBuffer);\n const len = bytes.byteLength;\n for (let i = 0; i < len; i++) {\n binary += String.fromCharCode(bytes[i]);\n }\n return btoa(binary);\n};\n\nexport const replaceCodecNumber = (input: string): string => {\n const map: Record<string, string> = {\n '2048': '123',\n '4096': '153',\n '8192': '156',\n '16384': '183',\n '32768': '186',\n };\n\n // Regex để tìm các key\n const regex = /2048|4096|8192|16384|32768/g;\n\n // Kiểm tra: Nếu input KHÔNG match bất kỳ số nào trong regex\n // thì trả về chuỗi mặc định\n if (!input.match(regex)) {\n return 'hev1.1.6.L123.B0';\n }\n\n // Nếu có match, thực hiện thay thế\n return input.replace(regex, (match) => map[match]);\n};\n\nexport const createForwardMessagePayload = <ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics>(\n message: FormatMessageResponse<ErmisChatGenerics>,\n targetCid: string,\n activeCid: string,\n): ForwardMessage<ErmisChatGenerics> => {\n const forwardPayload: ForwardMessage<ErmisChatGenerics> = {\n cid: targetCid,\n forward_cid: activeCid,\n forward_message_id: message.id as string,\n };\n\n if (\n message.sticker_url &&\n (!message.text || message.text === '') &&\n (!message.attachments || (Array.isArray(message.attachments) && message.attachments.length === 0))\n ) {\n forwardPayload.sticker_url = message.sticker_url as string;\n forwardPayload.text = message.text;\n } else {\n forwardPayload.text = message.text || '';\n if (message.attachments && message.attachments.length > 0) {\n forwardPayload.attachments = message.attachments.filter((item: any) => item.type !== 'linkPreview');\n }\n }\n\n return forwardPayload;\n};\n","import { Channel } from './channel';\nimport {\n ChannelMemberResponse,\n ChannelMembership,\n FormatMessageResponse,\n Event,\n ExtendableGenerics,\n DefaultGenerics,\n MessageSetType,\n MessageResponse,\n ReactionResponse,\n UserResponse,\n} from './types';\nimport { addToMessageList } from './utils';\n\ntype ChannelReadStatus<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Record<\n string,\n {\n last_read: Date;\n unread_messages: number;\n user: UserResponse<ErmisChatGenerics>;\n last_read_message_id?: string;\n last_send?: string;\n }\n>;\n\n/**\n * ChannelState - A container class for the channel state.\n * This class synchronously binds to a `Channel` and holds the single source of truth for\n * messages, read status, watchers, and typing indicators locally on the client.\n */\nexport class ChannelState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _channel: Channel<ErmisChatGenerics>;\n /** The current count of users actively watching (having an open WebSocket) this channel. */\n watcher_count: number;\n /** A dictionary of active typing events gracefully keyed by the user's ID. */\n typing: Record<string, Event<ErmisChatGenerics>>;\n /** A dictionary of read states mapped per user's ID detailing the last viewed message. */\n read: ChannelReadStatus<ErmisChatGenerics>;\n /** The locally cached array of pinned messages across the channel. */\n pinnedMessages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;\n /** A directory of users actively watching the channel, keyed by User ID. */\n watchers: Record<string, UserResponse<ErmisChatGenerics>>;\n /** A comprehensive directory mapping user IDs to their member status in the channel. */\n members: Record<string, ChannelMemberResponse<ErmisChatGenerics>>;\n /** The count of messages not yet read by the currently authenticated user. */\n unreadCount: number;\n /** Information detailing the authenticated user's own membership relation to this channel. */\n membership: ChannelMembership<ErmisChatGenerics>;\n /** Timestamp indicating when the very last message was created in this chat. */\n last_message_at: Date | null;\n /** Designates if the local channel state is entirely synchronized with the backend history. */\n isUpToDate: boolean;\n messageSets: {\n isCurrent: boolean;\n isLatest: boolean;\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>;\n }[] = [];\n topics?: Channel<ErmisChatGenerics>[] = [];\n constructor(channel: Channel<ErmisChatGenerics>) {\n this._channel = channel;\n this.watcher_count = 0;\n this.typing = {};\n this.read = {};\n this.initMessages();\n this.pinnedMessages = [];\n this.watchers = {};\n this.members = {};\n this.membership = {};\n this.unreadCount = 0;\n this.isUpToDate = true;\n this.last_message_at = channel?.state?.last_message_at != null ? new Date(channel.state.last_message_at) : null;\n }\n\n get messages() {\n return this.messageSets.find((s) => s.isCurrent)?.messages || [];\n }\n\n set messages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isCurrent);\n this.messageSets[index].messages = messages;\n }\n\n get latestMessages() {\n return this.messageSets.find((s) => s.isLatest)?.messages || [];\n }\n\n set latestMessages(messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>) {\n const index = this.messageSets.findIndex((s) => s.isLatest);\n this.messageSets[index].messages = messages;\n }\n\n /**\n * Pushes a new message directly into the sorted array of the local tracking state.\n * Useful to achieve optimistic UI updates locally.\n *\n * @param newMessage - The message context payload to insert.\n * @param timestampChanged - Specifies if the underlying `created_at` timestamp mutated.\n * @param addIfDoesNotExist - Append it strictly if its ID doesn't already exist.\n * @param messageSetToAddToIfDoesNotExist - Specifies which message set scope to manipulate.\n */\n addMessageSorted(\n newMessage: MessageResponse<ErmisChatGenerics>,\n timestampChanged = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n ) {\n return this.addMessagesSorted(\n [newMessage],\n timestampChanged,\n false,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n }\n\n formatMessage(message: MessageResponse<ErmisChatGenerics>): FormatMessageResponse<ErmisChatGenerics> {\n return {\n ...message,\n /**\n * @deprecated please use `html`\n */\n __html: message.html,\n // parse the date..\n pinned_at: message.pinned_at ? new Date(message.pinned_at) : null,\n created_at: message.created_at ? new Date(message.created_at) : new Date(),\n updated_at: message.updated_at ? new Date(message.updated_at) : null,\n status: message.status || 'received',\n };\n }\n\n addMessagesSorted(\n newMessages: MessageResponse<ErmisChatGenerics>[],\n timestampChanged = false,\n initializing = false,\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n const { messagesToAdd, targetMessageSetIndex } = this.findTargetMessageSet(\n newMessages,\n addIfDoesNotExist,\n messageSetToAddToIfDoesNotExist,\n );\n\n for (let i = 0; i < messagesToAdd.length; i += 1) {\n // If message is already formatted we can skip the tasks below\n // This will be true for messages that are already present at the state -> this happens when we perform merging of message sets\n // This will be also true for message previews used by some SDKs\n const isMessageFormatted = messagesToAdd[i].created_at instanceof Date;\n let message: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n if (isMessageFormatted) {\n message = messagesToAdd[i] as ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n } else {\n message = this.formatMessage(messagesToAdd[i] as MessageResponse<ErmisChatGenerics>);\n\n if (message.user && this._channel?.cid) {\n /**\n * Store the reference to user for this channel, so that when we have to\n * handle updates to user, we can use the reference map, to determine which\n * channels need to be updated with updated user object.\n */\n this._channel.getClient().state.updateUserReference(message.user, this._channel.cid);\n }\n\n if (!this.last_message_at) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n\n if (message.created_at.getTime() > this.last_message_at.getTime()) {\n this.last_message_at = new Date(message.created_at.getTime());\n }\n }\n\n // Cross-reference with pinnedMessages to ensure `pinned` and `pinned_at` are accurate\n if (!message.pinned) {\n const pinnedMatch = this.pinnedMessages.find((pm) => pm.id === message.id);\n if (pinnedMatch) {\n message.pinned = true;\n message.pinned_at = pinnedMatch.pinned_at || new Date();\n }\n }\n\n // update or append the messages...\n const parentID = message.parent_id;\n\n // add to the given message set\n if (!parentID && targetMessageSetIndex !== -1) {\n this.messageSets[targetMessageSetIndex].messages = this._addToMessageList(\n this.messageSets[targetMessageSetIndex].messages,\n message,\n timestampChanged,\n 'created_at',\n addIfDoesNotExist,\n );\n }\n }\n\n return {\n messageSet: this.messageSets[targetMessageSetIndex],\n };\n }\n\n addPinnedMessages(pinnedMessages: MessageResponse<ErmisChatGenerics>[]) {\n for (let i = 0; i < pinnedMessages.length; i += 1) {\n this.addPinnedMessage(pinnedMessages[i]);\n }\n // Sort by pinned_at descending (newest pin first)\n this.pinnedMessages.sort((a, b) => {\n const timeA = a.pinned_at ? new Date(a.pinned_at).getTime() : 0;\n const timeB = b.pinned_at ? new Date(b.pinned_at).getTime() : 0;\n return timeB - timeA;\n });\n }\n\n addPinnedMessage(pinnedMessage: MessageResponse<ErmisChatGenerics>) {\n const formatted = this.formatMessage(pinnedMessage);\n // Remove existing entry if present (to avoid duplicates)\n this.pinnedMessages = this.pinnedMessages.filter((msg) => msg.id !== formatted.id);\n // Add to the beginning of the list (newest pin first)\n this.pinnedMessages = [formatted, ...this.pinnedMessages];\n }\n\n removePinnedMessage(message: MessageResponse<ErmisChatGenerics>) {\n const { result } = this.removeMessageFromArray(this.pinnedMessages, message);\n this.pinnedMessages = result;\n }\n\n addReaction(\n reaction: ReactionResponse<ErmisChatGenerics>,\n message?: MessageResponse<ErmisChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._addOwnReactionToMessage(msg.own_reactions, reaction, enforce_unique);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n _addOwnReactionToMessage(\n ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<ErmisChatGenerics>,\n enforce_unique?: boolean,\n ) {\n if (enforce_unique) {\n ownReactions = [];\n } else {\n ownReactions = this._removeOwnReactionFromMessage(ownReactions, reaction);\n }\n\n ownReactions = ownReactions || [];\n if (this._channel.getClient().userID === reaction.user_id) {\n ownReactions.push(reaction);\n }\n\n return ownReactions;\n }\n\n _removeOwnReactionFromMessage(\n ownReactions: ReactionResponse<ErmisChatGenerics>[] | null | undefined,\n reaction: ReactionResponse<ErmisChatGenerics>,\n ) {\n if (ownReactions) {\n return ownReactions.filter((item) => item.user_id !== reaction.user_id || item.type !== reaction.type);\n }\n return ownReactions;\n }\n\n removeReaction(reaction: ReactionResponse<ErmisChatGenerics>, message?: MessageResponse<ErmisChatGenerics>) {\n if (!message) return;\n const messageWithReaction = message;\n this._updateMessage(message, (msg) => {\n messageWithReaction.own_reactions = this._removeOwnReactionFromMessage(msg.own_reactions, reaction);\n return this.formatMessage(messageWithReaction);\n });\n return messageWithReaction;\n }\n\n removeQuotedMessageReferences(message: MessageResponse<ErmisChatGenerics>) {\n const parseMessage = (m: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>) =>\n ({\n ...m,\n created_at: m.created_at.toISOString(),\n pinned_at: m.pinned_at?.toISOString(),\n updated_at: m.updated_at?.toISOString(),\n } as unknown as MessageResponse<ErmisChatGenerics>);\n\n this.messageSets.forEach((set) => {\n const updatedMessages = set.messages\n .filter((msg) => msg.quoted_message_id === message.id)\n .map(parseMessage)\n .map((msg) => ({ ...msg, quoted_message: { ...message, attachments: [] } }));\n\n this.addMessagesSorted(updatedMessages, true);\n });\n }\n\n _updateMessage(\n message: {\n id?: string;\n parent_id?: string;\n pinned?: boolean;\n },\n updateFunc: (\n msg: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n ) => ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n ) {\n const { parent_id, pinned } = message;\n\n if (!parent_id) {\n const messageSetIndex = this.findMessageSetIndex(message);\n if (messageSetIndex !== -1) {\n const msgIndex = this.messageSets[messageSetIndex].messages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.messageSets[messageSetIndex].messages[msgIndex] = updateFunc(\n this.messageSets[messageSetIndex].messages[msgIndex],\n );\n }\n }\n }\n\n if (pinned) {\n const msgIndex = this.pinnedMessages.findIndex((msg) => msg.id === message.id);\n if (msgIndex !== -1) {\n this.pinnedMessages[msgIndex] = updateFunc(this.pinnedMessages[msgIndex]);\n }\n }\n }\n\n setIsUpToDate = (isUpToDate: boolean) => {\n this.isUpToDate = isUpToDate;\n };\n\n /**\n * Update the status of a message by ID (used for optimistic UI).\n */\n updateMessageStatus(messageId: string, status: string) {\n this._updateMessage({ id: messageId }, (msg) => ({\n ...msg,\n status,\n }));\n }\n\n _addToMessageList(\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n message: ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>,\n timestampChanged = false,\n sortBy: 'pinned_at' | 'created_at' = 'created_at',\n addIfDoesNotExist = true,\n ) {\n return addToMessageList(messages, message, timestampChanged, sortBy, addIfDoesNotExist);\n }\n\n removeMessage(messageToRemove: { id: string; messageSetIndex?: number; parent_id?: string }) {\n let isRemoved = false;\n const messageSetIndex = messageToRemove.messageSetIndex ?? this.findMessageSetIndex(messageToRemove);\n if (messageSetIndex !== -1) {\n const { removed, result: messages } = this.removeMessageFromArray(\n this.messageSets[messageSetIndex].messages,\n messageToRemove,\n );\n this.messageSets[messageSetIndex].messages = messages;\n isRemoved = removed;\n }\n\n return isRemoved;\n }\n\n removeMessageFromArray = (\n msgArray: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n msg: { id: string; parent_id?: string },\n ) => {\n const result = msgArray.filter((message) => !(!!message.id && !!msg.id && message.id === msg.id));\n\n return { removed: result.length < msgArray.length, result };\n };\n\n /**\n * Refreshes internal user references cascading across all presently active messages.\n * Invoked instantly whenever an underlying user's profile metadata updates (e.g. name or avatar changes).\n *\n * @param user - The newly formatted and populated User details object.\n */\n updateUserMessages = (user: UserResponse<ErmisChatGenerics>) => {\n const _updateUserMessages = (\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n user: UserResponse<ErmisChatGenerics>,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n const latestReactions = m?.latest_reactions || [];\n if (m.user?.id === user.id) {\n messages[i] = {\n ...m,\n user: m.user?.id === user.id ? user : m.user,\n };\n }\n\n if (latestReactions && latestReactions.some((r) => r.user?.id === user.id)) {\n messages[i] = {\n ...m,\n latest_reactions: latestReactions.map((r) => (r.user?.id === user.id ? { ...r, user } : r)),\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _updateUserMessages(set.messages, user));\n\n _updateUserMessages(this.pinnedMessages, user);\n };\n\n deleteUserMessages = (user: UserResponse<ErmisChatGenerics>, hardDelete = false) => {\n const _deleteUserMessages = (\n messages: Array<ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>>,\n user: UserResponse<ErmisChatGenerics>,\n hardDelete = false,\n ) => {\n for (let i = 0; i < messages.length; i++) {\n const m = messages[i];\n if (m.user?.id !== user.id) {\n continue;\n }\n\n if (hardDelete) {\n /**\n * In case of hard delete, we need to strip down all text, html,\n * attachments and all the custom properties on message\n */\n messages[i] = {\n cid: m.cid,\n created_at: m.created_at,\n deleted_at: new Date().toISOString(),\n id: m.id,\n latest_reactions: [],\n mentioned_users: [],\n own_reactions: [],\n parent_id: m.parent_id,\n reply_count: m.reply_count,\n status: m.status,\n type: 'deleted',\n updated_at: m.updated_at,\n user: m.user,\n } as unknown as ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>;\n } else {\n messages[i] = {\n ...m,\n type: 'deleted',\n deleted_at: new Date().toISOString(),\n };\n }\n }\n };\n\n this.messageSets.forEach((set) => _deleteUserMessages(set.messages, user, hardDelete));\n\n _deleteUserMessages(this.pinnedMessages, user, hardDelete);\n };\n\n filterErrorMessages() {\n const filteredMessages = this.latestMessages.filter((message) => message.type !== 'error');\n\n this.latestMessages = filteredMessages;\n }\n\n clean() {\n const now = new Date();\n // prevent old users from showing up as typing\n for (const [userID, lastEvent] of Object.entries(this.typing)) {\n const receivedAt =\n typeof lastEvent.received_at === 'string'\n ? new Date(lastEvent.received_at)\n : lastEvent.received_at || new Date();\n if (now.getTime() - receivedAt.getTime() > 7000) {\n delete this.typing[userID];\n this._channel.getClient().dispatchEvent({\n cid: this._channel.cid,\n type: 'typing.stop',\n user: { id: userID },\n } as Event<ErmisChatGenerics>);\n }\n }\n }\n\n clearMessages() {\n this.initMessages();\n this.pinnedMessages = [];\n }\n\n initMessages() {\n this.messageSets = [{ messages: [], isLatest: true, isCurrent: true }];\n }\n\n async loadMessageIntoState(messageId: string | 'latest', parentMessageId?: string, limit = 25) {\n let messageSetIndex: number;\n let switchedToMessageSet = false;\n const messageIdToFind = parentMessageId || messageId;\n if (messageId === 'latest') {\n if (this.messages === this.latestMessages) {\n return;\n }\n messageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n } else {\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n }\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n switchedToMessageSet = true;\n }\n if (!switchedToMessageSet) {\n await this._channel.query({ messages: { id_around: messageIdToFind, limit } }, 'new');\n }\n\n messageSetIndex = this.findMessageSetIndex({ id: messageIdToFind });\n if (messageSetIndex !== -1) {\n this.switchToMessageSet(messageSetIndex);\n }\n }\n\n findMessage(messageId: string, parentMessageId?: string) {\n const messageSetIndex = this.findMessageSetIndex({ id: messageId });\n if (messageSetIndex === -1) {\n return undefined;\n }\n return this.messageSets[messageSetIndex].messages.find((m) => m.id === messageId);\n }\n\n private switchToMessageSet(index: number) {\n const currentMessages = this.messageSets.find((s) => s.isCurrent);\n if (!currentMessages) {\n return;\n }\n currentMessages.isCurrent = false;\n this.messageSets[index].isCurrent = true;\n }\n\n private areMessageSetsOverlap(messages1: Array<{ id: string }>, messages2: Array<{ id: string }>) {\n return messages1.some((m1) => messages2.find((m2) => m1.id === m2.id));\n }\n\n private findMessageSetIndex(message: { id?: string }) {\n return this.messageSets.findIndex((set) => !!set.messages.find((m) => m.id === message.id));\n }\n\n private findTargetMessageSet(\n newMessages: MessageResponse<ErmisChatGenerics>[],\n addIfDoesNotExist = true,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'current',\n ) {\n let messagesToAdd: (\n | MessageResponse<ErmisChatGenerics>\n | ReturnType<ChannelState<ErmisChatGenerics>['formatMessage']>\n )[] = newMessages;\n let targetMessageSetIndex!: number;\n if (addIfDoesNotExist) {\n const overlappingMessageSetIndices = this.messageSets\n .map((_, i) => i)\n .filter((i) => this.areMessageSetsOverlap(this.messageSets[i].messages, newMessages));\n switch (messageSetToAddToIfDoesNotExist) {\n case 'new':\n if (overlappingMessageSetIndices.length > 0) {\n targetMessageSetIndex = overlappingMessageSetIndices[0];\n } else if (newMessages.some((m) => !m.parent_id)) {\n this.messageSets.push({ messages: [], isCurrent: false, isLatest: false });\n targetMessageSetIndex = this.messageSets.length - 1;\n }\n break;\n case 'current':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isCurrent);\n break;\n case 'latest':\n targetMessageSetIndex = this.messageSets.findIndex((s) => s.isLatest);\n break;\n default:\n targetMessageSetIndex = -1;\n }\n // when merging the target set will be the first one from the overlapping message sets\n const mergeTargetMessageSetIndex = overlappingMessageSetIndices.splice(0, 1)[0];\n const mergeSourceMessageSetIndices = [...overlappingMessageSetIndices];\n if (mergeTargetMessageSetIndex !== undefined && mergeTargetMessageSetIndex !== targetMessageSetIndex) {\n mergeSourceMessageSetIndices.push(targetMessageSetIndex);\n }\n // merge message sets\n if (mergeSourceMessageSetIndices.length > 0) {\n const target = this.messageSets[mergeTargetMessageSetIndex];\n const sources = this.messageSets.filter((_, i) => mergeSourceMessageSetIndices.indexOf(i) !== -1);\n sources.forEach((messageSet) => {\n target.isLatest = target.isLatest || messageSet.isLatest;\n target.isCurrent = target.isCurrent || messageSet.isCurrent;\n messagesToAdd = [...messagesToAdd, ...messageSet.messages];\n });\n sources.forEach((s) => this.messageSets.splice(this.messageSets.indexOf(s), 1));\n const overlappingMessageSetIndex = this.messageSets.findIndex((s) =>\n this.areMessageSetsOverlap(s.messages, newMessages),\n );\n targetMessageSetIndex = overlappingMessageSetIndex;\n }\n } else {\n // assumes that all new messages belong to the same set\n targetMessageSetIndex = this.findMessageSetIndex(newMessages[0]);\n }\n\n return { targetMessageSetIndex, messagesToAdd };\n }\n}\n","import type { Attachment } from './types';\n\n/**\n * Normalize a file name for upload:\n * - Remove Vietnamese diacritics\n * - Replace đ/Đ with d/D\n * - Replace spaces with underscores\n * - Preserve extension\n */\nexport function normalizeFileName(name: string): string {\n const dotIndex = name.lastIndexOf('.');\n const baseName = dotIndex > 0 ? name.slice(0, dotIndex) : name;\n const extension = dotIndex > 0 ? name.slice(dotIndex) : '';\n\n const normalized = baseName\n .normalize('NFD')\n .replace(/[\\u0300-\\u036f]/g, '') // strip diacritics\n .replace(/đ/g, 'd')\n .replace(/Đ/g, 'D')\n .replace(/\\s+/g, '_');\n\n return normalized + extension;\n}\n\n/**\n * Check if a MIME type or file extension is HEIC/HEIF.\n */\nexport function isHeicFile(file: File): boolean {\n const mime = file.type.toLowerCase();\n const ext = file.name.toLowerCase().split('.').pop() || '';\n return (\n mime === 'image/heic' ||\n mime === 'image/heif' ||\n ext === 'heic' ||\n ext === 'heif'\n );\n}\n\n/**\n * Categorize a file by MIME type.\n * HEIC/HEIF files are treated as 'file' (not 'image') since browsers can't render them.\n */\nexport function getAttachmentCategory(\n mimeType: string,\n fileName?: string,\n): 'image' | 'video' | 'audio' | 'file' {\n const mime = mimeType.toLowerCase();\n const ext = (fileName || '').toLowerCase().split('.').pop() || '';\n\n // HEIC/HEIF → file (not image)\n if (mime === 'image/heic' || mime === 'image/heif' || ext === 'heic' || ext === 'heif') {\n return 'file';\n }\n\n if (mime.startsWith('image/')) return 'image';\n if (mime.startsWith('video/')) return 'video';\n if (mime.startsWith('audio/')) return 'audio';\n return 'file';\n}\n\n/**\n * Check if a file is a video type that supports thumbnail extraction.\n */\nexport function isVideoFile(file: File): boolean {\n return (\n file.type === 'video/mp4' ||\n file.type === 'video/webm' ||\n file.type === 'video/quicktime'\n );\n}\n\n/**\n * Metadata for voice recording attachments.\n */\nexport type VoiceRecordingMeta = {\n waveform_data: number[];\n duration: number;\n};\n\n/**\n * Build a normalized attachment payload from an uploaded file.\n *\n * @param file - Original file object\n * @param uploadedUrl - URL returned by the upload API\n * @param thumbUrl - Optional thumbnail URL (for video)\n * @param voiceMeta - Optional voice recording metadata\n */\nexport function buildAttachmentPayload(\n file: File,\n uploadedUrl: string,\n thumbUrl?: string,\n voiceMeta?: VoiceRecordingMeta,\n): Attachment {\n const title = normalizeFileName(file.name);\n const mimeType = file.type || '';\n const category = getAttachmentCategory(mimeType, file.name);\n\n if (voiceMeta) {\n return {\n type: 'voiceRecording',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n waveform_data: voiceMeta.waveform_data,\n duration: voiceMeta.duration,\n };\n }\n\n switch (category) {\n case 'image':\n return {\n type: 'image',\n image_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n };\n\n case 'video':\n return {\n type: 'video',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n thumb_url: thumbUrl || '',\n };\n\n case 'audio':\n return {\n type: 'file',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType,\n };\n\n default:\n return {\n type: 'file',\n asset_url: uploadedUrl,\n title,\n file_size: file.size,\n mime_type: mimeType || '',\n };\n }\n}\n","import { ChannelState } from './channel_state';\nimport { normalizeFileName, isVideoFile, buildAttachmentPayload } from './attachment_utils';\nimport type { VoiceRecordingMeta } from './attachment_utils';\nimport {\n enrichWithUserInfo,\n ensureMembersUserInfoLoaded,\n getDirectChannelImage,\n getDirectChannelName,\n getUserInfo,\n logChatPromiseExecution,\n randomId,\n} from './utils';\nimport { ErmisChat } from './client';\nimport {\n APIResponse,\n Attachment,\n ChannelAPIResponse,\n ChannelData,\n ChannelQueryOptions,\n ChannelResponse,\n DefaultGenerics,\n Event,\n EventHandler,\n EventTypes,\n ExtendableGenerics,\n FormatMessageResponse,\n Message,\n MessageResponse,\n MessageSetType,\n ReactionAPIResponse,\n SendMessageAPIResponse,\n UpdateChannelAPIResponse,\n UserResponse,\n QueryChannelAPIResponse,\n AttachmentResponse,\n PollMessage,\n EditMessage,\n ForwardMessage,\n} from './types';\n/**\n * Represents a Channel in the Ermis Network.\n * Channels handle chat sessions, livestream messages, teams, or video calls.\n * This class abstracts and exposes all API operations you can perform on a specific channel instance.\n */\nexport class Channel<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n _client: ErmisChat<ErmisChatGenerics>;\n type: string;\n id: string | undefined;\n data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics> | undefined;\n _data: ChannelData<ErmisChatGenerics> | ChannelResponse<ErmisChatGenerics>;\n cid: string;\n listeners: { [key: string]: (string | EventHandler<ErmisChatGenerics>)[] };\n state: ChannelState<ErmisChatGenerics>;\n initialized: boolean;\n offlineMode: boolean;\n lastKeyStroke?: Date;\n lastTypingEvent: Date | null;\n isTyping: boolean;\n disconnected: boolean;\n\n /**\n * Initializes a new Channel class instance.\n * Normally you should not call this directly; use `client.channel(type, id)` instead.\n *\n * @param client - The shared ErmisChat client instance initializing this channel.\n * @param type - The type of channel (`messaging`, `team`, `livestream`, etc.).\n * @param id - The unique ID of the channel.\n * @param data - Initial arbitrary metadata stored within this channel.\n */\n constructor(\n client: ErmisChat<ErmisChatGenerics>,\n type: string,\n id: string | undefined,\n data: ChannelData<ErmisChatGenerics>,\n ) {\n const validTypeRe = /^[\\w_-]+$/;\n const validIDRe = /^[\\w!:_-]+$/;\n\n if (!validTypeRe.test(type)) {\n throw new Error(`Invalid chat type ${type}, letters, numbers and \"_-\" are allowed`);\n }\n if (typeof id === 'string' && !validIDRe.test(id)) {\n throw new Error(`Invalid chat id ${id}, letters, numbers and \"!-_\" are allowed`);\n }\n\n this._client = client;\n this.type = type;\n this.id = id;\n this.data = data;\n this._data = { ...data };\n this.cid = `${type}:${id}`;\n this.listeners = {};\n this.state = new ChannelState<ErmisChatGenerics>(this);\n this.initialized = false;\n this.offlineMode = false;\n this.lastTypingEvent = null;\n this.isTyping = false;\n this.disconnected = false;\n }\n\n getClient(): ErmisChat<ErmisChatGenerics> {\n return this._client;\n }\n\n /**\n * Sends a message to this channel.\n * By default, it pushes the message eagerly (optimistically) to the local UI state before the server replies.\n *\n * @param message - The constructed text/attachment object payload representing the message.\n * @returns A Promise resolving to the exact API response encompassing message details.\n */\n async sendMessage(message: Message<ErmisChatGenerics>) {\n // 1. Generate ID upfront\n if (!message.id) {\n message = { ...message, id: randomId() };\n }\n const messageId = message.id!;\n\n // 2. Build optimistic (fake) message and push into state immediately\n const optimisticMessage = {\n ...message,\n id: messageId,\n status: 'sending',\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n user: this.getClient().user,\n user_id: this.getClient().userID,\n type: 'regular',\n } as unknown as MessageResponse<ErmisChatGenerics>;\n\n this.state.addMessageSorted(optimisticMessage);\n\n // 3. Call API — don't update status on success (WS message.new will handle it)\n try {\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n this._channelURL() + '/message',\n { message: { ...message } },\n );\n } catch (error: any) {\n // 4. On error: check if it's an offline/network error\n const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;\n const statusToSet = isOfflineError ? 'failed_offline' : 'error';\n this.state.updateMessageStatus(messageId, statusToSet);\n throw error;\n }\n }\n\n async retryMessage(messageId: string) {\n const stateMsg = this.state.messages.find((m) => m.id === messageId);\n if (!stateMsg) throw new Error(`Message ${messageId} not found in state`);\n\n this.state.updateMessageStatus(messageId, 'sending');\n\n const messagePayload: any = {\n id: stateMsg.id,\n text: stateMsg.text,\n attachments: stateMsg.attachments,\n mentioned_users: stateMsg.mentioned_users,\n parent_id: stateMsg.parent_id,\n quoted_message_id: stateMsg.quoted_message_id,\n sticker_url: (stateMsg as any).sticker_url,\n };\n\n if (stateMsg.show_in_channel !== undefined) {\n messagePayload.show_in_channel = stateMsg.show_in_channel;\n }\n\n try {\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n this._channelURL() + '/message',\n { message: messagePayload },\n );\n } catch (error: any) {\n const isOfflineError = !error.response || error.code === 'ERR_NETWORK' || error.isWSFailure || !this.getClient().wsConnection?.isHealthy;\n this.state.updateMessageStatus(messageId, isOfflineError ? 'failed_offline' : 'error');\n throw error;\n }\n }\n\n async createPoll(pollMessage: PollMessage) {\n const id = randomId();\n pollMessage = { ...pollMessage, id };\n\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(this._channelURL() + '/message', {\n message: { ...pollMessage },\n });\n }\n\n async votePoll(messageID: string, pollChoice: string) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return await this.getClient().post<APIResponse>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/poll/${pollChoice}`,\n );\n }\n\n async forwardMessage(message: ForwardMessage<ErmisChatGenerics>, channel: { type: string; channelID: string }) {\n if (!message.id) {\n message = { ...message, id: randomId() };\n }\n\n return await this.getClient().post<SendMessageAPIResponse<ErmisChatGenerics>>(\n `${this.getClient().baseURL}/channels/${channel.type}/${channel.channelID}` + '/message',\n {\n message: { ...message },\n },\n );\n }\n\n async pinMessage(messageID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/pin`);\n }\n\n async unpinMessage(messageID: string) {\n return await this.getClient().post(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/unpin`,\n );\n }\n\n async editMessage(oldMessageID: string, message: EditMessage) {\n return await this.getClient().post(this.getClient().baseURL + `/messages/${this.type}/${this.id}/${oldMessageID}`, {\n message,\n });\n }\n\n sendFile(\n uri: string | NodeJS.ReadableStream | Buffer | File,\n name?: string,\n contentType?: string,\n user?: UserResponse<ErmisChatGenerics>,\n ) {\n return this.getClient().sendFile(`${this._channelURL()}/file`, uri, name, contentType, user);\n }\n /**\n * Pre-process files (normalize names), upload them in parallel,\n * generate video thumbnails, and build attachment payloads.\n *\n * @param files - Array of File objects to upload\n * @param options - Optional voice recording metadata\n * @returns `attachments` ready for sendMessage, and `failedFiles` for error display\n */\n async uploadAndPrepareAttachments(\n files: File[],\n options?: {\n /** Map from file index → voice recording metadata */\n voiceMetadata?: Map<number, VoiceRecordingMeta>;\n },\n ): Promise<{\n attachments: Attachment[];\n failedFiles: Array<{ file: File; error: Error }>;\n }> {\n const failedFiles: Array<{ file: File; error: Error }> = [];\n\n // 1. Pre-process: normalize file names\n const processedFiles = files.map((file) => {\n const newName = normalizeFileName(file.name);\n if (newName !== file.name) {\n return new File([file], newName, { type: file.type, lastModified: file.lastModified });\n }\n return file;\n });\n\n // 2. Upload all files in parallel\n const uploadResults = await Promise.allSettled(\n processedFiles.map((file) =>\n this.sendFile(file, file.name, file.type),\n ),\n );\n\n // 3. For successful video uploads, generate and upload thumbnails\n const thumbUrls = new Map<number, string>();\n const thumbPromises: Promise<void>[] = [];\n\n for (let i = 0; i < processedFiles.length; i++) {\n const result = uploadResults[i];\n if (result.status === 'fulfilled' && isVideoFile(processedFiles[i])) {\n thumbPromises.push(\n (async () => {\n try {\n const thumbBlob = await this.getThumbBlobVideo(files[i]);\n if (thumbBlob) {\n const thumbFile = new File(\n [thumbBlob],\n `thumb_${processedFiles[i].name}.jpg`,\n { type: 'image/jpeg' },\n );\n const thumbResp = await this.sendFile(thumbFile, thumbFile.name, 'image/jpeg');\n thumbUrls.set(i, thumbResp.file);\n }\n } catch {\n // Thumbnail failure is non-critical\n }\n })(),\n );\n }\n }\n\n await Promise.allSettled(thumbPromises);\n\n // 4. Build attachment payloads from successful uploads\n const attachments: Attachment[] = [];\n for (let i = 0; i < processedFiles.length; i++) {\n const result = uploadResults[i];\n if (result.status === 'fulfilled') {\n const uploadedUrl = result.value.file;\n const thumbUrl = thumbUrls.get(i);\n const voiceMeta = options?.voiceMetadata?.get(i);\n attachments.push(\n buildAttachmentPayload(processedFiles[i], uploadedUrl, thumbUrl, voiceMeta),\n );\n } else {\n failedFiles.push({\n file: files[i],\n error: result.reason instanceof Error ? result.reason : new Error(String(result.reason)),\n });\n }\n }\n\n return { attachments, failedFiles };\n }\n\n async sendEvent(event: Event<ErmisChatGenerics>) {\n // this._checkInitialized();\n return await this.getClient().post(this._channelURL() + '/event', {\n event,\n });\n }\n\n async sendReaction(messageID: string, reactionType: string) {\n if (!messageID) {\n throw Error(`Message id is missing`);\n }\n return await this.getClient().post<ReactionAPIResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/reaction/${reactionType}`,\n );\n }\n\n deleteReaction(messageID: string, reactionType: string) {\n // this._checkInitialized();\n if (!reactionType || !messageID) {\n throw Error('Deleting a reaction requires specifying both the message and reaction type');\n }\n\n const url = this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageID}/reaction/${reactionType}`;\n //provided when server side request\n // if (user_id) {\n // return this.getClient().delete<ReactionAPIResponse<ErmisChatGenerics>>(url, { user_id });\n // }\n\n return this.getClient().delete<ReactionAPIResponse<ErmisChatGenerics>>(url, {});\n }\n\n async update(\n channelData: Partial<ChannelData<ErmisChatGenerics>> | Partial<ChannelResponse<ErmisChatGenerics>> = {},\n updateMessage?: Message<ErmisChatGenerics>,\n ) {\n // Strip out reserved names that will result in API errors.\n const reserved = [\n 'config',\n 'cid',\n 'created_by',\n 'id',\n 'member_count',\n 'type',\n 'created_at',\n 'updated_at',\n 'last_message_at',\n 'own_capabilities',\n ];\n reserved.forEach((key) => {\n delete channelData[key];\n });\n\n return await this._update({\n message: updateMessage,\n data: channelData,\n });\n }\n\n async delete() {\n return await this.getClient().delete(this._channelURL());\n }\n\n async truncate() {\n return await this.getClient().delete(this._channelURL() + '/truncate');\n }\n\n async blockUser() {\n return await this.getClient().post(this._channelURL(), { action: 'block' });\n }\n\n async unblockUser() {\n return await this.getClient().post(this._channelURL(), { action: 'unblock' });\n }\n\n async acceptInvite(action: string) {\n // const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/accept`;\n const channel_id = this.id;\n\n const url = this.getClient().userBaseURL + `/token_gate/join_channel/${this.type}`;\n return this.getClient().post<APIResponse>(url, {}, { channel_id, action });\n }\n\n async rejectInvite() {\n const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/reject`;\n return this.getClient().post<APIResponse>(url);\n }\n\n async skipInvite() {\n const url = this.getClient().baseURL + `/invites/${this.type}/${this.id}/skip`;\n return this.getClient().post<APIResponse>(url);\n }\n\n /**\n * Directly invites or adds registered users into this channel.\n *\n * @param members - Array of user IDs explicitly selected to be added.\n */\n async addMembers(members: string[]) {\n return await this._update({ add_members: members });\n }\n\n async addModerators(members: string[]) {\n return await this._update({ promote_members: members });\n }\n\n async banMembers(members: string[]) {\n return await this._update({ ban_members: members });\n }\n\n async unbanMembers(members: string[]) {\n return await this._update({ unban_members: members });\n }\n\n async updateCapabilities(capabilities: string[]) {\n return await this._update({ capabilities });\n }\n\n /**\n * Set slow mode (message cooldown) for the channel.\n * Only applicable to team channels. Prevents members from sending\n * messages faster than the specified cooldown interval.\n *\n * @param cooldown - Cooldown duration in milliseconds.\n * Allowed values: 0 (off), 10000 (10s), 30000 (30s),\n * 60000 (1min), 300000 (5min), 900000 (15min), 3600000 (1h).\n */\n async setSlowMode(cooldown: 0 | 10000 | 30000 | 60000 | 300000 | 900000 | 3600000) {\n const allowedValues = [0, 10000, 30000, 60000, 300000, 900000, 3600000];\n if (!allowedValues.includes(cooldown)) {\n throw new Error(\n `Invalid cooldown value: ${cooldown}. Allowed values are: ${allowedValues.join(', ')} (milliseconds).`,\n );\n }\n return await this.update({ member_message_cooldown: cooldown } as any);\n }\n\n async queryAttachmentMessages() {\n const response = await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/attachment`,\n {\n attachment_types: ['image', 'video', 'file', 'voiceRecording', 'linkPreview'],\n },\n );\n\n // Sort newest first\n if (response.attachments) {\n response.attachments.sort(\n (a: any, b: any) => new Date(b.created_at).getTime() - new Date(a.created_at).getTime(),\n );\n }\n\n return response;\n }\n\n async searchMessage(search_term: string, offset: number) {\n const response: any = await this.getClient().post(this.getClient().baseURL + `/channels/search`, {\n cid: this.cid,\n search_term,\n offset,\n limit: 25,\n });\n\n if (!response || response?.search_result?.messages.length === 0) {\n return null;\n }\n\n return {\n ...response?.search_result,\n messages: response?.search_result?.messages.map((message: any) => {\n const user = getUserInfo(message.user_id, Object.values(this.getClient().state.users)) || message.user;\n return { ...message, user };\n }),\n };\n }\n\n /**\n * Expels specified currently participating users out of the channel.\n *\n * @param members - Array of user IDs to strictly remove from this chat.\n */\n async removeMembers(members: string[]) {\n return await this._update({ remove_members: members });\n }\n\n async demoteModerators(members: string[]) {\n return await this._update({ demote_members: members });\n }\n\n async _update(payload: Object) {\n const data = await this.getClient().post<UpdateChannelAPIResponse<ErmisChatGenerics>>(this._channelURL(), payload);\n this.data = { ...this.data, ...data.channel };\n return data;\n }\n\n _processTopics(topicsFromApi: any, users: any[]) {\n const topics = topicsFromApi.map((topic: any) => {\n // Enrich topic members with user info\n if (topic.channel && topic.channel.members) {\n topic.channel.members = enrichWithUserInfo(topic.channel.members, users);\n }\n // Enrich topic messages with user info\n if (topic.messages) {\n topic.messages = enrichWithUserInfo(topic.messages, users);\n }\n // Enrich topic pinned messages with user info\n if (topic.pinned_messages) {\n topic.pinned_messages = enrichWithUserInfo(topic.pinned_messages, users);\n }\n // Enrich topic read with user info\n if (topic.read) {\n topic.read = enrichWithUserInfo(topic.read, users);\n }\n return topic;\n });\n\n const { channels } = this.getClient().hydrateChannels(topics, {});\n\n // Store topics in channel state\n this.state.topics = channels;\n }\n\n async muteNotification(duration: number | null) {\n return await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/muted`,\n { mute: true, duration },\n );\n }\n\n async unMuteNotification() {\n return await this.getClient().post<AttachmentResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/muted`,\n { mute: false },\n );\n }\n\n async keystroke(parent_id?: string, options?: { user_id: string }) {\n const now = new Date();\n const diff = this.lastTypingEvent && now.getTime() - this.lastTypingEvent.getTime();\n this.lastKeyStroke = now;\n this.isTyping = true;\n // send a typing.start every 2 seconds\n if (diff === null || diff > 2000) {\n this.lastTypingEvent = new Date();\n await this.sendEvent({\n type: 'typing.start',\n parent_id,\n ...(options || {}),\n } as Event<ErmisChatGenerics>);\n }\n }\n\n async stopTyping(parent_id?: string, options?: { user_id: string }) {\n if (!this.isTyping) return;\n this.lastTypingEvent = null;\n this.isTyping = false;\n await this.sendEvent({\n type: 'typing.stop',\n parent_id,\n ...(options || {}),\n } as Event<ErmisChatGenerics>);\n }\n\n _isTypingIndicatorsEnabled(): boolean {\n return true;\n }\n\n lastMessage() {\n let min = this.state.latestMessages.length - 5;\n if (min < 0) {\n min = 0;\n }\n const max = this.state.latestMessages.length + 1;\n const messageSlice = this.state.latestMessages.slice(min, max);\n\n // sort by pk desc\n messageSlice.sort((a, b) => b.created_at.getTime() - a.created_at.getTime());\n\n return messageSlice[0];\n }\n\n /**\n * Emits a mark-read event, updating the backend that the authenticated user has viewed up to the latest known message.\n * @returns Successful acknowledgement from the server.\n */\n async markRead() {\n return await this.getClient().post(this._channelURL() + '/read');\n }\n\n clean() {\n if (this.lastKeyStroke) {\n const now = new Date();\n const diff = now.getTime() - this.lastKeyStroke.getTime();\n if (diff > 1000 && this.isTyping) {\n logChatPromiseExecution(this.stopTyping(), 'stop typing event');\n }\n }\n\n this.state.clean();\n }\n\n /**\n * Subscribes to realtime events (WebSocket) for this channel, grabs the latest available metadata,\n * loads the most recent messages, and initializes the local state.\n *\n * @param options - Pagination limits like `{ watch: true, presence: true, state: true }`.\n * @returns The synchronized comprehensive channel state.\n */\n async watch(options?: ChannelQueryOptions) {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n const combined = { ...options };\n const state = await this.query(combined, 'latest');\n this.initialized = true;\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this.getClient(), state.channel.members);\n\n // Get the latest users after updating\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.channel.image =\n state.channel.type === 'messaging'\n ? getDirectChannelImage(state.channel.members, this.getClient().userID || '')\n : state.channel.image;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n\n // Process topics for team channels (already handled in query, but ensuring consistency)\n if (this.type === 'team' && state.channel.topics_enabled) {\n const payload = {\n filter_conditions: { type: ['topic'], parent_cid: this.cid, project_id: this.getClient().projectId },\n sort: [],\n message_limit: 25,\n };\n const topicsFromApi: any = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(\n this.getClient().baseURL + '/channels',\n payload,\n );\n\n this._processTopics(topicsFromApi.channels || [], users);\n }\n\n this.data = state.channel;\n\n this._client.logger('info', `channel:watch() - started watching channel ${this.cid}`, {\n tags: ['channel'],\n channel: this,\n });\n return state;\n }\n\n lastRead() {\n const { userID } = this.getClient();\n if (userID) {\n return this.state.read[userID] ? this.state.read[userID].last_read : null;\n }\n }\n // TODO: KhoaKheu Add mute Users later, confict here\n _countMessageAsUnread(message: FormatMessageResponse<ErmisChatGenerics> | MessageResponse<ErmisChatGenerics>) {\n if (message.parent_id && !message.show_in_channel) return false;\n if (message.user?.id === this.getClient().userID) return false;\n if (message.type === 'system') return false;\n\n // Return false if channel doesn't allow read events.\n if (Array.isArray(this.data?.own_capabilities) && !this.data?.own_capabilities.includes('read-events'))\n return false;\n\n return true;\n }\n\n countUnread(lastRead?: Date | null) {\n if (!lastRead) return this.state.unreadCount;\n\n let count = 0;\n for (let i = 0; i < this.state.latestMessages.length; i += 1) {\n const message = this.state.latestMessages[i];\n if (message.created_at > lastRead && this._countMessageAsUnread(message)) {\n count++;\n }\n }\n return count;\n }\n\n getUnreadMemberCount() {\n if (!this.state.read) return [];\n\n return Object.values(this.state.read);\n }\n\n getCapabilitiesMember() {\n if (!this.data) return [];\n\n return this.data.member_capabilities;\n }\n\n create = async () => {\n if (this.type === 'messaging') {\n return await this.createDirectChannel('latest');\n } else {\n return await this.query({}, 'latest');\n }\n };\n\n async createTopic(data: any) {\n const project_id = this._client.projectId;\n const uuid = randomId();\n const topicID = `${project_id}:${uuid}`;\n\n const queryURL = `${this.getClient().baseURL}/channels/topic/${topicID}`;\n const payload: any = {\n project_id,\n parent_cid: this.cid,\n data: { ...data },\n };\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n\n return state;\n }\n\n async query(options: ChannelQueryOptions, messageSetToAddToIfDoesNotExist: MessageSetType = 'current') {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let update_options = { ...options, project_id };\n\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}`;\n if (this.id) {\n queryURL += `/${this.id}`;\n } else {\n if (this.type === 'team') {\n const uuid = randomId();\n this.id = `${project_id}:${uuid}`;\n queryURL += `/${this.id}`;\n }\n }\n\n const payload: any = {\n state: true,\n ...update_options,\n };\n\n if (this._data && Object.keys(this._data).length > 0) {\n payload.data = this._data;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n // Ensure all members' user info are loaded in state.users\n await ensureMembersUserInfoLoaded(this.getClient(), state.channel.members);\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.channel.image =\n state.channel.type === 'messaging'\n ? getDirectChannelImage(state.channel.members, this.getClient().userID || '')\n : state.channel.image;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n state.channel.is_pinned = state.is_pinned || false;\n\n // Process topics for team channels\n // if (this.type === 'team' && state.channel.topics_enabled && state.topics) {\n // this._processTopics(state.topics, users);\n // }\n\n // update the channel id if it was missing\n\n if (!this.id) {\n this.id = state.channel.id;\n this.cid = state.channel.cid;\n\n // set the channel as active...\n const membersStr = state.channel.members\n .map((member) => member.user_id || member.user?.id)\n .sort()\n .join(',');\n const tempChannelCid = `${this.type}:!members-${membersStr}`;\n\n if (tempChannelCid in this.getClient().activeChannels) {\n // This gets set in `client.channel()` function, when channel is created\n // using members, not id.\n delete this.getClient().activeChannels[tempChannelCid];\n }\n\n if (!(this.cid in this.getClient().activeChannels)) {\n this.getClient().activeChannels[this.cid] = this;\n }\n }\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: this.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n return state;\n }\n\n async createDirectChannel(messageSetToAddToIfDoesNotExist: MessageSetType = 'current') {\n // Make sure we wait for the connect promise if there is a pending one\n await this.getClient().wsPromise;\n\n const project_id = this._client.projectId;\n\n const queryURL = `${this.getClient().baseURL}/channels/${this.type}`;\n\n const payload: any = {\n project_id,\n };\n\n if (this._data && Object.keys(this._data).length > 0) {\n payload.data = this._data;\n }\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', payload);\n\n const users = Object.values(this.getClient().state.users);\n state.channel.members = enrichWithUserInfo(state.channel.members, users);\n state.channel.name =\n state.channel.type === 'messaging'\n ? getDirectChannelName(state.channel.members, this.getClient().userID || '')\n : state.channel.name;\n state.messages = enrichWithUserInfo(state.messages, users);\n state.pinned_messages = state.pinned_messages ? enrichWithUserInfo(state.pinned_messages, users) : [];\n state.read = enrichWithUserInfo(state.read || [], users);\n\n // add any messages to our channel state\n const { messageSet } = this._initializeState(state, messageSetToAddToIfDoesNotExist);\n\n const areCapabilitiesChanged =\n [...(state.channel.own_capabilities || [])].sort().join() !==\n [...(Array.isArray(this.data?.own_capabilities) ? (this.data?.own_capabilities as string[]) : [])].sort().join();\n this.data = state.channel;\n this.offlineMode = false;\n\n if (areCapabilitiesChanged) {\n this.getClient().dispatchEvent({\n type: 'capabilities.changed',\n cid: state.channel.cid,\n own_capabilities: state.channel.own_capabilities,\n });\n }\n\n return state;\n }\n\n async queryMessagesLessThanId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_lt: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async queryMessagesGreaterThanId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_gt: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async queryMessagesAroundId(message_id: string, limit: number = 25) {\n await this.getClient().wsPromise;\n\n let project_id = this._client.projectId;\n let queryURL = `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n\n const state = await this.getClient().post<QueryChannelAPIResponse<ErmisChatGenerics>>(queryURL + '/query', {\n // data: this._data,\n state: true,\n project_id,\n messages: { limit, id_around: message_id },\n });\n\n const users = Object.values(this.getClient().state.users);\n state.messages = enrichWithUserInfo(state.messages, users);\n if (state.messages && state.messages.length > 0) {\n for (const msg of state.messages) {\n if (!msg.pinned) {\n const pm = this.state.pinnedMessages?.find((p) => p.id === msg.id);\n if (pm) {\n msg.pinned = true;\n const pmDate = pm.pinned_at || new Date();\n msg.pinned_at = typeof pmDate === 'string' ? pmDate : pmDate.toISOString();\n }\n }\n }\n this.state.addMessagesSorted(state.messages, false, true, true, 'current');\n }\n return state.messages;\n }\n\n async deleteMessage(messageId: string) {\n return await this.getClient().delete<APIResponse & { message: MessageResponse<ErmisChatGenerics> }>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageId}`,\n );\n }\n\n async deleteMessageForMe(messageId: string) {\n return await this.getClient().delete<APIResponse & { message: MessageResponse<ErmisChatGenerics> }>(\n this.getClient().baseURL + `/messages/${this.type}/${this.id}/${messageId}`,\n { for_me: true },\n );\n }\n\n async getThumbBlobVideo(file: File): Promise<Blob | null> {\n return new Promise((resolve) => {\n const seekTo = 0.1;\n const videoPlayer = document.createElement('video');\n videoPlayer.src = URL.createObjectURL(file);\n videoPlayer.crossOrigin = 'anonymous'; // Tránh lỗi CORS nếu cần\n videoPlayer.load();\n\n videoPlayer.addEventListener('error', () => {\n console.error('Error when loading video file.');\n resolve(null);\n });\n\n videoPlayer.addEventListener('loadedmetadata', () => {\n if (videoPlayer.duration < seekTo) {\n console.error('Video is too short.');\n resolve(null);\n return;\n }\n\n setTimeout(() => {\n videoPlayer.currentTime = seekTo;\n }, 200);\n });\n\n videoPlayer.addEventListener('seeked', () => {\n try {\n const canvas = document.createElement('canvas');\n canvas.width = videoPlayer.videoWidth;\n canvas.height = videoPlayer.videoHeight;\n const ctx = canvas.getContext('2d');\n\n if (!ctx) {\n console.error('Failed to create canvas context.');\n resolve(null);\n return;\n }\n\n ctx.drawImage(videoPlayer, 0, 0, canvas.width, canvas.height);\n\n ctx.canvas.toBlob(\n (blob) => {\n if (!blob) {\n console.error('Failed to generate thumbnail.');\n resolve(null);\n return;\n }\n resolve(blob);\n URL.revokeObjectURL(videoPlayer.src); // Giải phóng bộ nhớ\n },\n 'image/jpeg',\n 0.75,\n );\n } catch (error) {\n console.error('Error while extracting thumbnail:', error);\n resolve(null);\n }\n });\n });\n }\n\n async enableTopics() {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/enable`, {\n project_id: this.getClient().projectId,\n messages: { limit: 25 },\n });\n }\n\n async disableTopics() {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/disable`, {\n project_id: this.getClient().projectId,\n });\n }\n\n async closeTopic(topicCID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/close`, {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n });\n }\n\n async reopenTopic(topicCID: string) {\n return await this.getClient().post(this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics/reopen`, {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n });\n }\n\n async editTopic(topicCID: string, data: any) {\n const response: any = await this.getClient().post(\n this.getClient().baseURL + `/channels/${this.type}/${this.id}/topics`,\n {\n project_id: this.getClient().projectId,\n topic_cid: topicCID,\n data,\n },\n );\n\n if (response) {\n const activeTopic = this.getClient().activeChannels[topicCID];\n\n if (activeTopic) {\n activeTopic.data = response.channel;\n return activeTopic.data;\n } else {\n return response.channel;\n }\n }\n }\n\n on(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(callback: EventHandler<ErmisChatGenerics>): { unsubscribe: () => void };\n on(\n callbackOrString: EventHandler<ErmisChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): { unsubscribe: () => void } {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n this._client.logger('info', `Attaching listener for ${key} event on channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key].push(callback);\n\n return {\n unsubscribe: () => {\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n\n this.listeners[key] = this.listeners[key].filter((el) => el !== callback);\n },\n };\n }\n\n off(eventType: EventTypes, callback: EventHandler<ErmisChatGenerics>): void;\n off(callback: EventHandler<ErmisChatGenerics>): void;\n off(\n callbackOrString: EventHandler<ErmisChatGenerics> | EventTypes,\n callbackOrNothing?: EventHandler<ErmisChatGenerics>,\n ): void {\n const key = callbackOrNothing ? (callbackOrString as string) : 'all';\n const callback = callbackOrNothing ? callbackOrNothing : callbackOrString;\n if (!(key in this.listeners)) {\n this.listeners[key] = [];\n }\n\n this._client.logger('info', `Removing listener for ${key} event from channel ${this.cid}`, {\n tags: ['event', 'channel'],\n channel: this,\n });\n this.listeners[key] = this.listeners[key].filter((value) => value !== callback);\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n async _handleChannelEvent(event: Event<ErmisChatGenerics>) {\n const channel = this;\n this._client.logger(\n 'info',\n `channel:_handleChannelEvent - Received event of type { ${event.type} } on ${this.cid}`,\n {\n tags: ['event', 'channel'],\n channel: this,\n },\n );\n\n const channelState = channel.state;\n const users = Object.values(this.getClient().state.users);\n switch (event.type) {\n case 'typing.start':\n if (event.user?.id) {\n const user = getUserInfo(event.user.id || '', users);\n event.user = user;\n channelState.typing[event.user.id] = event;\n }\n break;\n case 'typing.stop':\n if (event.user?.id) {\n delete channelState.typing[event.user.id];\n }\n break;\n case 'message.read':\n if (event.user?.id && event.created_at) {\n const user = getUserInfo(event.user.id || '', users);\n event.user = user;\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at),\n last_read_message_id: event.last_read_message_id,\n user,\n unread_messages: 0,\n };\n\n if (event.user?.id === this.getClient().user?.id) {\n channelState.unreadCount = 0;\n }\n }\n break;\n case 'user.watching.start':\n if (event.user?.id) {\n channelState.watchers[event.user.id] = event.user;\n }\n break;\n case 'user.watching.stop':\n if (event.user?.id) {\n delete channelState.watchers[event.user.id];\n }\n break;\n case 'message.deleted':\n if (event.message) {\n this._extendEventWithOwnReactions(event);\n //! NOTE: check lai o day\n channelState.removeMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n // if (event.hard_delete) channelState.removeMessage(event.message);\n // else channelState.addMessageSorted(event.message, false, false);\n\n channelState.removeQuotedMessageReferences(event.message);\n\n // if (event.message.pinned) {\n // channelState.removePinnedMessage(event.message);\n // }\n\n if ([...channelState.pinnedMessages].some((msg) => msg.id === event.message?.id)) {\n channelState.removePinnedMessage(event.message);\n }\n\n for (const userId in channelState.read) {\n if (userId !== event.user?.id && event.message.id === channelState.read[userId].last_read_message_id) {\n // Clear last_read_message_id if the deleted message is the last_read_message_id\n channelState.read[userId] = { ...channelState.read[userId], last_read_message_id: undefined };\n }\n }\n }\n break;\n case 'message.deleted_for_me':\n if (event.message) {\n channelState.removeMessage(event.message);\n channelState.removeQuotedMessageReferences(event.message);\n\n if ([...channelState.pinnedMessages].some((msg) => msg.id === event.message?.id)) {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.new':\n if (event.message) {\n /* if message belongs to current user, always assume timestamp is changed to filter it out and add again to avoid duplication */\n const ownMessage = event.user?.id === this.getClient().user?.id;\n const isThreadMessage = !!event.message.parent_id;\n\n const existUser = users.find((user) => user.id === event.user?.id);\n if (!existUser) {\n if (event.user?.id) {\n const resUser = await this.getClient().queryUser(event.user.id);\n users.push(resUser);\n }\n }\n\n const userInfo = getUserInfo(event.user?.id || '', users);\n event.message.user = userInfo;\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.user = userInfo;\n\n if (this.state.isUpToDate || isThreadMessage) {\n channelState.addMessageSorted(event.message, ownMessage);\n }\n // if (event.message.pinned) {\n // channelState.addPinnedMessage(event.message);\n // }\n\n // do not increase the unread count - the back-end does not increase the count neither in the following cases:\n // 1. the message is mine\n // 2. the message is a thread reply from any user\n const preventUnreadCountUpdate = ownMessage || isThreadMessage;\n if (preventUnreadCountUpdate) break;\n\n if (event.user?.id) {\n for (const userId in channelState.read) {\n if (userId === event.user.id) {\n channelState.read[event.user.id] = {\n last_read: new Date(event.created_at as string),\n user: event.user,\n unread_messages: 0,\n };\n } else {\n channelState.read[userId].unread_messages += 1;\n }\n }\n }\n\n if (this._countMessageAsUnread(event.message)) {\n channelState.unreadCount = channelState.unreadCount + 1;\n }\n }\n break;\n case 'message.updated':\n if (event.message) {\n const userEvent = getUserInfo(event.user?.id || '', users);\n const userMsg = getUserInfo(event.message.user?.id || '', users);\n event.user = userEvent;\n event.message.user = userMsg;\n\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n\n if (event.message?.latest_reactions) {\n event.message.latest_reactions = enrichWithUserInfo(event.message.latest_reactions || [], users);\n }\n\n this._extendEventWithOwnReactions(event);\n channelState.addMessageSorted(event.message, false, false);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n } else {\n channelState.removePinnedMessage(event.message);\n }\n }\n break;\n case 'message.pinned':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.addPinnedMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'message.unpinned':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.removePinnedMessage(event.message);\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'channel.truncate':\n if (event.channel?.created_at) {\n const truncatedAt = +new Date(event.channel.created_at);\n\n channelState.messageSets.forEach((messageSet, messageSetIndex) => {\n messageSet.messages.forEach(({ created_at: createdAt, id }) => {\n if (truncatedAt > +createdAt) channelState.removeMessage({ id, messageSetIndex });\n });\n });\n\n channelState.pinnedMessages.forEach(({ id, created_at: createdAt }) => {\n if (truncatedAt > +createdAt)\n channelState.removePinnedMessage({ id } as MessageResponse<ErmisChatGenerics>);\n });\n } else {\n channelState.clearMessages();\n }\n\n channelState.unreadCount = 0;\n // system messages don't increment unread counts\n if (event.message) {\n channelState.addMessageSorted(event.message);\n if (event.message.pinned) {\n channelState.addPinnedMessage(event.message);\n }\n }\n break;\n case 'member.added':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n channelState.members[event.member.user_id] = event.member;\n\n if (event.member.user?.id === this.getClient().user?.id) {\n channelState.membership = event.member;\n }\n }\n break;\n case 'member.updated':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n channelState.members[event.member.user_id] = event.member;\n channelState.membership = event.member;\n }\n break;\n case 'member.removed':\n if (event.member?.user_id) {\n delete channelState.members[event.member.user_id];\n } else if (event.user?.id) {\n // fallback just in case some legacy payload uses event.user for the removed user\n delete channelState.members[event.user.id];\n }\n break;\n case 'channel.updated':\n if (event.channel) {\n channel.data = {\n ...channel.data,\n ...event.channel,\n own_capabilities: event.channel?.own_capabilities ?? channel.data?.own_capabilities,\n };\n }\n break;\n case 'pollchoice.new':\n if (event.message) {\n const user = getUserInfo(event.message.user?.id || '', users);\n event.message.user = user;\n channelState.addMessageSorted(event.message, false, false);\n }\n break;\n case 'reaction.new':\n if (event.message && event.reaction) {\n const userMsg = getUserInfo(event.message.user?.id || '', users);\n const userReaction = getUserInfo(event.reaction.user?.id || '', users);\n event.message.user = userMsg;\n event.message.latest_reactions = enrichWithUserInfo(event.message.latest_reactions || [], users);\n event.reaction.user = userReaction;\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.message = channelState.addReaction(event.reaction, event.message);\n }\n break;\n case 'reaction.deleted':\n event.user = getUserInfo(event.user?.id || '', users);\n if (event.message) {\n if (event.message?.quoted_message) {\n const quotedUser = getUserInfo(event.message.quoted_message.user?.id || '', users);\n event.message.quoted_message.user = quotedUser;\n }\n event.message.user = getUserInfo(event.message.user?.id || '', users);\n event.message.latest_reactions?.map((item) => {\n item.user = getUserInfo(item.user?.id || '', users);\n return item;\n });\n }\n\n if (event.reaction) {\n event.reaction.user = getUserInfo(event.reaction.user?.id || '', users);\n event.message = channelState.removeReaction(event.reaction, event.message);\n }\n break;\n case 'member.joined':\n case 'notification.invite_accepted':\n if (event.member?.user_id) {\n const existUser = users.find((user) => user.id === event.member?.user_id);\n\n if (!existUser) {\n const resUser = await this.getClient().queryUser(event.member?.user_id);\n users.push(resUser);\n }\n\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n\n channelState.members[event.member.user_id] = event.member;\n channel.data = {\n ...channel.data,\n member_count: Number(channel.data?.member_count) + 1,\n members: channel.data?.members ? [...channel.data.members, event.member] : [event.member],\n } as ChannelAPIResponse<ErmisChatGenerics>['channel'];\n this.offlineMode = true;\n this.initialized = true;\n }\n break;\n case 'notification.invite_rejected':\n if (event.member?.user_id) {\n delete channelState.members[event.member.user_id];\n\n // channel.data = {\n // ...channel.data,\n // member_count: Number(channel.data?.member_count) - 1,\n // members: channel.data?.members?.filter((m: any) => m.user_id !== event.member?.user_id) || [],\n // } as ChannelAPIResponse<ErmisChatGenerics>['channel'];\n }\n break;\n case 'notification.invite_messaging_skipped':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n\n channelState.members[event.member.user_id] = event.member;\n\n // this.offlineMode = true;\n // this.initialized = true;\n }\n break;\n case 'member.promoted':\n case 'member.demoted':\n case 'member.banned':\n case 'member.unbanned':\n case 'member.blocked':\n case 'member.unblocked':\n if (event.member?.user_id) {\n const user = getUserInfo(event.member.user_id, users);\n event.member.user = user;\n channelState.members[event.member.user_id] = event.member;\n if (event.member.user_id === this.getClient().user?.id) {\n channelState.membership = event.member;\n this.state.membership = event.member;\n }\n }\n break;\n case 'channel.pinned':\n if (channel.data) {\n channel.data.is_pinned = true;\n }\n break;\n case 'channel.unpinned':\n if (channel.data) {\n channel.data.is_pinned = false;\n }\n break;\n case 'channel.topic.disabled':\n if (channel.data) {\n channel.data.topics_enabled = false;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.enabled':\n if (channel.data) {\n channel.data.topics_enabled = true;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.created':\n const members = event.channel?.members || [];\n const enrichedMembers = enrichWithUserInfo(members, users);\n\n const topicState: any = {\n channel: event.channel,\n members: enrichedMembers,\n messages: [],\n pinned_messages: [],\n };\n const topic = this.getClient().channel(event.channel_type || '', event.channel_id || '');\n topic.data = event.channel;\n topic._initializeState(topicState, 'latest');\n channelState.topics?.unshift(topic);\n break;\n case 'channel.topic.closed':\n if (channel.data) {\n channel.data.is_closed_topic = true;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.reopen':\n if (channel.data) {\n channel.data.is_closed_topic = false;\n }\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n case 'channel.topic.updated':\n if (channel.data) {\n channel.data.name = event.channel?.name;\n channel.data.image = event.channel?.image;\n channel.data.description = event.channel?.description;\n }\n\n event.user = getUserInfo(event.user?.id || '', users);\n break;\n default:\n }\n\n // any event can send over the online count\n if (event.watcher_count !== undefined) {\n channel.state.watcher_count = event.watcher_count;\n }\n }\n\n _callChannelListeners = (event: Event<ErmisChatGenerics>) => {\n const channel = this;\n // gather and call the listeners\n const listeners = [];\n if (channel.listeners.all) {\n listeners.push(...channel.listeners.all);\n }\n if (channel.listeners[event.type]) {\n listeners.push(...channel.listeners[event.type]);\n }\n\n // call the event and send it to the listeners\n for (const listener of listeners) {\n if (typeof listener !== 'string') {\n listener(event);\n }\n }\n };\n\n _channelURL = () => {\n if (!this.id) {\n throw new Error('channel id is not defined');\n }\n return `${this.getClient().baseURL}/channels/${this.type}/${this.id}`;\n };\n\n _checkInitialized() {\n if (!this.initialized && !this.offlineMode) {\n throw Error(\n `Channel ${this.cid} hasn't been initialized yet. Make sure to call .watch() and wait for it to resolve`,\n );\n }\n }\n\n // eslint-disable-next-line sonarjs/cognitive-complexity\n _initializeState(\n state: ChannelAPIResponse<ErmisChatGenerics>,\n messageSetToAddToIfDoesNotExist: MessageSetType = 'latest',\n updateUserIds?: (id: string) => void,\n ) {\n const { state: clientState, user, userID } = this.getClient();\n // add the Users\n if (state.channel.members) {\n for (const member of state.channel.members) {\n if (member.user) {\n if (updateUserIds) {\n updateUserIds(member.user.id);\n }\n clientState.updateUserReference(member.user, this.cid);\n }\n }\n }\n\n this.state.membership = state.membership || {};\n\n // Remove duplicate messages by ID\n const map = new Map();\n const uniqueMessages = [];\n\n if (!state.messages) {\n state.messages = [];\n }\n for (const msg of state.messages) {\n if (!map.has(msg.id)) {\n map.set(msg.id, true);\n uniqueMessages.push(msg);\n }\n }\n\n if (this.state.pinnedMessages) {\n this.state.pinnedMessages = [];\n }\n this.state.addPinnedMessages(state.pinned_messages || []);\n\n const messages = uniqueMessages || [];\n if (!this.state.messages) {\n this.state.initMessages();\n }\n const { messageSet } = this.state.addMessagesSorted(messages, false, true, true, messageSetToAddToIfDoesNotExist);\n\n if (state.watcher_count !== undefined) {\n this.state.watcher_count = state.watcher_count;\n }\n // NOTE: we don't send the watchers with the channel data anymore\n // // convert the arrays into objects for easier syncing...\n if (state.watchers) {\n for (const watcher of state.watchers) {\n if (watcher) {\n clientState.updateUserReference(watcher, this.cid);\n this.state.watchers[watcher.id] = watcher;\n }\n }\n }\n\n // initialize read state to last message or current time if the channel is empty\n // if the user is a member, this value will be overwritten later on otherwise this ensures\n // that everything up to this point is not marked as unread\n if (userID != null) {\n const last_read = this.state.last_message_at || new Date();\n if (user) {\n this.state.read[user.id] = {\n user,\n last_read,\n unread_messages: 0,\n };\n }\n }\n\n // apply read state if part of the state\n if (state.read) {\n for (const read of state.read) {\n this.state.read[read.user.id] = {\n last_read: new Date(read.last_read),\n last_read_message_id: read.last_read_message_id,\n unread_messages: read.unread_messages ?? 0,\n user: read.user,\n last_send: read.last_send,\n };\n\n if (read.user.id === user?.id) {\n this.state.unreadCount = this.state.read[read.user.id].unread_messages;\n }\n }\n }\n\n if (state.channel.members) {\n this.state.members = state.channel.members.reduce((acc, member) => {\n if (member.user) {\n acc[member.user.id] = member;\n }\n return acc;\n }, {} as ChannelState<ErmisChatGenerics>['members']);\n }\n\n // Process topics for team channels\n if (state.channel.type === 'team' && state.channel.topics_enabled && state.topics) {\n const users = Object.values(this.getClient().state.users);\n this._processTopics(state.topics, users);\n }\n\n return {\n messageSet,\n };\n }\n\n _extendEventWithOwnReactions(event: Event<ErmisChatGenerics>) {\n if (!event.message) {\n return;\n }\n const message = this.state.findMessage(event.message.id, event.message.parent_id);\n if (message) {\n event.message.own_reactions = message.own_reactions;\n }\n }\n\n _disconnect() {\n this._client.logger('info', `channel:disconnect() - Disconnecting the channel ${this.cid}`, {\n tags: ['connection', 'channel'],\n channel: this,\n });\n\n this.disconnected = true;\n this.state.setIsUpToDate(false);\n }\n}\n","import { UserResponse, ExtendableGenerics, DefaultGenerics } from './types';\n\n/**\n * ClientState - A container class for the client state.\n */\nexport class ClientState<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n users: {\n [key: string]: UserResponse<ErmisChatGenerics>;\n };\n userChannelReferences: { [key: string]: { [key: string]: boolean } };\n constructor() {\n // show the status for a certain user...\n // ie online, offline etc\n this.users = {};\n // store which channels contain references to the specified user...\n this.userChannelReferences = {};\n }\n\n updateUsers(users: UserResponse<ErmisChatGenerics>[]) {\n for (const user of users) {\n this.updateUser(user);\n }\n }\n\n updateUser(user?: UserResponse<ErmisChatGenerics>) {\n if (user != null) {\n if (this.users[user.id]) {\n // Update existing user's fields, because the user is updated from 2 diffferent servers\n const updatedUser = { ...this.users[user.id], ...user };\n this.users[user.id] = updatedUser;\n } else {\n // Add new user\n this.users[user.id] = user;\n }\n }\n }\n\n updateUserReference(user: UserResponse<ErmisChatGenerics>, channelID: string) {\n if (user == null) {\n return;\n }\n // dont update user here\n // this.updateUser(user);\n if (!this.userChannelReferences[user.id]) {\n this.userChannelReferences[user.id] = {};\n }\n this.userChannelReferences[user.id][channelID] = true;\n }\n\n deleteAllChannelReference(channelID: string) {\n for (const userID in this.userChannelReferences) {\n delete this.userChannelReferences[userID][channelID];\n }\n }\n}\n","import WebSocket from 'isomorphic-ws';\nimport {\n chatCodes,\n sleep,\n retryInterval,\n randomId,\n removeConnectionEventListeners,\n addConnectionEventListeners,\n} from './utils';\n\nimport { ConnectAPIResponse, ConnectionOpen, ExtendableGenerics, DefaultGenerics, UR, LogLevel } from './types';\nimport { ErmisChat } from './client';\n\n// Type guards to check WebSocket error type\nconst isCloseEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.CloseEvent =>\n (res as WebSocket.CloseEvent).code !== undefined;\n\nconst isErrorEvent = (res: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent): res is WebSocket.ErrorEvent =>\n (res as WebSocket.ErrorEvent).error !== undefined;\n\n/**\n * StableWSConnection - A WS connection that reconnects upon failure.\n * - the browser will sometimes report that you're online or offline\n * - the WS connection can break and fail (there is a 30s health check)\n * - sometimes your WS connection will seem to work while the user is in fact offline\n * - to speed up online/offline detection you can use the window.addEventListener('offline');\n *\n * There are 4 ways in which a connection can become unhealthy:\n * - websocket.onerror is called\n * - websocket.onclose is called\n * - the health check fails and no event is received for ~40 seconds\n * - the browser indicates the connection is now offline\n *\n * There are 2 assumptions we make about the server:\n * - state can be recovered by querying the channel again\n * - if the servers fails to publish a message to the client, the WS connection is destroyed\n */\nexport class StableWSConnection<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n // global from constructor\n client: ErmisChat<ErmisChatGenerics>;\n\n // local vars\n\n connectionOpen?: ConnectAPIResponse<ErmisChatGenerics>;\n consecutiveFailures: number;\n pingInterval: number;\n healthCheckTimeoutRef?: NodeJS.Timeout;\n isConnecting: boolean;\n isDisconnected: boolean;\n isHealthy: boolean;\n isResolved?: boolean;\n lastEvent: Date | null;\n connectionCheckTimeout: number;\n connectionCheckTimeoutRef?: NodeJS.Timeout;\n rejectPromise?: (\n reason?: Error & { code?: string | number; isWSFailure?: boolean; StatusCode?: string | number },\n ) => void;\n requestID: string | undefined;\n resolvePromise?: (value: ConnectionOpen<ErmisChatGenerics>) => void;\n totalFailures: number;\n ws?: WebSocket;\n wsID: number;\n\n constructor({ client }: { client: ErmisChat<ErmisChatGenerics> }) {\n /** ErmisChat client */\n this.client = client;\n /** consecutive failures influence the duration of the timeout */\n this.consecutiveFailures = 0;\n /** keep track of the total number of failures */\n this.totalFailures = 0;\n /** We only make 1 attempt to reconnect at the same time.. */\n this.isConnecting = false;\n /** To avoid reconnect if client is disconnected */\n this.isDisconnected = false;\n /** Boolean that indicates if the connection promise is resolved */\n this.isResolved = false;\n /** Boolean that indicates if we have a working connection to the server */\n this.isHealthy = false;\n /** Incremented when a new WS connection is made */\n this.wsID = 1;\n /** Store the last event time for health checks */\n this.lastEvent = null;\n /** Send a health check message every 25 seconds */\n this.pingInterval = 25 * 1000;\n this.connectionCheckTimeout = this.pingInterval + 10 * 1000;\n\n addConnectionEventListeners(this.onlineStatusChanged);\n }\n\n _log(msg: string, extra: UR = {}, level: LogLevel = 'info') {\n this.client.logger(level, 'connection:' + msg, { tags: ['connection'], ...extra });\n }\n\n setClient(client: ErmisChat<ErmisChatGenerics>) {\n this.client = client;\n }\n\n async connect(timeout = 15000) {\n if (this.isConnecting) {\n throw Error(`You've called connect twice, can only attempt 1 connection at the time`);\n }\n\n this.isDisconnected = false;\n\n try {\n const healthCheck = await this._connect();\n this.consecutiveFailures = 0;\n\n this._log(`connect() - Established ws connection with healthcheck: ${healthCheck}`);\n } catch (error: any) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n if (error.code === chatCodes.TOKEN_EXPIRED) {\n this._log('connect() - WS failure due to expired token');\n } else if (!error.isWSFailure) {\n // API rejected the connection and we should not retry\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n }\n\n return await this._waitForHealthy(timeout);\n }\n\n /**\n * _waitForHealthy polls the promise connection to see if its resolved until it times out\n * the default 15s timeout allows between 2~3 tries\n * @param timeout duration(ms)\n */\n async _waitForHealthy(timeout = 15000) {\n return Promise.race([\n (async () => {\n const interval = 50; // ms\n for (let i = 0; i <= timeout; i += interval) {\n try {\n return await this.connectionOpen;\n } catch (error: any) {\n if (i === timeout) {\n throw new Error(\n JSON.stringify({\n code: error.code,\n StatusCode: error.StatusCode,\n message: error.message,\n isWSFailure: error.isWSFailure,\n }),\n );\n }\n await sleep(interval);\n }\n }\n })(),\n (async () => {\n await sleep(timeout);\n this.isConnecting = false;\n throw new Error(\n JSON.stringify({\n code: '',\n StatusCode: '',\n message: 'initial WS connection could not be established',\n isWSFailure: true,\n }),\n );\n })(),\n ]);\n }\n\n /**\n * Builds and returns the url for websocket.\n * @private\n * @returns url string\n */\n _buildUrl = () => {\n const qs = encodeURIComponent(this.client._buildWSPayload(this.requestID));\n const token = this.client.tokenManager.getToken();\n\n let rawURL = `${this.client.wsBaseURL}/connect?json=${qs}&api_key=${\n this.client.apiKey\n }&authorization=${token}&stream-auth-type=${this.client.getAuthType()}&X-Stream-Client=${this.client.getUserAgent()}`;\n rawURL = encodeURI(rawURL);\n return rawURL;\n };\n\n /**\n * disconnect - Disconnect the connection and doesn't recover...\n *\n */\n disconnect(timeout?: number) {\n this._log(`disconnect() - Closing the websocket connection for wsID ${this.wsID}`);\n\n this.wsID += 1;\n this.isConnecting = false;\n this.isDisconnected = true;\n\n // start by removing all the listeners\n if (this.healthCheckTimeoutRef) {\n clearInterval(this.healthCheckTimeoutRef);\n }\n if (this.connectionCheckTimeoutRef) {\n clearInterval(this.connectionCheckTimeoutRef);\n }\n\n removeConnectionEventListeners(this.onlineStatusChanged);\n\n this.isHealthy = false;\n\n // remove ws handlers...\n if (this.ws && this.ws.removeAllListeners) {\n this.ws.removeAllListeners();\n }\n\n let isClosedPromise: Promise<void>;\n // and finally close...\n // Assigning to local here because we will remove it from this before the\n // promise resolves.\n const { ws } = this;\n if (ws && ws.close && ws.readyState === ws.OPEN) {\n isClosedPromise = new Promise((resolve) => {\n const onclose = (event: WebSocket.CloseEvent) => {\n this._log(`disconnect() - resolving isClosedPromise ${event ? 'with' : 'without'} close frame`, { event });\n resolve();\n };\n\n ws.onclose = onclose;\n // In case we don't receive close frame websocket server in time,\n // lets not wait for more than 1 seconds.\n setTimeout(onclose, timeout != null ? timeout : 1000);\n });\n\n this._log(`disconnect() - Manually closed connection by calling client.disconnect()`);\n\n ws.close(chatCodes.WS_CLOSED_SUCCESS, 'Manually closed connection by calling client.disconnect()');\n } else {\n this._log(`disconnect() - ws connection doesn't exist or it is already closed.`);\n isClosedPromise = Promise.resolve();\n }\n\n delete this.ws;\n\n return isClosedPromise;\n }\n\n async _connect() {\n if (this.isConnecting) return; // simply ignore _connect if it's currently trying to connect\n this.isConnecting = true;\n this.requestID = randomId();\n\n let isTokenReady = false;\n try {\n this._log(`_connect() - waiting for token`);\n await this.client.tokenManager.tokenReady();\n isTokenReady = true;\n } catch (e) {\n // token provider has failed before, so try again\n }\n\n try {\n this._setupConnectionPromise();\n const wsURL = this._buildUrl();\n this._log(`_connect() - Connecting to ${wsURL}`, { wsURL, requestID: this.requestID });\n this.ws = new WebSocket(wsURL);\n this.ws.onopen = this.onopen.bind(this, this.wsID);\n this.ws.onclose = this.onclose.bind(this, this.wsID);\n this.ws.onerror = this.onerror.bind(this, this.wsID);\n this.ws.onmessage = this.onmessage.bind(this, this.wsID);\n const response = await this.connectionOpen;\n this.isConnecting = false;\n\n if (response) {\n return response;\n }\n } catch (err: any) {\n this.isConnecting = false;\n this._log(`_connect() - Error - `, err);\n\n throw err;\n }\n }\n\n /**\n * _reconnect - Retry the connection to WS endpoint\n *\n * @param {{ interval?: number; refreshToken?: boolean }} options Following options are available\n *\n * - `interval`\t{int}\t\t\tnumber of ms that function should wait before reconnecting\n * - `refreshToken` {boolean}\treload/refresh user token be refreshed before attempting reconnection.\n */\n async _reconnect(options: { interval?: number; refreshToken?: boolean } = {}): Promise<void> {\n this._log('_reconnect() - Initiating the reconnect');\n\n // only allow 1 connection at the time\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (1) since already connecting or healthy');\n return;\n }\n\n // reconnect in case of on error or on close\n // also reconnect if the health check cycle fails\n let interval = options.interval;\n if (!interval) {\n interval = retryInterval(this.consecutiveFailures);\n }\n // reconnect, or try again after a little while...\n await sleep(interval);\n\n // Check once again if by some other call to _reconnect is active or connection is\n // already restored, then no need to proceed.\n if (this.isConnecting || this.isHealthy) {\n this._log('_reconnect() - Abort (2) since already connecting or healthy');\n return;\n }\n\n if (this.isDisconnected) {\n this._log('_reconnect() - Abort (3) since disconnect() is called');\n return;\n }\n\n this._log('_reconnect() - Destroying current WS connection');\n\n // cleanup the old connection\n this._destroyCurrentWSConnection();\n\n try {\n await this._connect();\n this._log('_reconnect() - Waiting for recoverCallBack');\n await this.client.recoverState();\n this._log('_reconnect() - Finished recoverCallBack');\n\n this.consecutiveFailures = 0;\n } catch (error: any) {\n this.isHealthy = false;\n this.consecutiveFailures += 1;\n\n // reconnect on WS failures, don't reconnect if there is a code bug\n if (error.isWSFailure) {\n this._log('_reconnect() - WS failure, so going to try to reconnect');\n\n this._reconnect();\n }\n }\n this._log('_reconnect() - == END ==');\n }\n\n /**\n * onlineStatusChanged - this function is called when the browser connects or disconnects from the internet.\n *\n * @param {Event} event Event with type online or offline\n *\n */\n onlineStatusChanged = (event: Event) => {\n if (event.type === 'offline') {\n // mark the connection as down\n this._log('onlineStatusChanged() - Status changing to offline');\n this._setHealth(false);\n } else if (event.type === 'online') {\n // retry right now...\n // We check this.isHealthy, not sure if it's always\n // smart to create a new WS connection if the old one is still up and running.\n // it's possible we didn't miss any messages, so this process is just expensive and not needed.\n this._log(`onlineStatusChanged() - Status changing to online. isHealthy: ${this.isHealthy}`);\n if (!this.isHealthy) {\n this._reconnect({ interval: 10 });\n }\n }\n };\n\n onopen = (wsID: number) => {\n if (this.wsID !== wsID) return;\n\n this._log('onopen() - onopen callback', { wsID });\n };\n\n onmessage = (wsID: number, event: WebSocket.MessageEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onmessage() - onmessage callback', { event, wsID });\n const data = typeof event.data === 'string' ? JSON.parse(event.data) : null;\n\n // we wait till the first message before we consider the connection open..\n // the reason for this is that auth errors and similar errors trigger a ws.onopen and immediately\n // after that a ws.onclose..\n if (!this.isResolved && data) {\n this.isResolved = true;\n if (data.error) {\n this.rejectPromise?.(this._errorFromWSEvent(data, false));\n return;\n }\n\n this.resolvePromise?.(data);\n this._setHealth(true);\n }\n\n // trigger the event..\n this.lastEvent = new Date();\n\n if (data && data.type === 'health.check') {\n this.scheduleNextPing();\n }\n\n this.client.handleEvent(event);\n this.scheduleConnectionCheck();\n };\n\n onclose = (wsID: number, event: WebSocket.CloseEvent) => {\n if (this.wsID !== wsID) return;\n\n this._log('onclose() - onclose callback - ' + event.code, { event, wsID });\n\n if (event.code === chatCodes.WS_CLOSED_SUCCESS) {\n // this is a permanent error raised by stream..\n // usually caused by invalid auth details\n const error = new Error(`WS connection reject with error ${event.reason}`) as Error & WebSocket.CloseEvent;\n\n error.reason = event.reason;\n error.code = event.code;\n error.wasClean = event.wasClean;\n error.target = event.target;\n\n this.rejectPromise?.(error);\n this._log(`onclose() - WS connection reject with error ${event.reason}`, { event });\n } else {\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n\n this._log(`onclose() - WS connection closed. Calling reconnect ...`, { event });\n\n // reconnect if its an abnormal failure\n this._reconnect();\n }\n };\n\n onerror = (wsID: number, event: WebSocket.ErrorEvent) => {\n if (this.wsID !== wsID) return;\n\n this.consecutiveFailures += 1;\n this.totalFailures += 1;\n this._setHealth(false);\n this.isConnecting = false;\n\n this.rejectPromise?.(this._errorFromWSEvent(event));\n this._log(`onerror() - WS connection resulted into error`, { event });\n\n this._reconnect();\n };\n\n /**\n * _setHealth - Sets the connection to healthy or unhealthy.\n * Broadcasts an event in case the connection status changed.\n *\n * @param {boolean} healthy boolean indicating if the connection is healthy or not\n *\n */\n _setHealth = (healthy: boolean) => {\n if (healthy === this.isHealthy) return;\n\n this.isHealthy = healthy;\n\n if (this.isHealthy) {\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n return;\n }\n\n // we're offline, wait few seconds and fire and event if still offline\n setTimeout(() => {\n if (this.isHealthy) return;\n this.client.dispatchEvent({ type: 'connection.changed', online: this.isHealthy });\n }, 1000);\n };\n\n /**\n * _errorFromWSEvent - Creates an error object for the WS event\n *\n */\n _errorFromWSEvent = (event: WebSocket.CloseEvent | WebSocket.Data | WebSocket.ErrorEvent, isWSFailure = true) => {\n let code;\n let statusCode;\n let message;\n if (isCloseEvent(event)) {\n code = event.code;\n statusCode = 'unknown';\n message = event.reason;\n }\n\n if (isErrorEvent(event)) {\n code = event.error.code;\n statusCode = event.error.StatusCode;\n message = event.error.message;\n }\n\n // Keeping this `warn` level log, to avoid cluttering of error logs from ws failures.\n this._log(`_errorFromWSEvent() - WS failed with code ${code}`, { event }, 'warn');\n\n const error = new Error(`WS failed with code ${code} and reason - ${message}`) as Error & {\n code?: string | number;\n isWSFailure?: boolean;\n StatusCode?: string | number;\n };\n error.code = code;\n /**\n * StatusCode does not exist on any event types but has been left\n * as is to preserve JS functionality during the TS implementation\n */\n error.StatusCode = statusCode;\n error.isWSFailure = isWSFailure;\n return error;\n };\n\n /**\n * _destroyCurrentWSConnection - Removes the current WS connection\n *\n */\n _destroyCurrentWSConnection() {\n // increment the ID, meaning we will ignore all messages from the old\n // ws connection from now on.\n this.wsID += 1;\n\n try {\n this?.ws?.removeAllListeners();\n this?.ws?.close();\n } catch (e) {\n // we don't care\n }\n }\n\n /**\n * _setupPromise - sets up the this.connectOpen promise\n */\n _setupConnectionPromise = () => {\n this.isResolved = false;\n /** a promise that is resolved once ws.open is called */\n this.connectionOpen = new Promise<ConnectionOpen<ErmisChatGenerics>>((resolve, reject) => {\n this.resolvePromise = resolve;\n this.rejectPromise = reject;\n });\n };\n\n /**\n * Schedules a next health check ping for websocket.\n */\n scheduleNextPing = () => {\n if (this.healthCheckTimeoutRef) {\n clearTimeout(this.healthCheckTimeoutRef);\n }\n\n // 30 seconds is the recommended interval (messenger uses this)\n this.healthCheckTimeoutRef = setTimeout(() => {\n // send the healthcheck.., server replies with a health check event\n const data = [{ type: 'health.check', client_id: this.client.clientID }];\n // try to send on the connection\n try {\n this.ws?.send(JSON.stringify(data));\n } catch (e) {\n // error will already be detected elsewhere\n }\n }, this.pingInterval);\n };\n\n /**\n * scheduleConnectionCheck - schedules a check for time difference between last received event and now.\n * If the difference is more than 35 seconds, it means our health check logic has failed and websocket needs\n * to be reconnected.\n */\n scheduleConnectionCheck = () => {\n if (this.connectionCheckTimeoutRef) {\n clearTimeout(this.connectionCheckTimeoutRef);\n }\n\n this.connectionCheckTimeoutRef = setTimeout(() => {\n const now = new Date();\n if (this.lastEvent && now.getTime() - this.lastEvent.getTime() > this.connectionCheckTimeout) {\n this._log('scheduleConnectionCheck - going to reconnect');\n this._setHealth(false);\n this._reconnect();\n }\n }, this.connectionCheckTimeout);\n };\n}\n","import { ExtendableGenerics, DefaultGenerics, UserResponse } from './types';\n\n/**\n * TokenManager\n *\n * Manages token storage and retrieval for the chat client.\n */\nexport class TokenManager<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n loadTokenPromise: Promise<string> | null;\n token?: string;\n user?: UserResponse<ErmisChatGenerics>;\n\n constructor() {\n this.loadTokenPromise = null;\n }\n\n /**\n * Set the static string token.\n */\n setTokenOrProvider = async (tokenOrProvider: string | null, user: UserResponse<ErmisChatGenerics>) => {\n this.user = user;\n\n if (typeof tokenOrProvider === 'string') {\n this.token = tokenOrProvider;\n }\n\n this.loadTokenPromise = Promise.resolve(this.token as string);\n };\n\n /**\n * Resets the token manager.\n */\n reset = () => {\n this.token = undefined;\n this.user = undefined;\n this.loadTokenPromise = null;\n };\n\n /**\n * Resolves when token is ready.\n */\n tokenReady = () => this.loadTokenPromise;\n\n /** Returns the current token */\n getToken = () => {\n return this.token;\n };\n}\n","import { AxiosResponse } from 'axios';\nimport { APIErrorResponse } from './types';\n\nexport const APIErrorCodes: Record<string, { name: string; retryable: boolean }> = {\n '-1': { name: 'InternalSystemError', retryable: true },\n '2': { name: 'AccessKeyError', retryable: false },\n '3': { name: 'AuthenticationFailedError', retryable: true },\n '4': { name: 'InputError', retryable: false },\n '6': { name: 'DuplicateUsernameError', retryable: false },\n '9': { name: 'RateLimitError', retryable: true },\n '16': { name: 'DoesNotExistError', retryable: false },\n '17': { name: 'NotAllowedError', retryable: false },\n '18': { name: 'EventNotSupportedError', retryable: false },\n '19': { name: 'ChannelFeatureNotSupportedError', retryable: false },\n '20': { name: 'MessageTooLongError', retryable: false },\n '21': { name: 'MultipleNestingLevelError', retryable: false },\n '22': { name: 'PayloadTooBigError', retryable: false },\n '23': { name: 'RequestTimeoutError', retryable: true },\n '24': { name: 'MaxHeaderSizeExceededError', retryable: false },\n '40': { name: 'AuthErrorTokenExpired', retryable: false },\n '41': { name: 'AuthErrorTokenNotValidYet', retryable: false },\n '42': { name: 'AuthErrorTokenUsedBeforeIssuedAt', retryable: false },\n '43': { name: 'AuthErrorTokenSignatureInvalid', retryable: false },\n '44': { name: 'CustomCommandEndpointMissingError', retryable: false },\n '45': { name: 'CustomCommandEndpointCallError', retryable: true },\n '60': { name: 'CoolDownError', retryable: true },\n '69': { name: 'ErrWrongRegion', retryable: false },\n '70': { name: 'ErrQueryChannelPermissions', retryable: false },\n '71': { name: 'ErrTooManyConnections', retryable: true },\n '99': { name: 'AppSuspendedError', retryable: false },\n};\n\ntype APIError = Error & { code: number; isWSFailure?: boolean };\n\nexport function isAPIError(error: Error): error is APIError {\n return (error as APIError).code !== undefined;\n}\n\nexport function isErrorRetryable(error: APIError) {\n if (!error.code) return false;\n const err = APIErrorCodes[`${error.code}`];\n if (!err) return false;\n return err.retryable;\n}\n\nexport function isWSFailure(err: APIError): boolean {\n if (typeof err.isWSFailure === 'boolean') {\n return err.isWSFailure;\n }\n\n try {\n return JSON.parse(err.message).isWSFailure;\n } catch (_) {\n return false;\n }\n}\n\nexport function isErrorResponse(res: AxiosResponse<unknown>): res is AxiosResponse<APIErrorResponse> {\n return !res.status || res.status < 200 || 300 <= res.status;\n}\n","import { AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { StableWSConnection } from './connection';\nimport { EVENT_MAP } from './events';\n\nexport type Role = 'owner' | 'moder' | 'member' | 'pending' | 'skipped' | string;\n\n/* Unknown Record */\nexport type UR = Record<string, unknown>;\nexport type DefaultGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: LiteralStringForUnion;\n eventType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\nexport type ExtendableGenerics = {\n attachmentType: UR;\n channelType: UR;\n commandType: string;\n eventType: UR;\n messageType: UR;\n pollOptionType: UR;\n pollType: UR;\n reactionType: UR;\n userType: UR;\n};\n\n/**\n * Response Types\n */\n\nexport type APIResponse = {\n duration?: string;\n};\n\nexport type ChannelResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['channelType'] & {\n cid: string;\n id: string;\n type: string;\n created_at?: string;\n created_by?: UserResponse<ErmisChatGenerics> | null;\n deleted_at?: string;\n last_message_at?: string;\n member_count?: number;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n name?: string;\n own_capabilities?: string[];\n updated_at?: string;\n image?: string;\n description?: string;\n member_message_cooldown?: number;\n member_capabilities?: string[];\n is_pinned?: boolean;\n topics_enabled?: boolean;\n is_closed_topic?: boolean;\n };\n\nexport type QueryChannelsAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channels: Omit<ChannelAPIResponse<ErmisChatGenerics>, keyof APIResponse>[];\n};\n\nexport type QueryChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse &\n ChannelAPIResponse<ErmisChatGenerics>;\n\nexport type ChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n channel: ChannelResponse<ErmisChatGenerics>;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n messages: MessageResponse<ErmisChatGenerics>[];\n pinned_messages: MessageResponse<ErmisChatGenerics>[];\n membership?: ChannelMembership<ErmisChatGenerics> | null;\n read?: ReadResponse<ErmisChatGenerics>[];\n topics?: QueryChannelAPIResponse<ErmisChatGenerics>[];\n watcher_count?: number;\n watchers?: UserResponse<ErmisChatGenerics>[];\n is_pinned?: boolean;\n};\n\nexport type ChannelMemberResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n banned?: boolean;\n blocked?: boolean;\n channel_role?: Role;\n created_at?: string;\n updated_at?: string;\n user?: UserResponse<ErmisChatGenerics>;\n user_id?: string;\n};\n\nexport type ConnectAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n Promise<void | ConnectionOpen<ErmisChatGenerics>>;\n\nexport type FormatMessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Omit<\n MessageResponse<{\n attachmentType: ErmisChatGenerics['attachmentType'];\n channelType: ErmisChatGenerics['channelType'];\n commandType: ErmisChatGenerics['commandType'];\n eventType: ErmisChatGenerics['eventType'];\n messageType: {};\n pollOptionType: ErmisChatGenerics['pollOptionType'];\n pollType: ErmisChatGenerics['pollType'];\n reactionType: ErmisChatGenerics['reactionType'];\n userType: ErmisChatGenerics['userType'];\n }>,\n 'created_at' | 'pinned_at' | 'updated_at' | 'status'\n> &\n ErmisChatGenerics['messageType'] & {\n created_at: Date;\n pinned_at: Date | null;\n status: string;\n updated_at: Date;\n };\n\nexport type MessageResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n MessageResponseBase<ErmisChatGenerics> & {\n quoted_message?: MessageResponseBase<ErmisChatGenerics>;\n };\n\nexport type MessageResponseBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n MessageBase<ErmisChatGenerics> & {\n type: MessageLabel;\n channel?: ChannelResponse<ErmisChatGenerics>;\n cid?: string;\n created_at?: string;\n deleted_at?: string;\n latest_reactions?: ReactionResponse<ErmisChatGenerics>[];\n mentioned_users?: string[];\n own_reactions?: ReactionResponse<ErmisChatGenerics>[] | null;\n pinned_at?: string | null;\n pinned_by?: UserResponse<ErmisChatGenerics> | null;\n reaction_counts?: { [key: string]: number } | null;\n reaction_scores?: { [key: string]: number } | null;\n reply_count?: number;\n status?: string;\n updated_at?: string;\n };\n\nexport type ReactionAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<ErmisChatGenerics>;\n reaction: ReactionResponse<ErmisChatGenerics>;\n};\n\nexport type ReactionResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n Reaction<ErmisChatGenerics> & {\n created_at: string;\n message_id: string;\n updated_at: string;\n };\n\nexport type ReadResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n last_read: string;\n user: UserResponse<ErmisChatGenerics>;\n last_read_message_id?: string;\n unread_messages?: number;\n last_send?: string;\n};\n\n// Thumb URL(thumb_url) is added considering video attachments as the backend will return the thumbnail in the response.\nexport type SendFileAPIResponse = APIResponse & { file: string; thumb_url?: string };\n\nexport type SendMessageAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n message: MessageResponse<ErmisChatGenerics>;\n};\n\nexport type UpdateChannelAPIResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n channel: ChannelResponse<ErmisChatGenerics>;\n members: ChannelMemberResponse<ErmisChatGenerics>[];\n message?: MessageResponse<ErmisChatGenerics>;\n};\n\nexport type UserResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['userType'] & {\n id: string;\n name?: string;\n avatar?: string;\n about_me?: string;\n project_id?: string;\n email?: string;\n phone?: string;\n };\nexport type Contact = {\n project_id: string;\n user_id: string;\n other_id: string;\n relation_status: string;\n created_at: string;\n updated_at: string;\n};\n\nexport type ContactResponse = APIResponse & {\n project_id_user_ids: {\n [key: string]: Contact[];\n };\n};\n\nexport type ContactResult<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n contact_users: UserResponse<ErmisChatGenerics>[];\n block_users: UserResponse<ErmisChatGenerics>[];\n};\n\nexport type ChannelQueryOptions = {\n messages?: {\n limit?: number;\n id_lt?: string;\n id_gt?: string;\n id_around?: string;\n };\n};\n\nexport type ChannelStateOptions = {\n offlineMode?: boolean;\n skipInitialization?: string[];\n};\n\nexport type ErmisChatOptions = AxiosRequestConfig & {\n /**\n * Used to disable warnings that are triggered by using connectUser or connectAnonymousUser server-side.\n */\n allowServerSideConnect?: boolean;\n axiosRequestConfig?: AxiosRequestConfig;\n /**\n * Base url for User BE API (uss/v1). Defaults to baseURL + '/uss/v1' if not provided.\n */\n userBaseURL?: string;\n browser?: boolean;\n enableInsights?: boolean;\n /** experimental feature, please contact support if you want this feature enabled for you */\n logger?: Logger;\n /**\n * When network is recovered, we re-query the active channels on client. But in single query, you can recover\n * only 30 channels. So its not guaranteed that all the channels in activeChannels object have updated state.\n * Thus in UI sdks, state recovery is managed by components themselves, they don't rely on js client for this.\n *\n * `recoverStateOnReconnect` parameter can be used in such cases, to disable state recovery within js client.\n * When false, user/consumer of this client will need to make sure all the channels present on UI by\n * manually calling queryChannels endpoint.\n */\n recoverStateOnReconnect?: boolean;\n warmUp?: boolean;\n // Set the instance of StableWSConnection on chat client. Its purely for testing purpose and should\n // not be used in production apps.\n wsConnection?: StableWSConnection;\n};\n\n/**\n * Event Types\n */\n\nexport type Event<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = ErmisChatGenerics['eventType'] & {\n type: EventTypes;\n channel?: ChannelResponse<ErmisChatGenerics>;\n channel_id?: string;\n channel_type?: string;\n cid?: string;\n created_at?: string;\n hard_delete?: boolean;\n last_read_at?: string;\n last_read_message_id?: string;\n me?: UserResponse<ErmisChatGenerics>;\n member?: ChannelMemberResponse<ErmisChatGenerics>;\n message?: MessageResponse<ErmisChatGenerics>;\n online?: boolean;\n parent_id?: string;\n reaction?: ReactionResponse<ErmisChatGenerics>;\n received_at?: string | Date;\n unread_messages?: number;\n user?: UserResponse<ErmisChatGenerics>;\n user_id?: string;\n watcher_count?: number;\n};\n\nexport type EventHandler<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = (\n event: Event<ErmisChatGenerics>,\n) => void;\n\nexport type EventTypes = 'all' | keyof typeof EVENT_MAP;\n\n/**\n * Filter Types\n */\n\nexport type AscDesc = 1 | -1;\n\nexport type ChannelFilters = {\n project_id?: string;\n type: ('messaging' | 'team' | 'topic')[];\n limit?: number;\n offset?: number;\n roles?: string[];\n other_roles?: string[];\n banned?: boolean;\n blocked?: boolean;\n include_pinned_messages?: boolean;\n parent_cid?: string;\n parent_id?: string;\n include_parent?: boolean;\n};\n\nexport type ChannelSort = {\n field: string;\n direction: -1 | 1;\n}[];\n\nexport type Attachment<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['attachmentType'] & {\n // main fields for ermis.\n id?: string;\n thumb_url?: string;\n content_disposition?: string;\n content_length?: number;\n content_type?: string;\n updated_at?: string;\n created_at?: string;\n message_id?: string;\n file_name?: string;\n url?: string;\n cid?: string;\n user_id?: string;\n asset_url?: string;\n author_icon?: string;\n author_link?: string;\n author_name?: string;\n color?: string;\n duration?: number;\n fallback?: string;\n file_size?: number | string;\n footer?: string;\n footer_icon?: string;\n image_url?: string;\n mime_type?: string;\n og_scrape_url?: string;\n original_height?: number;\n original_width?: number;\n pretext?: string;\n text?: string;\n title?: string;\n title_link?: string;\n type?: string;\n waveform_data?: Array<number>;\n link_url?: string;\n };\n\nexport type ChannelData<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['channelType'] & {\n members?: string[];\n name?: string;\n is_pinned?: boolean;\n };\n\nexport type ChannelMembership<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n banned?: boolean;\n blocked?: boolean;\n channel_role?: Role;\n created_at?: string;\n updated_at?: string;\n user?: UserResponse<ErmisChatGenerics>;\n};\n\nexport type ConnectionOpen<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n cid?: string;\n created_at?: string;\n me?: UserResponse<ErmisChatGenerics>;\n type?: string;\n};\n\nexport type LiteralStringForUnion = string & {};\n\nexport type LogLevel = 'info' | 'error' | 'warn';\n\nexport type Logger = (logLevel: LogLevel, message: string, extraData?: Record<string, unknown>) => void;\n\nexport type Message<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = Partial<\n MessageBase<ErmisChatGenerics>\n> & {\n id?: string;\n mentioned_all?: boolean;\n mentioned_users?: string[];\n cid?: string;\n forward_cid?: string;\n forward_message_id?: string;\n poll_type?: string; // single | multiple\n poll_choices?: string[];\n sticker_url?: string;\n};\n\nexport type EditMessage = {\n text: string;\n mentioned_all?: boolean;\n mentioned_users?: string[];\n};\n\nexport type ForwardMessage<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n cid: string;\n forward_cid: string;\n forward_message_id: string;\n id?: string;\n text?: string;\n attachments?: Attachment<ErmisChatGenerics>[];\n sticker_url?: string;\n};\n\nexport type PollMessage = {\n id?: string;\n text: string;\n poll_type: string; // single | multiple\n poll_choices: string[];\n};\n\nexport type MessageBase<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['messageType'] & {\n id: string;\n attachments?: Attachment[];\n html?: string;\n mml?: string;\n parent_id?: string;\n pinned?: boolean;\n pinned_at?: string | null;\n quoted_message_id?: string;\n text?: string;\n user?: UserResponse | null;\n user_id?: string;\n };\n\nexport type MessageLabel = 'regular' | 'system' | 'signal' | 'poll' | 'sticker' | 'error';\n\nexport type Reaction<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> =\n ErmisChatGenerics['reactionType'] & {\n type: string;\n message_id?: string;\n score?: number;\n user?: UserResponse | null;\n user_id?: string;\n };\n\nexport type MessageSetType = 'latest' | 'current' | 'new';\n\nexport type APIErrorResponse = {\n code: number;\n duration: string;\n message: string;\n more_info: string;\n StatusCode: number;\n};\n\nexport class ErrorFromResponse<T> extends Error {\n code?: number;\n response?: AxiosResponse<T>;\n status?: number;\n}\n\nexport type UsersResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = {\n data: Array<UserResponse<ErmisChatGenerics>>;\n count: number;\n total: number;\n page: number;\n page_count: number;\n};\n\nexport type AttachmentResponse<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> = APIResponse & {\n attachments: Attachment<ErmisChatGenerics>[];\n};\n\nexport type SignalData = {\n cid?: string;\n is_video?: boolean;\n action?: string;\n signal?: Object;\n metadata?: Object;\n};\n\nexport enum CallAction {\n CREATE_CALL = 'create-call',\n ACCEPT_CALL = 'accept-call',\n SIGNAL_CALL = 'signal-call',\n CONNECT_CALL = 'connect-call',\n HEALTH_CALL = 'health-call',\n END_CALL = 'end-call',\n REJECT_CALL = 'reject-call',\n MISS_CALL = 'miss-call',\n UPGRADE_CALL = 'upgrade-call',\n}\n\nexport enum CallStatus {\n RINGING = 'ringing',\n ENDED = 'ended',\n CONNECTED = 'connected',\n ERROR = 'error',\n}\n\nexport type CallEventType = 'incoming' | 'outgoing';\n\nexport type CallEventData = {\n type: CallEventType;\n callType: string;\n cid: string;\n callerInfo: UserCallInfo | undefined;\n receiverInfo: UserCallInfo | undefined;\n metadata?: Object;\n};\n\nexport type UserCallInfo = {\n id: string;\n name?: string;\n avatar?: string;\n};\n\nexport type Metadata = {\n address?: string;\n};\n\nexport type INodeCall = {\n connect: (address: string) => Promise<void>;\n acceptConnection: () => Promise<void>;\n sendControlFrame: (packet: Uint8Array) => Promise<void>;\n sendAudioFrame: (packet: Uint8Array) => Promise<void>; // audio\n sendFrame: (packet: Uint8Array) => Promise<void>; // video delta\n beginWithGop: (packet: Uint8Array) => Promise<void>; // video key\n asyncRecv: () => Promise<Uint8Array>;\n};\n\nexport type VideoConfig = {\n codec: string;\n codedWidth: number;\n codedHeight: number;\n frameRate?: number;\n orientation?: number;\n rotation?: number;\n description?: any;\n};\n\nexport type AudioConfig = {\n codec: string;\n sampleRate: number;\n numberOfChannels: number;\n description?: string;\n};\n\nexport type TransceiverState = {\n audio_enable: boolean;\n video_enable: boolean;\n};\n\nexport interface IMediaReceiverEvents {\n onConnected?: () => void;\n onTransceiverState?: (state: any) => void;\n onRequestConfig?: () => void;\n onRequestKeyFrame?: () => void;\n onEndCall?: () => void;\n}\n\nexport enum FRAME_TYPE {\n VIDEO_CONFIG = 0,\n AUDIO_CONFIG = 1,\n VIDEO_KEY = 2,\n VIDEO_DELTA = 3,\n AUDIO = 4,\n ORIENTATION = 5,\n CONNECTED = 6,\n TRANSCEIVER_STATE = 7,\n REQUEST_CONFIG = 8,\n REQUEST_KEY_FRAME = 9,\n END_CALL = 10,\n}\n","export const EVENT_MAP = {\n 'channel.created': true,\n 'channel.deleted': true,\n 'channel.truncate': true,\n 'channel.updated': true,\n 'channel.pinned': true,\n 'channel.unpinned': true,\n 'health.check': true,\n 'member.added': true,\n 'member.removed': true,\n 'member.updated': true,\n 'member.joined': true,\n 'member.promoted': true,\n 'member.demoted': true,\n 'member.banned': true,\n 'member.unbanned': true,\n 'member.blocked': true,\n 'member.unblocked': true,\n 'message.deleted': true,\n 'message.deleted_for_me': true,\n 'message.new': true,\n 'message.read': true,\n 'message.updated': true,\n 'message.pinned': true,\n 'message.unpinned': true,\n 'notification.channel_deleted': true,\n 'notification.invite_accepted': true,\n 'notification.invite_rejected': true,\n 'notification.invite_messaging_skipped': true,\n 'pollchoice.new': true,\n 'reaction.deleted': true,\n 'reaction.new': true,\n 'typing.start': true,\n 'typing.stop': true,\n 'user.watching.start': true,\n 'user.watching.stop': true,\n 'connection.changed': true,\n 'connection.recovered': true,\n 'capabilities.changed': true,\n 'channel.topic.disabled': true,\n 'channel.topic.enabled': true,\n 'channel.topic.created': true,\n 'channel.topic.closed': true,\n 'channel.topic.reopen': true,\n 'channel.topic.updated': true,\n};\n","let wasm;\n\nlet cachedUint8ArrayMemory0 = null;\n\nfunction getUint8ArrayMemory0() {\n if (cachedUint8ArrayMemory0 === null || cachedUint8ArrayMemory0.byteLength === 0) {\n cachedUint8ArrayMemory0 = new Uint8Array(wasm.memory.buffer);\n }\n return cachedUint8ArrayMemory0;\n}\n\nlet cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n\ncachedTextDecoder.decode();\n\nconst MAX_SAFARI_DECODE_BYTES = 2146435072;\nlet numBytesDecoded = 0;\nfunction decodeText(ptr, len) {\n numBytesDecoded += len;\n if (numBytesDecoded >= MAX_SAFARI_DECODE_BYTES) {\n cachedTextDecoder = new TextDecoder('utf-8', { ignoreBOM: true, fatal: true });\n cachedTextDecoder.decode();\n numBytesDecoded = len;\n }\n return cachedTextDecoder.decode(getUint8ArrayMemory0().subarray(ptr, ptr + len));\n}\n\nfunction getStringFromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return decodeText(ptr, len);\n}\n\nlet heap = new Array(128).fill(undefined);\n\nheap.push(undefined, null, true, false);\n\nlet heap_next = heap.length;\n\nfunction addHeapObject(obj) {\n if (heap_next === heap.length) heap.push(heap.length + 1);\n const idx = heap_next;\n heap_next = heap[idx];\n\n heap[idx] = obj;\n return idx;\n}\n\nfunction getObject(idx) { return heap[idx]; }\n\nlet WASM_VECTOR_LEN = 0;\n\nconst cachedTextEncoder = new TextEncoder();\n\nif (!('encodeInto' in cachedTextEncoder)) {\n cachedTextEncoder.encodeInto = function (arg, view) {\n const buf = cachedTextEncoder.encode(arg);\n view.set(buf);\n return {\n read: arg.length,\n written: buf.length\n };\n }\n}\n\nfunction passStringToWasm0(arg, malloc, realloc) {\n\n if (realloc === undefined) {\n const buf = cachedTextEncoder.encode(arg);\n const ptr = malloc(buf.length, 1) >>> 0;\n getUint8ArrayMemory0().subarray(ptr, ptr + buf.length).set(buf);\n WASM_VECTOR_LEN = buf.length;\n return ptr;\n }\n\n let len = arg.length;\n let ptr = malloc(len, 1) >>> 0;\n\n const mem = getUint8ArrayMemory0();\n\n let offset = 0;\n\n for (; offset < len; offset++) {\n const code = arg.charCodeAt(offset);\n if (code > 0x7F) break;\n mem[ptr + offset] = code;\n }\n\n if (offset !== len) {\n if (offset !== 0) {\n arg = arg.slice(offset);\n }\n ptr = realloc(ptr, len, len = offset + arg.length * 3, 1) >>> 0;\n const view = getUint8ArrayMemory0().subarray(ptr + offset, ptr + len);\n const ret = cachedTextEncoder.encodeInto(arg, view);\n\n offset += ret.written;\n ptr = realloc(ptr, len, offset, 1) >>> 0;\n }\n\n WASM_VECTOR_LEN = offset;\n return ptr;\n}\n\nlet cachedDataViewMemory0 = null;\n\nfunction getDataViewMemory0() {\n if (cachedDataViewMemory0 === null || cachedDataViewMemory0.buffer.detached === true || (cachedDataViewMemory0.buffer.detached === undefined && cachedDataViewMemory0.buffer !== wasm.memory.buffer)) {\n cachedDataViewMemory0 = new DataView(wasm.memory.buffer);\n }\n return cachedDataViewMemory0;\n}\n\nfunction isLikeNone(x) {\n return x === undefined || x === null;\n}\n\nfunction debugString(val) {\n // primitive types\n const type = typeof val;\n if (type == 'number' || type == 'boolean' || val == null) {\n return `${val}`;\n }\n if (type == 'string') {\n return `\"${val}\"`;\n }\n if (type == 'symbol') {\n const description = val.description;\n if (description == null) {\n return 'Symbol';\n } else {\n return `Symbol(${description})`;\n }\n }\n if (type == 'function') {\n const name = val.name;\n if (typeof name == 'string' && name.length > 0) {\n return `Function(${name})`;\n } else {\n return 'Function';\n }\n }\n // objects\n if (Array.isArray(val)) {\n const length = val.length;\n let debug = '[';\n if (length > 0) {\n debug += debugString(val[0]);\n }\n for(let i = 1; i < length; i++) {\n debug += ', ' + debugString(val[i]);\n }\n debug += ']';\n return debug;\n }\n // Test for built-in\n const builtInMatches = /\\[object ([^\\]]+)\\]/.exec(toString.call(val));\n let className;\n if (builtInMatches && builtInMatches.length > 1) {\n className = builtInMatches[1];\n } else {\n // Failed to match the standard '[object ClassName]'\n return toString.call(val);\n }\n if (className == 'Object') {\n // we're a user defined class or Object\n // JSON.stringify avoids problems with cycles, and is generally much\n // easier than looping through ownProperties of `val`.\n try {\n return 'Object(' + JSON.stringify(val) + ')';\n } catch (_) {\n return 'Object';\n }\n }\n // errors\n if (val instanceof Error) {\n return `${val.name}: ${val.message}\\n${val.stack}`;\n }\n // TODO we could test for more things here, like `Set`s and `Map`s.\n return className;\n}\n\nfunction handleError(f, args) {\n try {\n return f.apply(this, args);\n } catch (e) {\n wasm.__wbindgen_export3(addHeapObject(e));\n }\n}\n\nfunction dropObject(idx) {\n if (idx < 132) return;\n heap[idx] = heap_next;\n heap_next = idx;\n}\n\nfunction takeObject(idx) {\n const ret = getObject(idx);\n dropObject(idx);\n return ret;\n}\n\nfunction getArrayU8FromWasm0(ptr, len) {\n ptr = ptr >>> 0;\n return getUint8ArrayMemory0().subarray(ptr / 1, ptr / 1 + len);\n}\n\nconst CLOSURE_DTORS = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(state => state.dtor(state.a, state.b));\n\nfunction makeMutClosure(arg0, arg1, dtor, f) {\n const state = { a: arg0, b: arg1, cnt: 1, dtor };\n const real = (...args) => {\n\n // First up with a closure we increment the internal reference\n // count. This ensures that the Rust closure environment won't\n // be deallocated while we're invoking it.\n state.cnt++;\n const a = state.a;\n state.a = 0;\n try {\n return f(a, state.b, ...args);\n } finally {\n state.a = a;\n real._wbg_cb_unref();\n }\n };\n real._wbg_cb_unref = () => {\n if (--state.cnt === 0) {\n state.dtor(state.a, state.b);\n state.a = 0;\n CLOSURE_DTORS.unregister(state);\n }\n };\n CLOSURE_DTORS.register(real, state, state);\n return real;\n}\n\nfunction makeClosure(arg0, arg1, dtor, f) {\n const state = { a: arg0, b: arg1, cnt: 1, dtor };\n const real = (...args) => {\n\n // First up with a closure we increment the internal reference\n // count. This ensures that the Rust closure environment won't\n // be deallocated while we're invoking it.\n state.cnt++;\n try {\n return f(state.a, state.b, ...args);\n } finally {\n real._wbg_cb_unref();\n }\n };\n real._wbg_cb_unref = () => {\n if (--state.cnt === 0) {\n state.dtor(state.a, state.b);\n state.a = 0;\n CLOSURE_DTORS.unregister(state);\n }\n };\n CLOSURE_DTORS.register(real, state, state);\n return real;\n}\n\nfunction passArray8ToWasm0(arg, malloc) {\n const ptr = malloc(arg.length * 1, 1) >>> 0;\n getUint8ArrayMemory0().set(arg, ptr / 1);\n WASM_VECTOR_LEN = arg.length;\n return ptr;\n}\nfunction __wasm_bindgen_func_elem_12858(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_12858(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_11688(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_11688(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_6230(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_6230(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_2287(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_2287(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_12912(arg0, arg1, arg2) {\n wasm.__wasm_bindgen_func_elem_12912(arg0, arg1, addHeapObject(arg2));\n}\n\nfunction __wasm_bindgen_func_elem_5748(arg0, arg1) {\n wasm.__wasm_bindgen_func_elem_5748(arg0, arg1);\n}\n\nfunction __wasm_bindgen_func_elem_14376(arg0, arg1, arg2, arg3) {\n wasm.__wasm_bindgen_func_elem_14376(arg0, arg1, addHeapObject(arg2), addHeapObject(arg3));\n}\n\nconst __wbindgen_enum_BinaryType = [\"blob\", \"arraybuffer\"];\n\nconst __wbindgen_enum_ReadableStreamType = [\"bytes\"];\n\nconst __wbindgen_enum_RequestCache = [\"default\", \"no-store\", \"reload\", \"no-cache\", \"force-cache\", \"only-if-cached\"];\n\nconst __wbindgen_enum_RequestCredentials = [\"omit\", \"same-origin\", \"include\"];\n\nconst __wbindgen_enum_RequestMode = [\"same-origin\", \"no-cors\", \"cors\", \"navigate\"];\n\nconst ConnectionStatsFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_connectionstats_free(ptr >>> 0, 1));\n\nexport class ConnectionStats {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ConnectionStatsFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_connectionstats_free(ptr, 0);\n }\n /**\n * @returns {number | undefined}\n */\n get rtt_ms() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.__wbg_get_connectionstats_rtt_ms(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {number | null} [arg0]\n */\n set rtt_ms(arg0) {\n wasm.__wbg_set_connectionstats_rtt_ms(this.__wbg_ptr, !isLikeNone(arg0), isLikeNone(arg0) ? 0 : arg0);\n }\n /**\n * @returns {number | undefined}\n */\n get packet_loss() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.__wbg_get_connectionstats_packet_loss(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {number | null} [arg0]\n */\n set packet_loss(arg0) {\n wasm.__wbg_set_connectionstats_packet_loss(this.__wbg_ptr, !isLikeNone(arg0), isLikeNone(arg0) ? 0 : arg0);\n }\n /**\n * @param {string | null} [connection_type]\n * @param {number | null} [rtt_ms]\n * @param {number | null} [packet_loss]\n */\n constructor(connection_type, rtt_ms, packet_loss) {\n var ptr0 = isLikeNone(connection_type) ? 0 : passStringToWasm0(connection_type, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len0 = WASM_VECTOR_LEN;\n const ret = wasm.connectionstats_new(ptr0, len0, !isLikeNone(rtt_ms), isLikeNone(rtt_ms) ? 0 : rtt_ms, !isLikeNone(packet_loss), isLikeNone(packet_loss) ? 0 : packet_loss);\n this.__wbg_ptr = ret >>> 0;\n ConnectionStatsFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @returns {string | undefined}\n */\n get connection_type() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.connectionstats_connection_type(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n let v1;\n if (r0 !== 0) {\n v1 = getStringFromWasm0(r0, r1).slice();\n wasm.__wbindgen_export4(r0, r1 * 1, 1);\n }\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {string | null} [value]\n */\n set connection_type(value) {\n var ptr0 = isLikeNone(value) ? 0 : passStringToWasm0(value, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len0 = WASM_VECTOR_LEN;\n wasm.connectionstats_set_connection_type(this.__wbg_ptr, ptr0, len0);\n }\n}\nif (Symbol.dispose) ConnectionStats.prototype[Symbol.dispose] = ConnectionStats.prototype.free;\n\nconst ErmisCallFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_ermiscall_free(ptr >>> 0, 1));\n\nexport class ErmisCall {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n ErmisCallFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_ermiscall_free(ptr, 0);\n }\n constructor() {\n const ret = wasm.ermiscall_new();\n this.__wbg_ptr = ret >>> 0;\n ErmisCallFinalization.register(this, this.__wbg_ptr, this);\n return this;\n }\n /**\n * @param {any} relay_urls\n * @param {Uint8Array | null} [secret_key]\n * @returns {Promise<void>}\n */\n spawn(relay_urls, secret_key) {\n var ptr0 = isLikeNone(secret_key) ? 0 : passArray8ToWasm0(secret_key, wasm.__wbindgen_export);\n var len0 = WASM_VECTOR_LEN;\n const ret = wasm.ermiscall_spawn(this.__wbg_ptr, addHeapObject(relay_urls), ptr0, len0);\n return takeObject(ret);\n }\n /**\n * @returns {Promise<string>}\n */\n getLocalEndpointAddr() {\n const ret = wasm.ermiscall_getLocalEndpointAddr(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {string} addr\n * @returns {Promise<void>}\n */\n connect(addr) {\n const ptr0 = passStringToWasm0(addr, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len0 = WASM_VECTOR_LEN;\n const ret = wasm.ermiscall_connect(this.__wbg_ptr, ptr0, len0);\n return takeObject(ret);\n }\n /**\n * @returns {Promise<void>}\n */\n closeEndpoint() {\n const ret = wasm.ermiscall_closeEndpoint(this.__wbg_ptr);\n return takeObject(ret);\n }\n closeConnection() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_closeConnection(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Promise<void>}\n */\n acceptConnection() {\n const ret = wasm.ermiscall_acceptConnection(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {Uint8Array} data\n */\n sendControlFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendControlFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {Uint8Array} data\n */\n sendAudioFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendAudioFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @param {Uint8Array} data\n */\n sendFrame(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_sendFrame(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n notifyNewGop() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_notifyNewGop(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Uint8Array}\n */\n recv() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_recv(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n if (r2) {\n throw takeObject(r1);\n }\n return takeObject(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {Promise<Uint8Array>}\n */\n asyncRecv() {\n const ret = wasm.ermiscall_asyncRecv(this.__wbg_ptr);\n return takeObject(ret);\n }\n /**\n * @param {Uint8Array} data\n */\n beginWithGop(data) {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n const ptr0 = passArray8ToWasm0(data, wasm.__wbindgen_export);\n const len0 = WASM_VECTOR_LEN;\n wasm.ermiscall_beginWithGop(retptr, this.__wbg_ptr, ptr0, len0);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n if (r1) {\n throw takeObject(r0);\n }\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {string | undefined}\n */\n connectionType() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_connectionType(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n let v1;\n if (r0 !== 0) {\n v1 = getStringFromWasm0(r0, r1).slice();\n wasm.__wbindgen_export4(r0, r1 * 1, 1);\n }\n return v1;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number | undefined}\n */\n roundTripTime() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_roundTripTime(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n /**\n * @returns {number | undefined}\n */\n currentPacketLoss() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_currentPacketLoss(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r2 = getDataViewMemory0().getFloat64(retptr + 8 * 1, true);\n return r0 === 0 ? undefined : r2;\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n networkChange() {\n wasm.ermiscall_networkChange(this.__wbg_ptr);\n }\n /**\n * @returns {any}\n */\n getStats() {\n try {\n const retptr = wasm.__wbindgen_add_to_stack_pointer(-16);\n wasm.ermiscall_getStats(retptr, this.__wbg_ptr);\n var r0 = getDataViewMemory0().getInt32(retptr + 4 * 0, true);\n var r1 = getDataViewMemory0().getInt32(retptr + 4 * 1, true);\n var r2 = getDataViewMemory0().getInt32(retptr + 4 * 2, true);\n if (r2) {\n throw takeObject(r1);\n }\n return takeObject(r0);\n } finally {\n wasm.__wbindgen_add_to_stack_pointer(16);\n }\n }\n}\nif (Symbol.dispose) ErmisCall.prototype[Symbol.dispose] = ErmisCall.prototype.free;\n\nconst IntoUnderlyingByteSourceFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingbytesource_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingByteSource {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingByteSourceFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingbytesource_free(ptr, 0);\n }\n /**\n * @returns {ReadableStreamType}\n */\n get type() {\n const ret = wasm.intounderlyingbytesource_type(this.__wbg_ptr);\n return __wbindgen_enum_ReadableStreamType[ret];\n }\n /**\n * @returns {number}\n */\n get autoAllocateChunkSize() {\n const ret = wasm.intounderlyingbytesource_autoAllocateChunkSize(this.__wbg_ptr);\n return ret >>> 0;\n }\n /**\n * @param {ReadableByteStreamController} controller\n */\n start(controller) {\n wasm.intounderlyingbytesource_start(this.__wbg_ptr, addHeapObject(controller));\n }\n /**\n * @param {ReadableByteStreamController} controller\n * @returns {Promise<any>}\n */\n pull(controller) {\n const ret = wasm.intounderlyingbytesource_pull(this.__wbg_ptr, addHeapObject(controller));\n return takeObject(ret);\n }\n cancel() {\n const ptr = this.__destroy_into_raw();\n wasm.intounderlyingbytesource_cancel(ptr);\n }\n}\nif (Symbol.dispose) IntoUnderlyingByteSource.prototype[Symbol.dispose] = IntoUnderlyingByteSource.prototype.free;\n\nconst IntoUnderlyingSinkFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingsink_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingSink {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingSinkFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingsink_free(ptr, 0);\n }\n /**\n * @param {any} chunk\n * @returns {Promise<any>}\n */\n write(chunk) {\n const ret = wasm.intounderlyingsink_write(this.__wbg_ptr, addHeapObject(chunk));\n return takeObject(ret);\n }\n /**\n * @returns {Promise<any>}\n */\n close() {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.intounderlyingsink_close(ptr);\n return takeObject(ret);\n }\n /**\n * @param {any} reason\n * @returns {Promise<any>}\n */\n abort(reason) {\n const ptr = this.__destroy_into_raw();\n const ret = wasm.intounderlyingsink_abort(ptr, addHeapObject(reason));\n return takeObject(ret);\n }\n}\nif (Symbol.dispose) IntoUnderlyingSink.prototype[Symbol.dispose] = IntoUnderlyingSink.prototype.free;\n\nconst IntoUnderlyingSourceFinalization = (typeof FinalizationRegistry === 'undefined')\n ? { register: () => {}, unregister: () => {} }\n : new FinalizationRegistry(ptr => wasm.__wbg_intounderlyingsource_free(ptr >>> 0, 1));\n\nexport class IntoUnderlyingSource {\n\n __destroy_into_raw() {\n const ptr = this.__wbg_ptr;\n this.__wbg_ptr = 0;\n IntoUnderlyingSourceFinalization.unregister(this);\n return ptr;\n }\n\n free() {\n const ptr = this.__destroy_into_raw();\n wasm.__wbg_intounderlyingsource_free(ptr, 0);\n }\n /**\n * @param {ReadableStreamDefaultController} controller\n * @returns {Promise<any>}\n */\n pull(controller) {\n const ret = wasm.intounderlyingsource_pull(this.__wbg_ptr, addHeapObject(controller));\n return takeObject(ret);\n }\n cancel() {\n const ptr = this.__destroy_into_raw();\n wasm.intounderlyingsource_cancel(ptr);\n }\n}\nif (Symbol.dispose) IntoUnderlyingSource.prototype[Symbol.dispose] = IntoUnderlyingSource.prototype.free;\n\nconst EXPECTED_RESPONSE_TYPES = new Set(['basic', 'cors', 'default']);\n\nasync function __wbg_load(module, imports) {\n if (typeof Response === 'function' && module instanceof Response) {\n if (typeof WebAssembly.instantiateStreaming === 'function') {\n try {\n return await WebAssembly.instantiateStreaming(module, imports);\n\n } catch (e) {\n const validResponse = module.ok && EXPECTED_RESPONSE_TYPES.has(module.type);\n\n if (validResponse && module.headers.get('Content-Type') !== 'application/wasm') {\n console.warn(\"`WebAssembly.instantiateStreaming` failed because your server does not serve Wasm with `application/wasm` MIME type. Falling back to `WebAssembly.instantiate` which is slower. Original error:\\n\", e);\n\n } else {\n throw e;\n }\n }\n }\n\n const bytes = await module.arrayBuffer();\n return await WebAssembly.instantiate(bytes, imports);\n\n } else {\n const instance = await WebAssembly.instantiate(module, imports);\n\n if (instance instanceof WebAssembly.Instance) {\n return { instance, module };\n\n } else {\n return instance;\n }\n }\n}\n\nfunction __wbg_get_imports() {\n const imports = {};\n imports.wbg = {};\n imports.wbg.__wbg_Error_e83987f665cf5504 = function(arg0, arg1) {\n const ret = Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_String_8f0eb39a4a4c2f66 = function(arg0, arg1) {\n const ret = String(getObject(arg1));\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_boolean_get_6d5a1ee65bab5f68 = function(arg0) {\n const v = getObject(arg0);\n const ret = typeof(v) === 'boolean' ? v : undefined;\n return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;\n };\n imports.wbg.__wbg___wbindgen_debug_string_df47ffb5e35e6763 = function(arg0, arg1) {\n const ret = debugString(getObject(arg1));\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_is_function_ee8a6c5833c90377 = function(arg0) {\n const ret = typeof(getObject(arg0)) === 'function';\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_object_c818261d21f283a4 = function(arg0) {\n const val = getObject(arg0);\n const ret = typeof(val) === 'object' && val !== null;\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_string_fbb76cb2940daafd = function(arg0) {\n const ret = typeof(getObject(arg0)) === 'string';\n return ret;\n };\n imports.wbg.__wbg___wbindgen_is_undefined_2d472862bd29a478 = function(arg0) {\n const ret = getObject(arg0) === undefined;\n return ret;\n };\n imports.wbg.__wbg___wbindgen_jsval_loose_eq_b664b38a2f582147 = function(arg0, arg1) {\n const ret = getObject(arg0) == getObject(arg1);\n return ret;\n };\n imports.wbg.__wbg___wbindgen_number_get_a20bf9b85341449d = function(arg0, arg1) {\n const obj = getObject(arg1);\n const ret = typeof(obj) === 'number' ? obj : undefined;\n getDataViewMemory0().setFloat64(arg0 + 8 * 1, isLikeNone(ret) ? 0 : ret, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, !isLikeNone(ret), true);\n };\n imports.wbg.__wbg___wbindgen_string_get_e4f06c90489ad01b = function(arg0, arg1) {\n const obj = getObject(arg1);\n const ret = typeof(obj) === 'string' ? obj : undefined;\n var ptr1 = isLikeNone(ret) ? 0 : passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n var len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg___wbindgen_throw_b855445ff6a94295 = function(arg0, arg1) {\n throw new Error(getStringFromWasm0(arg0, arg1));\n };\n imports.wbg.__wbg__wbg_cb_unref_2454a539ea5790d9 = function(arg0) {\n getObject(arg0)._wbg_cb_unref();\n };\n imports.wbg.__wbg_abort_28ad55c5825b004d = function(arg0, arg1) {\n getObject(arg0).abort(getObject(arg1));\n };\n imports.wbg.__wbg_abort_e7eb059f72f9ed0c = function(arg0) {\n getObject(arg0).abort();\n };\n imports.wbg.__wbg_addEventListener_40dc0fc428fc49e1 = function() { return handleError(function (arg0, arg1, arg2, arg3) {\n getObject(arg0).addEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));\n }, arguments) };\n imports.wbg.__wbg_append_b577eb3a177bc0fa = function() { return handleError(function (arg0, arg1, arg2, arg3, arg4) {\n getObject(arg0).append(getStringFromWasm0(arg1, arg2), getStringFromWasm0(arg3, arg4));\n }, arguments) };\n imports.wbg.__wbg_body_587542b2fd8e06c0 = function(arg0) {\n const ret = getObject(arg0).body;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_buffer_ccc4520b36d3ccf4 = function(arg0) {\n const ret = getObject(arg0).buffer;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_byobRequest_2344e6975f27456e = function(arg0) {\n const ret = getObject(arg0).byobRequest;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_byteLength_bcd42e4025299788 = function(arg0) {\n const ret = getObject(arg0).byteLength;\n return ret;\n };\n imports.wbg.__wbg_byteOffset_ca3a6cf7944b364b = function(arg0) {\n const ret = getObject(arg0).byteOffset;\n return ret;\n };\n imports.wbg.__wbg_call_525440f72fbfc0ea = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = getObject(arg0).call(getObject(arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_call_e762c39fa8ea36bf = function() { return handleError(function (arg0, arg1) {\n const ret = getObject(arg0).call(getObject(arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_cancel_48ab6f9dc366e369 = function(arg0) {\n const ret = getObject(arg0).cancel();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_catch_943836faa5d29bfb = function(arg0, arg1) {\n const ret = getObject(arg0).catch(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_clearTimeout_15dfc3d1dcb635c6 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).clearTimeout(takeObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_clearTimeout_7a42b49784aea641 = function(arg0) {\n const ret = clearTimeout(takeObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_close_5a6caed3231b68cd = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_close_6956df845478561a = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_close_885e277edf06b3fa = function() { return handleError(function (arg0) {\n getObject(arg0).close();\n }, arguments) };\n imports.wbg.__wbg_code_20d453b11b200026 = function(arg0) {\n const ret = getObject(arg0).code;\n return ret;\n };\n imports.wbg.__wbg_code_218f5fdf8c7fcabd = function(arg0) {\n const ret = getObject(arg0).code;\n return ret;\n };\n imports.wbg.__wbg_crypto_574e78ad8b13b65f = function(arg0) {\n const ret = getObject(arg0).crypto;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_data_ee4306d069f24f2d = function(arg0) {\n const ret = getObject(arg0).data;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_done_2042aa2670fb1db1 = function(arg0) {\n const ret = getObject(arg0).done;\n return ret;\n };\n imports.wbg.__wbg_enqueue_7b18a650aec77898 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).enqueue(getObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_fetch_74a3e84ebd2c9a0e = function(arg0) {\n const ret = fetch(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_fetch_f8ba0e29a9d6de0d = function(arg0, arg1) {\n const ret = getObject(arg0).fetch(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_getRandomValues_1c61fac11405ffdc = function() { return handleError(function (arg0, arg1) {\n globalThis.crypto.getRandomValues(getArrayU8FromWasm0(arg0, arg1));\n }, arguments) };\n imports.wbg.__wbg_getRandomValues_b8f5dbd5f3995a9e = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).getRandomValues(getObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_getReader_48e00749fe3f6089 = function() { return handleError(function (arg0) {\n const ret = getObject(arg0).getReader();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_getTime_14776bfb48a1bff9 = function(arg0) {\n const ret = getObject(arg0).getTime();\n return ret;\n };\n imports.wbg.__wbg_get_7bed016f185add81 = function(arg0, arg1) {\n const ret = getObject(arg0)[arg1 >>> 0];\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_get_done_a0463af43a1fc764 = function(arg0) {\n const ret = getObject(arg0).done;\n return isLikeNone(ret) ? 0xFFFFFF : ret ? 1 : 0;\n };\n imports.wbg.__wbg_get_efcb449f58ec27c2 = function() { return handleError(function (arg0, arg1) {\n const ret = Reflect.get(getObject(arg0), getObject(arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_get_value_5ce96c9f81ce7398 = function(arg0) {\n const ret = getObject(arg0).value;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_has_787fafc980c3ccdb = function() { return handleError(function (arg0, arg1) {\n const ret = Reflect.has(getObject(arg0), getObject(arg1));\n return ret;\n }, arguments) };\n imports.wbg.__wbg_headers_b87d7eaba61c3278 = function(arg0) {\n const ret = getObject(arg0).headers;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_instanceof_ArrayBuffer_70beb1189ca63b38 = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof ArrayBuffer;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Blob_23b3322f66e5a83b = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Blob;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Response_f4f3e87e07f3135c = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Response;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_instanceof_Uint8Array_20c8e73002f7af98 = function(arg0) {\n let result;\n try {\n result = getObject(arg0) instanceof Uint8Array;\n } catch (_) {\n result = false;\n }\n const ret = result;\n return ret;\n };\n imports.wbg.__wbg_isArray_96e0af9891d0945d = function(arg0) {\n const ret = Array.isArray(getObject(arg0));\n return ret;\n };\n imports.wbg.__wbg_iterator_e5822695327a3c39 = function() {\n const ret = Symbol.iterator;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_length_69bca3cb64fc8748 = function(arg0) {\n const ret = getObject(arg0).length;\n return ret;\n };\n imports.wbg.__wbg_length_cdd215e10d9dd507 = function(arg0) {\n const ret = getObject(arg0).length;\n return ret;\n };\n imports.wbg.__wbg_log_ee0138cca4957740 = function(arg0, arg1) {\n console.log(getStringFromWasm0(arg0, arg1));\n };\n imports.wbg.__wbg_message_bd42dbe3f2f3ed8e = function(arg0, arg1) {\n const ret = getObject(arg1).message;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_msCrypto_a61aeb35a24c1329 = function(arg0) {\n const ret = getObject(arg0).msCrypto;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_0_f9740686d739025c = function() {\n const ret = new Date();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_1acc0b6eea89d040 = function() {\n const ret = new Object();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_2531773dac38ebb3 = function() { return handleError(function () {\n const ret = new AbortController();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_3c3d849046688a66 = function(arg0, arg1) {\n try {\n var state0 = {a: arg0, b: arg1};\n var cb0 = (arg0, arg1) => {\n const a = state0.a;\n state0.a = 0;\n try {\n return __wasm_bindgen_func_elem_14376(a, state0.b, arg0, arg1);\n } finally {\n state0.a = a;\n }\n };\n const ret = new Promise(cb0);\n return addHeapObject(ret);\n } finally {\n state0.a = state0.b = 0;\n }\n };\n imports.wbg.__wbg_new_5a79be3ab53b8aa5 = function(arg0) {\n const ret = new Uint8Array(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_881c4fe631eee9ad = function() { return handleError(function (arg0, arg1) {\n const ret = new WebSocket(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_9edf9838a2def39c = function() { return handleError(function () {\n const ret = new Headers();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_a7442b4b19c1a356 = function(arg0, arg1) {\n const ret = new Error(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_e17d9f43105b08be = function() {\n const ret = new Array();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_from_slice_92f4d78ca282a2d2 = function(arg0, arg1) {\n const ret = new Uint8Array(getArrayU8FromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_no_args_ee98eee5275000a4 = function(arg0, arg1) {\n const ret = new Function(getStringFromWasm0(arg0, arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_byte_offset_and_length_46e3e6a5e9f9e89b = function(arg0, arg1, arg2) {\n const ret = new Uint8Array(getObject(arg0), arg1 >>> 0, arg2 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_length_01aa0dc35aa13543 = function(arg0) {\n const ret = new Uint8Array(arg0 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_new_with_str_and_init_0ae7728b6ec367b1 = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = new Request(getStringFromWasm0(arg0, arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_new_with_str_sequence_57a88eb77393f23f = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = new WebSocket(getStringFromWasm0(arg0, arg1), getObject(arg2));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_next_020810e0ae8ebcb0 = function() { return handleError(function (arg0) {\n const ret = getObject(arg0).next();\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_next_2c826fe5dfec6b6a = function(arg0) {\n const ret = getObject(arg0).next;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_node_905d3e251edff8a2 = function(arg0) {\n const ret = getObject(arg0).node;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_now_2c95c9de01293173 = function(arg0) {\n const ret = getObject(arg0).now();\n return ret;\n };\n imports.wbg.__wbg_now_793306c526e2e3b6 = function() {\n const ret = Date.now();\n return ret;\n };\n imports.wbg.__wbg_performance_7a3ffd0b17f663ad = function(arg0) {\n const ret = getObject(arg0).performance;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_process_dc0fbacc7c1c06f7 = function(arg0) {\n const ret = getObject(arg0).process;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_prototypesetcall_2a6620b6922694b2 = function(arg0, arg1, arg2) {\n Uint8Array.prototype.set.call(getArrayU8FromWasm0(arg0, arg1), getObject(arg2));\n };\n imports.wbg.__wbg_push_df81a39d04db858c = function(arg0, arg1) {\n const ret = getObject(arg0).push(getObject(arg1));\n return ret;\n };\n imports.wbg.__wbg_queueMicrotask_34d692c25c47d05b = function(arg0) {\n const ret = getObject(arg0).queueMicrotask;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_queueMicrotask_9d76cacb20c84d58 = function(arg0) {\n queueMicrotask(getObject(arg0));\n };\n imports.wbg.__wbg_randomFillSync_ac0988aba3254290 = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).randomFillSync(takeObject(arg1));\n }, arguments) };\n imports.wbg.__wbg_read_48f1593df542f968 = function(arg0) {\n const ret = getObject(arg0).read();\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_readyState_97984f126080aeda = function(arg0) {\n const ret = getObject(arg0).readyState;\n return ret;\n };\n imports.wbg.__wbg_reason_1cced37e3a93763e = function(arg0, arg1) {\n const ret = getObject(arg1).reason;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_releaseLock_5d0b5a68887b891d = function(arg0) {\n getObject(arg0).releaseLock();\n };\n imports.wbg.__wbg_removeEventListener_924d9db66a4f775d = function() { return handleError(function (arg0, arg1, arg2, arg3) {\n getObject(arg0).removeEventListener(getStringFromWasm0(arg1, arg2), getObject(arg3));\n }, arguments) };\n imports.wbg.__wbg_require_60cc747a6bc5215a = function() { return handleError(function () {\n const ret = module.require;\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_resolve_caf97c30b83f7053 = function(arg0) {\n const ret = Promise.resolve(getObject(arg0));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_respond_0f4dbf5386f5c73e = function() { return handleError(function (arg0, arg1) {\n getObject(arg0).respond(arg1 >>> 0);\n }, arguments) };\n imports.wbg.__wbg_send_171576d2f7487517 = function() { return handleError(function (arg0, arg1, arg2) {\n getObject(arg0).send(getStringFromWasm0(arg1, arg2));\n }, arguments) };\n imports.wbg.__wbg_send_3d2cf376613294f0 = function() { return handleError(function (arg0, arg1, arg2) {\n getObject(arg0).send(getArrayU8FromWasm0(arg1, arg2));\n }, arguments) };\n imports.wbg.__wbg_setTimeout_4eb823e8b72fbe79 = function() { return handleError(function (arg0, arg1, arg2) {\n const ret = getObject(arg0).setTimeout(takeObject(arg1), arg2);\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_setTimeout_7bb3429662ab1e70 = function(arg0, arg1) {\n const ret = setTimeout(getObject(arg0), arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_set_3f1d0b984ed272ed = function(arg0, arg1, arg2) {\n getObject(arg0)[takeObject(arg1)] = takeObject(arg2);\n };\n imports.wbg.__wbg_set_9e6516df7b7d0f19 = function(arg0, arg1, arg2) {\n getObject(arg0).set(getArrayU8FromWasm0(arg1, arg2));\n };\n imports.wbg.__wbg_set_binaryType_9d839cea8fcdc5c3 = function(arg0, arg1) {\n getObject(arg0).binaryType = __wbindgen_enum_BinaryType[arg1];\n };\n imports.wbg.__wbg_set_body_3c365989753d61f4 = function(arg0, arg1) {\n getObject(arg0).body = getObject(arg1);\n };\n imports.wbg.__wbg_set_cache_2f9deb19b92b81e3 = function(arg0, arg1) {\n getObject(arg0).cache = __wbindgen_enum_RequestCache[arg1];\n };\n imports.wbg.__wbg_set_credentials_f621cd2d85c0c228 = function(arg0, arg1) {\n getObject(arg0).credentials = __wbindgen_enum_RequestCredentials[arg1];\n };\n imports.wbg.__wbg_set_handle_event_b2de49ad6c81e3c8 = function(arg0, arg1) {\n getObject(arg0).handleEvent = getObject(arg1);\n };\n imports.wbg.__wbg_set_headers_6926da238cd32ee4 = function(arg0, arg1) {\n getObject(arg0).headers = getObject(arg1);\n };\n imports.wbg.__wbg_set_method_c02d8cbbe204ac2d = function(arg0, arg1, arg2) {\n getObject(arg0).method = getStringFromWasm0(arg1, arg2);\n };\n imports.wbg.__wbg_set_mode_52ef73cfa79639cb = function(arg0, arg1) {\n getObject(arg0).mode = __wbindgen_enum_RequestMode[arg1];\n };\n imports.wbg.__wbg_set_onclose_c09e4f7422de8dae = function(arg0, arg1) {\n getObject(arg0).onclose = getObject(arg1);\n };\n imports.wbg.__wbg_set_onerror_337a3a2db9517378 = function(arg0, arg1) {\n getObject(arg0).onerror = getObject(arg1);\n };\n imports.wbg.__wbg_set_onmessage_8661558551a89792 = function(arg0, arg1) {\n getObject(arg0).onmessage = getObject(arg1);\n };\n imports.wbg.__wbg_set_onopen_efccb9305427b907 = function(arg0, arg1) {\n getObject(arg0).onopen = getObject(arg1);\n };\n imports.wbg.__wbg_set_signal_dda2cf7ccb6bee0f = function(arg0, arg1) {\n getObject(arg0).signal = getObject(arg1);\n };\n imports.wbg.__wbg_signal_4db5aa055bf9eb9a = function(arg0) {\n const ret = getObject(arg0).signal;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_89e1d9ac6a1b250e = function() {\n const ret = typeof global === 'undefined' ? null : global;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_GLOBAL_THIS_8b530f326a9e48ac = function() {\n const ret = typeof globalThis === 'undefined' ? null : globalThis;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_SELF_6fdf4b64710cc91b = function() {\n const ret = typeof self === 'undefined' ? null : self;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_static_accessor_WINDOW_b45bfc5a37f6cfa2 = function() {\n const ret = typeof window === 'undefined' ? null : window;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_status_de7eed5a7a5bfd5d = function(arg0) {\n const ret = getObject(arg0).status;\n return ret;\n };\n imports.wbg.__wbg_stringify_b5fb28f6465d9c3e = function() { return handleError(function (arg0) {\n const ret = JSON.stringify(getObject(arg0));\n return addHeapObject(ret);\n }, arguments) };\n imports.wbg.__wbg_subarray_480600f3d6a9f26c = function(arg0, arg1, arg2) {\n const ret = getObject(arg0).subarray(arg1 >>> 0, arg2 >>> 0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_then_4f46f6544e6b4a28 = function(arg0, arg1) {\n const ret = getObject(arg0).then(getObject(arg1));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_then_70d05cf780a18d77 = function(arg0, arg1, arg2) {\n const ret = getObject(arg0).then(getObject(arg1), getObject(arg2));\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_url_9bd0af1cd8643de7 = function(arg0, arg1) {\n const ret = getObject(arg1).url;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_url_b36d2a5008eb056f = function(arg0, arg1) {\n const ret = getObject(arg1).url;\n const ptr1 = passStringToWasm0(ret, wasm.__wbindgen_export, wasm.__wbindgen_export2);\n const len1 = WASM_VECTOR_LEN;\n getDataViewMemory0().setInt32(arg0 + 4 * 1, len1, true);\n getDataViewMemory0().setInt32(arg0 + 4 * 0, ptr1, true);\n };\n imports.wbg.__wbg_value_692627309814bb8c = function(arg0) {\n const ret = getObject(arg0).value;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_versions_c01dfd4722a88165 = function(arg0) {\n const ret = getObject(arg0).versions;\n return addHeapObject(ret);\n };\n imports.wbg.__wbg_view_f6c15ac9fed63bbd = function(arg0) {\n const ret = getObject(arg0).view;\n return isLikeNone(ret) ? 0 : addHeapObject(ret);\n };\n imports.wbg.__wbg_wasClean_3d7c0cf05bd0a123 = function(arg0) {\n const ret = getObject(arg0).wasClean;\n return ret;\n };\n imports.wbg.__wbindgen_cast_0b4723bb5ff7475b = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2388, function: Function { arguments: [NamedExternref(\"MessageEvent\")], shim_idx: 2389, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_11664, __wasm_bindgen_func_elem_11688);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_2241b6af4c4b2941 = function(arg0, arg1) {\n // Cast intrinsic for `Ref(String) -> Externref`.\n const ret = getStringFromWasm0(arg0, arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_253c73f2760a05aa = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 1351, function: Function { arguments: [], shim_idx: 1352, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_6219, __wasm_bindgen_func_elem_6230);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_343835dd8f264af2 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 1255, function: Function { arguments: [], shim_idx: 1256, ret: Unit, inner_ret: Some(Unit) }, mutable: false }) -> Externref`.\n const ret = makeClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_5735, __wasm_bindgen_func_elem_5748);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_7bacc9fa7d2c65f4 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2465, function: Function { arguments: [], shim_idx: 2466, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_12841, __wasm_bindgen_func_elem_12858);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_88fdcfb6b716b7f8 = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 2473, function: Function { arguments: [Externref], shim_idx: 2474, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_12896, __wasm_bindgen_func_elem_12912);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_c43a1cf1b94f2e7c = function(arg0, arg1) {\n // Cast intrinsic for `Closure(Closure { dtor_idx: 544, function: Function { arguments: [NamedExternref(\"CloseEvent\")], shim_idx: 545, ret: Unit, inner_ret: Some(Unit) }, mutable: true }) -> Externref`.\n const ret = makeMutClosure(arg0, arg1, wasm.__wasm_bindgen_func_elem_2083, __wasm_bindgen_func_elem_2287);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_cb9088102bce6b30 = function(arg0, arg1) {\n // Cast intrinsic for `Ref(Slice(U8)) -> NamedExternref(\"Uint8Array\")`.\n const ret = getArrayU8FromWasm0(arg0, arg1);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_cast_d6cd19b81560fd6e = function(arg0) {\n // Cast intrinsic for `F64 -> Externref`.\n const ret = arg0;\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_object_clone_ref = function(arg0) {\n const ret = getObject(arg0);\n return addHeapObject(ret);\n };\n imports.wbg.__wbindgen_object_drop_ref = function(arg0) {\n takeObject(arg0);\n };\n\n return imports;\n}\n\nfunction __wbg_finalize_init(instance, module) {\n wasm = instance.exports;\n __wbg_init.__wbindgen_wasm_module = module;\n cachedDataViewMemory0 = null;\n cachedUint8ArrayMemory0 = null;\n\n\n\n return wasm;\n}\n\nfunction initSync(module) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module !== 'undefined') {\n if (Object.getPrototypeOf(module) === Object.prototype) {\n ({module} = module)\n } else {\n console.warn('using deprecated parameters for `initSync()`; pass a single object instead')\n }\n }\n\n const imports = __wbg_get_imports();\n\n if (!(module instanceof WebAssembly.Module)) {\n module = new WebAssembly.Module(module);\n }\n\n const instance = new WebAssembly.Instance(module, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nasync function __wbg_init(module_or_path) {\n if (wasm !== undefined) return wasm;\n\n\n if (typeof module_or_path !== 'undefined') {\n if (Object.getPrototypeOf(module_or_path) === Object.prototype) {\n ({module_or_path} = module_or_path)\n } else {\n console.warn('using deprecated parameters for the initialization function; pass a single object instead')\n }\n }\n\n if (typeof module_or_path === 'undefined') {\n module_or_path = new URL('ermis_call_node_wasm_bg.wasm', import.meta.url);\n }\n const imports = __wbg_get_imports();\n\n if (typeof module_or_path === 'string' || (typeof Request === 'function' && module_or_path instanceof Request) || (typeof URL === 'function' && module_or_path instanceof URL)) {\n module_or_path = fetch(module_or_path);\n }\n\n const { instance, module } = await __wbg_load(await module_or_path, imports);\n\n return __wbg_finalize_init(instance, module);\n}\n\nexport { initSync };\nexport default __wbg_init;\n","import { base64Encode, createPacketWithHeader } from './utils';\nimport { AudioConfig, INodeCall, TransceiverState, VideoConfig } from './types';\n\nexport class MediaStreamSender {\n private videoEncoder: VideoEncoder | null = null;\n private audioEncoder: AudioEncoder | null = null;\n private videoReader: ReadableStreamDefaultReader<VideoFrame> | null = null;\n\n private localStream: MediaStream | null = null;\n\n private videoConfig: VideoConfig | null = null;\n private audioConfig: AudioConfig | null = null;\n\n private videoConfigSent: boolean = false;\n private audioConfigSent: boolean = false;\n\n private hasVideo: boolean = false;\n private hasAudio: boolean = false;\n\n private forceKeyFrame: boolean = false;\n\n private nodeCall: INodeCall;\n\n constructor(nodeCall: INodeCall) {\n this.nodeCall = nodeCall;\n }\n\n /**\n * Bắt đầu xử lý MediaStream\n */\n public async connect(address: string): Promise<void> {\n try {\n await this.nodeCall.connect(address);\n await this.sendConnected();\n await this.sendConfigs();\n } catch (error) {\n console.error('Error starting MediaStreamSender:', error);\n }\n }\n\n public async sendConfigs(): Promise<void> {\n try {\n await this.sendTransceiverState(this.hasAudio, this.hasVideo);\n await this.sendAudioConfig();\n\n const videoTrack = this.localStream?.getVideoTracks()[0];\n if (videoTrack) {\n await this.sendVideoConfig();\n }\n } catch (error) {\n console.error('Error sending configs:', error);\n }\n }\n\n /**\n * Dừng và reset encoders\n */\n public stop = (): void => {\n if (this.videoReader) {\n try {\n this.videoReader.cancel('Stream stopped').catch(() => {});\n } catch (e) {}\n this.videoReader = null;\n }\n\n if (this.videoEncoder) {\n try {\n if (this.videoEncoder.state !== 'closed') {\n this.videoEncoder.reset(); // Xả frame\n this.videoEncoder.close();\n }\n } catch (e) {}\n this.videoEncoder = null;\n }\n\n // Reset and close audio encoder\n if (this.audioEncoder) {\n try {\n if (this.audioEncoder.state !== 'closed') {\n this.audioEncoder.reset();\n this.audioEncoder.close();\n }\n } catch (e) {}\n this.audioEncoder = null;\n }\n\n // Reset configs and flags\n this.videoConfig = null;\n this.audioConfig = null;\n\n this.videoConfigSent = false;\n this.audioConfigSent = false;\n this.hasVideo = false;\n this.hasAudio = false;\n\n if (this.localStream) {\n this.localStream.getTracks().forEach((track) => track.stop());\n this.localStream = null;\n }\n };\n\n public initAudioEncoder = (audioTrack: MediaStreamTrack): void => {\n this.localStream = new MediaStream([audioTrack]);\n this.audioConfigSent = false;\n this.hasAudio = !!audioTrack;\n\n const audioEncoder = new AudioEncoder({\n output: (chunk, metadata) => {\n if (metadata?.decoderConfig && !this.audioConfigSent) {\n let description: string | undefined = undefined;\n if (metadata.decoderConfig.description) {\n description = base64Encode(metadata.decoderConfig.description as ArrayBuffer);\n }\n\n this.audioConfig = {\n codec: metadata.decoderConfig.codec ?? 'opus',\n sampleRate: metadata.decoderConfig.sampleRate ?? 48000,\n numberOfChannels: metadata.decoderConfig.numberOfChannels ?? 1,\n ...(description && { description }),\n };\n }\n\n if (chunk && this.isReadyToSendData('audio')) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(data);\n // const timestamp = Math.floor(chunk.timestamp / 1000);\n const timestamp = chunk.timestamp;\n\n const packet = createPacketWithHeader(data, timestamp, 'audio', null);\n this.sendPacketOrQueue(packet, 'audio', null);\n }\n },\n error: (e) => console.error('AudioEncoder error:', e),\n });\n\n audioEncoder.configure({\n codec: 'mp4a.40.2',\n sampleRate: 48000,\n numberOfChannels: 1,\n bitrate: 128000,\n });\n\n this.audioEncoder = audioEncoder;\n this.processAudioFrames(audioTrack);\n };\n\n public initVideoEncoder(videoTrack: MediaStreamTrack): void {\n if (this.localStream) {\n this.localStream.addTrack(videoTrack);\n }\n\n this.videoConfigSent = false;\n this.hasVideo = !!videoTrack;\n\n const settings = videoTrack.getSettings();\n const videoWidth = settings.width || 1280;\n const videoHeight = settings.height || 720;\n\n const videoEncoder = new VideoEncoder({\n output: async (chunk, metadata) => {\n if (metadata?.decoderConfig && !this.videoConfigSent) {\n let description: string | undefined = undefined;\n if (metadata.decoderConfig.description) {\n description = base64Encode(metadata.decoderConfig.description as ArrayBuffer);\n }\n\n this.videoConfig = {\n codec: metadata.decoderConfig.codec ?? 'hev1.1.6.L93.B0',\n codedWidth: metadata.decoderConfig.codedWidth ?? videoWidth,\n codedHeight: metadata.decoderConfig.codedHeight ?? videoHeight,\n frameRate: 30.0,\n orientation: 0,\n ...(description && { description }),\n };\n\n await this.sendVideoConfig();\n }\n\n if (chunk && this.isReadyToSendData('video')) {\n const data = new ArrayBuffer(chunk.byteLength);\n chunk.copyTo(data);\n const frameType = chunk.type === 'key' ? 'video-key' : 'video-delta';\n // const timestamp = Math.floor(chunk.timestamp / 1000);\n const timestamp = chunk.timestamp;\n\n const packet = createPacketWithHeader(data, timestamp, frameType, null);\n this.sendPacketOrQueue(packet, 'video', frameType);\n }\n },\n error: (e) => console.error('VideoEncoder error:', e),\n });\n\n videoEncoder.configure({\n codec: 'hev1.1.6.L93.B0',\n width: videoWidth,\n height: videoHeight,\n bitrate: 500_000,\n framerate: 30,\n latencyMode: 'realtime',\n hardwareAcceleration: 'prefer-hardware',\n });\n\n this.videoEncoder = videoEncoder;\n this.processVideoFrames(videoTrack);\n }\n\n public initEncoders = (stream: MediaStream): void => {\n const videoTrack = stream.getVideoTracks()[0];\n const audioTrack = stream.getAudioTracks()[0];\n\n if (audioTrack) {\n this.initAudioEncoder(audioTrack);\n }\n\n if (videoTrack) {\n this.initVideoEncoder(videoTrack);\n }\n };\n\n public sendTransceiverState = async (audioEnable: boolean, videoEnable: boolean) => {\n const state: TransceiverState = {\n audio_enable: !!audioEnable,\n video_enable: !!videoEnable,\n };\n const configPacket = createPacketWithHeader(null, null, 'transciverState', state);\n await this.nodeCall.sendControlFrame(configPacket);\n };\n\n public async replaceVideoTrack(track: MediaStreamTrack): Promise<void> {\n // 1. Dừng reader của track cũ (quan trọng)\n if (this.videoReader) {\n try {\n // Việc gọi cancel sẽ làm Promise tại dòng await read() bên dưới throw lỗi hoặc trả về done\n await this.videoReader.cancel('Replacing track');\n } catch (e) {\n // Bỏ qua lỗi khi cancel\n }\n this.videoReader = null;\n }\n\n if (track) {\n this.processVideoFrames(track);\n }\n }\n\n public async replaceAudioTrack(track: MediaStreamTrack): Promise<void> {\n if (track) {\n this.processAudioFrames(track);\n }\n }\n\n /**\n * Yêu cầu gửi keyframe ngay lập tức (được gọi khi nhận REQUEST_KEY_FRAME từ receiver)\n */\n public requestKeyFrame = (): void => {\n console.log('📥 KeyFrame requested');\n this.forceKeyFrame = true;\n };\n\n // ================= PRIVATE METHODS =================\n\n private processVideoFrames = async (videoTrack: MediaStreamTrack) => {\n try {\n // @ts-ignore: MediaStreamTrackProcessor is explicitly defined in WebCodecs types\n const videoProcessor = new MediaStreamTrackProcessor({ track: videoTrack });\n this.videoReader = videoProcessor.readable.getReader();\n\n let frameCounter = 0;\n while (true) {\n if (!this.videoReader) break;\n\n const { done, value: frame } = await this.videoReader.read();\n if (done) break;\n\n if (!this.videoEncoder) {\n frame?.close();\n break;\n }\n\n if (frame) {\n frameCounter += 1;\n const keyFrame = frameCounter % 60 === 0 || this.forceKeyFrame;\n if (this.forceKeyFrame) {\n console.log('📤 Sending forced KeyFrame');\n this.forceKeyFrame = false;\n }\n try {\n this.videoEncoder.encode(frame, { keyFrame });\n } catch (err) {\n console.error('Encode error:', err);\n } finally {\n frame.close();\n }\n }\n }\n } catch (error: any) {\n console.error(`Error processing video frames: ${error.message}`);\n } finally {\n if (this.videoReader) {\n try {\n this.videoReader.releaseLock();\n } catch (e) {}\n // this.videoReader = null;\n }\n }\n };\n\n private processAudioFrames = async (audioTrack: MediaStreamTrack) => {\n // @ts-ignore\n const audioProcessor = new MediaStreamTrackProcessor({ track: audioTrack });\n const audioReader = audioProcessor.readable.getReader();\n\n try {\n while (true) {\n const { done, value: frame } = await audioReader.read();\n if (done) break;\n\n if (!this.audioEncoder) {\n frame?.close();\n break;\n }\n\n if (frame) {\n try {\n this.audioEncoder.encode(frame);\n } catch (err) {\n console.error('Audio Encoding error:', err);\n } finally {\n frame.close();\n }\n }\n }\n } catch (error: any) {\n console.error(`Error processing audio frames: ${error.message}`);\n }\n };\n\n private isReadyToSendData = (type: 'video' | 'audio'): boolean => {\n const videoReady = !this.hasVideo || this.videoConfigSent;\n const audioReady = !this.hasAudio || this.audioConfigSent;\n const allConfigsSent = videoReady && audioReady;\n\n if (type === 'video') {\n return allConfigsSent && this.videoConfigSent;\n } else if (type === 'audio') {\n return allConfigsSent && this.audioConfigSent;\n }\n\n return false;\n };\n\n private sendVideoConfig = async () => {\n if (this.videoConfig && !this.videoConfigSent) {\n try {\n const configPacket = createPacketWithHeader(null, null, 'videoConfig', this.videoConfig);\n await this.nodeCall.sendControlFrame(configPacket);\n this.videoConfigSent = true;\n } catch (error) {\n console.error('Error sending video config:', error);\n }\n }\n };\n\n private sendAudioConfig = async () => {\n if (this.audioConfig && !this.audioConfigSent) {\n try {\n const configPacket = createPacketWithHeader(null, null, 'audioConfig', this.audioConfig);\n await this.nodeCall.sendControlFrame(configPacket);\n this.audioConfigSent = true;\n } catch (error) {\n console.error('Error sending audio config:', error);\n }\n }\n };\n\n public sendConnected = async () => {\n const configPacket = createPacketWithHeader(null, null, 'connected', null);\n await this.nodeCall.sendControlFrame(configPacket);\n };\n\n private sendPacketOrQueue = async (\n packet: Uint8Array,\n type: 'video' | 'audio',\n frameType: 'video-key' | 'video-delta' | null,\n ) => {\n if (!this.isReadyToSendData(type)) {\n return;\n }\n\n if (type === 'audio') {\n await this.nodeCall.sendAudioFrame(packet);\n } else if (type === 'video') {\n if (frameType === 'video-key') {\n await this.nodeCall.beginWithGop(packet);\n } else if (frameType === 'video-delta') {\n await this.nodeCall.sendFrame(packet);\n }\n }\n };\n}\n","// 1. Định nghĩa các hằng số NAL Unit\nexport const NALUnitType = {\n VPS_NUT: 32,\n SPS_NUT: 33,\n PPS_NUT: 34,\n PREFIX_SEI_NUT: 39,\n SUFFIX_SEI_NUT: 40,\n\n fromValue(value: number): string | number {\n const types: Record<number, string> = {\n 32: 'VPS_NUT',\n 33: 'SPS_NUT',\n 34: 'PPS_NUT',\n 39: 'PREFIX_SEI_NUT',\n 40: 'SUFFIX_SEI_NUT',\n };\n return types[value] || value;\n },\n} as const;\n\n// 2. Interface cho mảng NAL Unit bên trong config\nexport interface INALArray {\n arrayCompleteness: boolean;\n nalUnitType: string | number;\n nalus: Uint8Array[];\n}\n\n// 3. Interface cho cấu hình HEVC (giúp strict type checking)\nexport interface IHEVCConfig {\n generalProfileSpace: number;\n generalTierFlag: boolean;\n generalProfileIdc: number;\n generalProfileCompatibilityFlags: number;\n generalConstraintIndicatorFlags: number;\n generalLevelIdc: number;\n minSpatialSegmentationIdc: number;\n parallelismType: number;\n chromaFormatIdc: number;\n bitDepthLumaMinus8: number;\n bitDepthChromaMinus8: number;\n avgFrameRate: number;\n constantFrameRate: number;\n numTemporalLayers: number;\n temporalIdNested: boolean;\n lengthSizeMinusOne: number;\n arrays: INALArray[];\n}\n\nexport class HEVCDecoderConfigurationRecord implements IHEVCConfig {\n // Khai báo các thuộc tính của class\n public generalProfileSpace: number = 0;\n public generalTierFlag: boolean = false;\n public generalProfileIdc: number = 0;\n public generalProfileCompatibilityFlags: number = 0;\n public generalConstraintIndicatorFlags: number = 0;\n public generalLevelIdc: number = 0;\n public minSpatialSegmentationIdc: number = 0;\n public parallelismType: number = 0;\n public chromaFormatIdc: number = 0;\n public bitDepthLumaMinus8: number = 0;\n public bitDepthChromaMinus8: number = 0;\n public avgFrameRate: number = 0;\n public constantFrameRate: number = 0;\n public numTemporalLayers: number = 0;\n public temporalIdNested: boolean = false;\n public lengthSizeMinusOne: number = 0;\n public arrays: INALArray[] = [];\n\n constructor(config: IHEVCConfig) {\n Object.assign(this, config);\n }\n\n /**\n * Demuxes an HEVCDecoderConfigurationRecord from a byte buffer.\n * @param data - The byte data to parse\n */\n static demux(data: ArrayBuffer | Uint8Array): HEVCDecoderConfigurationRecord {\n const buffer = data instanceof Uint8Array ? data : new Uint8Array(data);\n const view = new DataView(buffer.buffer, buffer.byteOffset, buffer.byteLength);\n\n let offset = 0;\n let bitOffset = 0;\n\n // Helper to read bits\n const readBits = (numBits: number): number => {\n let result = 0;\n for (let i = 0; i < numBits; i++) {\n if (offset >= buffer.length) throw new Error('End of buffer');\n const bit = (buffer[offset] >> (7 - bitOffset)) & 1;\n result = (result << 1) | bit;\n bitOffset++;\n if (bitOffset === 8) {\n bitOffset = 0;\n offset++;\n }\n }\n return result;\n };\n\n // Helper to read a byte\n const readU8 = (): number => {\n if (bitOffset !== 0) return readBits(8);\n if (offset >= buffer.length) throw new Error('End of buffer');\n return buffer[offset++];\n };\n\n // Helper to read 16-bit big-endian\n const readU16BE = (): number => {\n if (bitOffset !== 0) return readBits(16);\n const val = view.getUint16(offset, false);\n offset += 2;\n return val;\n };\n\n // Helper to read 32-bit big-endian\n const readU32BE = (): number => {\n if (bitOffset !== 0) return readBits(32);\n const val = view.getUint32(offset, false);\n offset += 4;\n return val;\n };\n\n // Helper to read 48-bit big-endian\n const readU48BE = (): number => {\n const high = readU16BE();\n const low = readU32BE();\n return high * 0x100000000 + low;\n };\n\n // Helper to read exact bytes\n const readExact = (length: number): Uint8Array => {\n if (bitOffset !== 0) {\n const result = new Uint8Array(length);\n for (let i = 0; i < length; i++) {\n result[i] = readBits(8);\n }\n return result;\n }\n if (offset + length > buffer.length) throw new Error('End of buffer');\n const result = buffer.slice(offset, offset + length);\n offset += length;\n return result;\n };\n\n // Parse configuration version\n const configurationVersion = readU8();\n if (configurationVersion !== 1) {\n throw new Error('Invalid configuration version');\n }\n\n // Parse profile information\n const generalProfileSpace = readBits(2);\n const generalTierFlag = readBits(1) === 1;\n const generalProfileIdc = readBits(5);\n const generalProfileCompatibilityFlags = readU32BE();\n const generalConstraintIndicatorFlags = readU48BE();\n const generalLevelIdc = readU8();\n\n // Parse spatial segmentation\n readBits(4); // reserved_4bits\n const minSpatialSegmentationIdc = readBits(12);\n\n // Parse parallelism type\n readBits(6); // reserved_6bits\n const parallelismType = readBits(2);\n\n // Parse chroma format\n readBits(6); // reserved_6bits\n const chromaFormatIdc = readBits(2);\n\n // Parse bit depth (luma)\n readBits(5); // reserved_5bits\n const bitDepthLumaMinus8 = readBits(3);\n\n // Parse bit depth (chroma)\n readBits(5); // reserved_5bits\n const bitDepthChromaMinus8 = readBits(3);\n\n // Parse frame rate and temporal information\n const avgFrameRate = readU16BE();\n const constantFrameRate = readBits(2);\n const numTemporalLayers = readBits(3);\n const temporalIdNested = readBits(1) === 1;\n const lengthSizeMinusOne = readBits(2);\n\n if (lengthSizeMinusOne === 2) {\n throw new Error('length_size_minus_one must be 0, 1, or 3');\n }\n\n // Parse NALU arrays\n const numOfArrays = readU8();\n const arrays: INALArray[] = [];\n\n for (let i = 0; i < numOfArrays; i++) {\n const arrayCompleteness = readBits(1) === 1;\n readBits(1); // reserved\n const nalUnitType = readBits(6);\n const nalUnitTypeName = NALUnitType.fromValue(nalUnitType);\n\n if (\n nalUnitType !== NALUnitType.VPS_NUT &&\n nalUnitType !== NALUnitType.SPS_NUT &&\n nalUnitType !== NALUnitType.PPS_NUT &&\n nalUnitType !== NALUnitType.PREFIX_SEI_NUT &&\n nalUnitType !== NALUnitType.SUFFIX_SEI_NUT\n ) {\n // Có thể comment dòng này nếu muốn hỗ trợ các loại NALU khác không chuẩn\n // throw new Error('Invalid nal_unit_type');\n }\n\n const numNalus = readU16BE();\n const nalus: Uint8Array[] = [];\n\n for (let j = 0; j < numNalus; j++) {\n const nalUnitLength = readU16BE();\n const naluData = readExact(nalUnitLength);\n nalus.push(naluData);\n }\n\n arrays.push({\n arrayCompleteness,\n nalUnitType: nalUnitTypeName,\n nalus,\n });\n }\n\n return new HEVCDecoderConfigurationRecord({\n generalProfileSpace,\n generalTierFlag,\n generalProfileIdc,\n generalProfileCompatibilityFlags,\n generalConstraintIndicatorFlags,\n generalLevelIdc,\n minSpatialSegmentationIdc,\n parallelismType,\n chromaFormatIdc,\n bitDepthLumaMinus8,\n bitDepthChromaMinus8,\n avgFrameRate,\n constantFrameRate,\n numTemporalLayers,\n temporalIdNested,\n lengthSizeMinusOne,\n arrays,\n });\n }\n\n /**\n * Converts the HEVC configuration to a codec string (RFC 6381 format).\n * @returns Codec string like \"hev1.1.6.L93.B0\"\n */\n toCodecString(): string {\n const profileSpaceMap: Record<number, string> = { 0: '', 1: 'A', 2: 'B', 3: 'C' };\n const generalProfileSpace = profileSpaceMap[this.generalProfileSpace];\n\n if (generalProfileSpace === undefined) {\n throw new Error('Unknown profile space');\n }\n\n const profileAndSpace = `${generalProfileSpace}${this.generalProfileIdc}`;\n\n // Format profile compatibility flags (reverse hex and strip trailing zeros)\n let profileCompatibilityFlagsUnfiltered = this.generalProfileCompatibilityFlags\n .toString(16)\n .padStart(8, '0')\n .split('')\n .reverse()\n .join('');\n\n let profileCompatibilityFlags = '';\n for (let i = 0; i < profileCompatibilityFlagsUnfiltered.length; i++) {\n const char = profileCompatibilityFlagsUnfiltered[i];\n if (char !== '0' || i === 0) {\n profileCompatibilityFlags += char;\n }\n }\n\n // Format tier and level\n const generalTierFlag = this.generalTierFlag ? 'H' : 'L';\n const tierAndLevel = `${generalTierFlag}${this.generalLevelIdc}`;\n\n // Format constraint flags (skip first 2 bytes of 48-bit value)\n let constraintFlags = '';\n\n // Convert 48-bit number to 6 bytes\n const constraint = this.generalConstraintIndicatorFlags;\n const bytes = [\n Math.floor(constraint / 0x10000000000) & 0xff,\n Math.floor(constraint / 0x100000000) & 0xff,\n Math.floor(constraint / 0x1000000) & 0xff,\n Math.floor(constraint / 0x10000) & 0xff,\n Math.floor(constraint / 0x100) & 0xff,\n constraint & 0xff,\n ];\n\n // Skip first 2 bytes (bytes[0] and bytes[1]) per Logic\n for (let i = 2; i < 6; i++) {\n if (bytes[i] !== 0) {\n constraintFlags += `.${bytes[i].toString(16).padStart(2, '0')}`;\n }\n }\n\n return `hev1.${profileAndSpace}.${profileCompatibilityFlags}.${tierAndLevel}${constraintFlags}`;\n }\n}\n","import { replaceCodecNumber } from './utils';\nimport { FRAME_TYPE, IMediaReceiverEvents, INodeCall, VideoConfig } from './types';\nimport { HEVCDecoderConfigurationRecord } from './hevc_decoder_config';\n\n// Các biến cấu hình Audio Sync\nconst MAX_AUDIO_LATENCY = 0.1; // 100ms\nconst MIN_BUFFER_AHEAD = 0.02; // 20ms\n\nexport class MediaStreamReceiver {\n private videoDecoder: VideoDecoder | null = null;\n private audioDecoder: AudioDecoder | null = null;\n\n // WritableStreamDefaultWriter<VideoFrame> là type chuẩn của WebCodecs\n private videoWriter: WritableStreamDefaultWriter<VideoFrame> | null = null;\n\n private audioContext: AudioContext | null = null;\n private mediaDestination: MediaStreamAudioDestinationNode | null = null;\n\n private isWaitingForKeyFrame: boolean = true;\n private nextStartTime: number = 0;\n private lastVideoConfig: VideoConfig | null = null;\n\n private nodeCall: INodeCall;\n private events: IMediaReceiverEvents;\n\n private generatedStream: MediaStream | null = null;\n\n constructor(nodeCall: INodeCall, events: IMediaReceiverEvents = {}) {\n this.nodeCall = nodeCall;\n this.events = events;\n }\n\n public async acceptConnection(): Promise<void> {\n try {\n await this.nodeCall.acceptConnection();\n } catch (error) {\n console.error('❌ Error starting MediaStreamReceiver:', error);\n }\n }\n\n public getRemoteStream = (): MediaStream | null => {\n return this.generatedStream;\n };\n\n /**\n * Dừng toàn bộ quá trình và giải phóng tài nguyên\n */\n public stop = (): void => {\n this.resetDecoders();\n };\n\n // ================= PRIVATE METHODS =================\n\n private initAudioContext = async (): Promise<void> => {\n if (!this.audioContext || this.audioContext.state === 'closed') {\n const AudioContextClass = window.AudioContext || (window as any).webkitAudioContext;\n this.audioContext = new AudioContextClass({\n sampleRate: 48000,\n latencyHint: 'interactive',\n });\n\n this.mediaDestination = this.audioContext.createMediaStreamDestination();\n\n if (this.audioContext.state === 'suspended') {\n await this.audioContext.resume();\n }\n this.nextStartTime = this.audioContext.currentTime + MIN_BUFFER_AHEAD;\n }\n };\n\n public initDecoders = (callType: string): void => {\n // 1. Audio Decoder Setup\n if (this.audioDecoder) this.audioDecoder.close();\n\n // 2. Setup Audio Context & Streams\n this.initAudioContext();\n\n // Đảm bảo mediaDestination đã được tạo trong initAudioContext\n if (this.mediaDestination) {\n const audioTrack = this.mediaDestination.stream.getAudioTracks()[0];\n\n // Khởi tạo stream với 1 track audio\n this.generatedStream = new MediaStream([audioTrack]);\n }\n\n this.isWaitingForKeyFrame = true;\n\n // 3. Init AudioDecoder\n this.audioDecoder = new AudioDecoder({\n output: (audioData) => this.playDecodedAudio(audioData),\n error: (err) => console.error('AudioDecoder error:', err),\n });\n\n if (callType === 'video') {\n // 4. Setup VideoDecoder\n this.setupVideoDecoder();\n }\n\n this.receiveLoop();\n };\n\n public setupVideoDecoder = (): void => {\n if (!this.videoWriter) return;\n\n if (this.videoDecoder) {\n try {\n if (this.videoDecoder.state !== 'closed') this.videoDecoder.close();\n } catch (e) {\n /* ignore */\n }\n }\n\n const videoDecoder = new VideoDecoder({\n output: async (frame) => {\n try {\n if (!this.videoWriter) {\n frame.close();\n return;\n }\n\n // Backpressure check: Nếu writer đang bận, drop frame để tránh overflow\n if (this.videoWriter.desiredSize! <= 0) {\n frame.close();\n return;\n }\n\n await this.videoWriter.write(frame);\n } catch (err) {\n frame.close();\n // console.error('Frame write error:', err);\n } finally {\n frame.close();\n }\n },\n error: (err) => {\n console.error('❌ VideoDecoder CRASHED:', err);\n this.isWaitingForKeyFrame = true;\n\n if (this.videoWriter) {\n // Chỉ hồi sinh nếu Writer vẫn còn sống\n console.log('♻️ Attempting to respawn VideoDecoder...');\n this.setupVideoDecoder();\n if (this.lastVideoConfig && this.videoDecoder) {\n try {\n this.videoDecoder.configure(this.lastVideoConfig);\n } catch (configErr) {}\n }\n }\n },\n });\n\n this.videoDecoder = videoDecoder;\n };\n\n private playDecodedAudio = (audioData: AudioData): void => {\n try {\n if (!this.audioContext || !this.mediaDestination) {\n audioData.close();\n return;\n }\n\n const { numberOfChannels, numberOfFrames, sampleRate } = audioData;\n const duration = numberOfFrames / sampleRate;\n const currentTime = this.audioContext.currentTime;\n\n // --- XỬ LÝ LATENCY & SYNC ---\n if (this.nextStartTime < currentTime) {\n this.nextStartTime = currentTime;\n } else if (this.nextStartTime > currentTime + MAX_AUDIO_LATENCY) {\n // Nếu buffer quá lớn (latency cao), reset về thời điểm hiện tại\n this.nextStartTime = currentTime + MIN_BUFFER_AHEAD;\n }\n\n const audioBuffer = this.audioContext.createBuffer(numberOfChannels, numberOfFrames, sampleRate);\n const size = numberOfChannels * numberOfFrames;\n const tempBuffer = new Float32Array(size);\n\n audioData.copyTo(tempBuffer, { planeIndex: 0, format: 'f32-planar' });\n\n for (let ch = 0; ch < numberOfChannels; ch++) {\n const channelData = tempBuffer.subarray(ch * numberOfFrames, (ch + 1) * numberOfFrames);\n audioBuffer.copyToChannel(channelData, ch);\n }\n\n const source = this.audioContext.createBufferSource();\n source.buffer = audioBuffer;\n source.connect(this.mediaDestination);\n\n source.start(this.nextStartTime);\n this.nextStartTime += duration;\n\n audioData.close();\n } catch (err) {\n console.error('Error in playDecodedAudio:', err);\n audioData?.close();\n }\n };\n\n private newCodecFromDescription = (buffer: ArrayBuffer, receivedCodec: string): string => {\n // Chỉ check nếu codec là HEVC (hvc1 hoặc hev1)\n if (!receivedCodec.toLowerCase().includes('hvc') && !receivedCodec.toLowerCase().includes('hev')) return '';\n\n try {\n const record = HEVCDecoderConfigurationRecord.demux(buffer);\n return record.toCodecString();\n } catch (error) {\n return '';\n }\n };\n\n // Vòng lặp chính xử lý dữ liệu\n public receiveLoop = async (): Promise<void> => {\n const textDecoder = new TextDecoder();\n\n while (true) {\n try {\n if (!this.nodeCall) break;\n\n // Gọi hàm nhận dữ liệu async\n const data = await this.nodeCall.asyncRecv();\n\n const dataView = new DataView(data.buffer, data.byteOffset, data.byteLength);\n const frameType = dataView.getUint8(0);\n\n // const frameTypeName =\n // {\n // [FRAME_TYPE.VIDEO_CONFIG]: 'VIDEO_CONFIG',\n // [FRAME_TYPE.AUDIO_CONFIG]: 'AUDIO_CONFIG',\n // [FRAME_TYPE.VIDEO_KEY]: 'VIDEO_KEY',\n // [FRAME_TYPE.VIDEO_DELTA]: 'VIDEO_DELTA',\n // [FRAME_TYPE.AUDIO]: 'AUDIO',\n // [FRAME_TYPE.CONNECTED]: 'CONNECTED',\n // [FRAME_TYPE.TRANSCEIVER_STATE]: 'TRANSCEIVER_STATE',\n // [FRAME_TYPE.ORIENTATION]: 'ORIENTATION',\n // [FRAME_TYPE.REQUEST_CONFIG]: 'REQUEST_CONFIG',\n // [FRAME_TYPE.REQUEST_KEY_FRAME]: 'REQUEST_KEY_FRAME',\n // [FRAME_TYPE.END_CALL]: 'END_CALL',\n // }[frameType] || 'UNKNOWN';\n\n // console.log(`----frameType ${frameTypeName}----`, frameType);\n\n const payloadOffset = (\n [\n FRAME_TYPE.VIDEO_CONFIG,\n FRAME_TYPE.AUDIO_CONFIG,\n FRAME_TYPE.CONNECTED,\n FRAME_TYPE.TRANSCEIVER_STATE,\n FRAME_TYPE.ORIENTATION,\n FRAME_TYPE.REQUEST_CONFIG,\n FRAME_TYPE.REQUEST_KEY_FRAME,\n FRAME_TYPE.END_CALL,\n ] as number[]\n ).includes(frameType)\n ? 1\n : 9; // 1 byte type + 8 bytes timestamp\n\n const payload = new Uint8Array(data.buffer, data.byteOffset + payloadOffset, data.byteLength - payloadOffset);\n\n switch (frameType) {\n // --- VIDEO CONFIG ---\n case FRAME_TYPE.VIDEO_CONFIG: {\n try {\n const videoConfigStr = textDecoder.decode(payload);\n const videoConfig = JSON.parse(videoConfigStr);\n console.log('--videoConfig--', videoConfig);\n\n // Setup Video Track Writer & Combine Streams\n if (!this.videoWriter) {\n // @ts-ignore: MediaStreamTrackGenerator types\n const videoTrackGenerator = new MediaStreamTrackGenerator({ kind: 'video' });\n this.videoWriter = videoTrackGenerator.writable.getWriter();\n\n // MERGE: Add Video Track vào Stream Audio đã có sẵn\n if (this.generatedStream) {\n this.generatedStream.addTrack(videoTrackGenerator);\n }\n }\n\n if (!this.videoDecoder) {\n this.setupVideoDecoder();\n }\n\n this.isWaitingForKeyFrame = true;\n\n let descriptionBuffer: ArrayBuffer | undefined = undefined;\n if (videoConfig.description) {\n try {\n const binaryString = atob(videoConfig.description);\n const desc = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n desc[i] = binaryString.charCodeAt(i);\n }\n descriptionBuffer = desc.buffer;\n } catch (e) {}\n }\n\n // const newCodec = replaceCodecNumber(videoConfig.codec);\n\n let newCodec: string = '';\n if (descriptionBuffer) {\n newCodec =\n this.newCodecFromDescription(descriptionBuffer, videoConfig.codec) ||\n replaceCodecNumber(videoConfig.codec);\n }\n\n const decoderConfig: VideoConfig = {\n codec: newCodec,\n frameRate: videoConfig.frameRate,\n codedWidth: videoConfig.codedWidth,\n codedHeight: videoConfig.codedHeight,\n ...(videoConfig.orientation && { rotation: videoConfig.orientation }),\n ...(descriptionBuffer && { description: descriptionBuffer }),\n };\n\n this.lastVideoConfig = decoderConfig;\n\n if (this.videoDecoder && this.videoDecoder.state !== 'closed') {\n const support = await VideoDecoder.isConfigSupported(decoderConfig);\n if (support.supported) {\n this.videoDecoder.configure(decoderConfig);\n this.isWaitingForKeyFrame = true;\n } else {\n console.error('❌ Browser does not support this video config:', decoderConfig);\n }\n }\n } catch (error) {\n console.error('❌ Error processing VIDEO_CONFIG:', error);\n }\n break;\n }\n\n // --- AUDIO CONFIG ---\n case FRAME_TYPE.AUDIO_CONFIG: {\n const audioConfig = JSON.parse(textDecoder.decode(payload));\n console.log('--audioConfig--', audioConfig);\n\n if (this.audioDecoder?.state !== 'closed') {\n this.audioDecoder?.configure({\n codec: audioConfig.codec,\n sampleRate: audioConfig.sampleRate,\n numberOfChannels: audioConfig.numberOfChannels,\n });\n }\n break;\n }\n\n // --- VIDEO DATA ---\n case FRAME_TYPE.VIDEO_KEY:\n case FRAME_TYPE.VIDEO_DELTA: {\n if (!this.videoDecoder || this.videoDecoder.state !== 'configured') break;\n const isKeyFrame = frameType === FRAME_TYPE.VIDEO_KEY;\n\n if (this.isWaitingForKeyFrame) {\n if (!isKeyFrame) break;\n console.log('✅ Resumed decoding at KeyFrame');\n this.isWaitingForKeyFrame = false;\n }\n\n if (!isKeyFrame && this.videoDecoder.decodeQueueSize > 15) {\n console.warn('⚠️ Queue > 15. Dropping & Waiting for KeyFrame...');\n // Nếu drop bất kỳ frame nào, ta phải chờ Key Frame tiếp theo mới decode được\n this.isWaitingForKeyFrame = true;\n break;\n }\n\n // const timestamp = dataView.getUint32(1, false);\n const timestampBigInt = dataView.getBigUint64(1, false);\n const timestamp = Number(timestampBigInt);\n\n try {\n this.videoDecoder.decode(\n new EncodedVideoChunk({\n type: isKeyFrame ? 'key' : 'delta',\n timestamp: timestamp,\n data: payload,\n }),\n );\n } catch (decodeErr) {\n console.error('Video decode failed:', decodeErr);\n if ((this.videoDecoder as VideoDecoder).state === 'closed') {\n // this.setupVideoDecoder();\n // if (this.lastVideoConfig) {\n // this.videoDecoder?.configure(this.lastVideoConfig);\n // }\n this.isWaitingForKeyFrame = true;\n }\n }\n break;\n }\n\n // --- AUDIO DATA ---\n case FRAME_TYPE.AUDIO: {\n if (this.audioDecoder?.state === 'configured') {\n // const timestamp = dataView.getUint32(1, false);\n const timestampBigInt = dataView.getBigUint64(1, false);\n const timestamp = Number(timestampBigInt);\n this.audioDecoder.decode(\n new EncodedAudioChunk({\n type: 'key',\n timestamp: timestamp,\n data: payload,\n }),\n );\n }\n break;\n }\n\n case FRAME_TYPE.CONNECTED:\n if (this.events.onConnected) {\n this.events.onConnected();\n }\n break;\n\n case FRAME_TYPE.TRANSCEIVER_STATE:\n const transceiverState = JSON.parse(textDecoder.decode(payload));\n if (this.events.onTransceiverState) {\n this.events.onTransceiverState(transceiverState);\n }\n break;\n\n case FRAME_TYPE.ORIENTATION: {\n const orientation = dataView.getInt32(1, false);\n if (this.videoDecoder && this.lastVideoConfig && this.lastVideoConfig.rotation !== orientation) {\n this.lastVideoConfig.rotation = orientation;\n try {\n // 1. Configure lại với rotation mới\n this.videoDecoder.configure(this.lastVideoConfig);\n\n // 2. QUAN TRỌNG: Phải chờ KeyFrame mới để tránh lỗi decode Delta frame sau khi reset\n this.isWaitingForKeyFrame = true;\n\n console.log('🔄 Reconfigured rotation to', orientation, '- Waiting for next KeyFrame');\n } catch (configErr) {\n console.error('Error reconfiguring VideoDecoder with new orientation:', configErr);\n }\n }\n break;\n }\n\n case FRAME_TYPE.REQUEST_CONFIG:\n console.log('📥 Received REQUEST_CONFIG');\n if (this.events.onRequestConfig) {\n this.events.onRequestConfig();\n }\n break;\n\n case FRAME_TYPE.REQUEST_KEY_FRAME:\n console.log('📥 Received REQUEST_KEY_FRAME');\n if (this.events.onRequestKeyFrame) {\n this.events.onRequestKeyFrame();\n }\n break;\n\n case FRAME_TYPE.END_CALL:\n console.log('📥 Received END_CALL');\n if (this.events.onEndCall) {\n this.events.onEndCall();\n }\n break;\n\n default:\n console.warn('❓ Unknown frame type received:', frameType);\n break;\n }\n } catch (error) {\n console.error('Stream loop error', error);\n // Có thể thêm delay nhỏ ở đây để tránh spam error nếu loop lỗi liên tục\n await new Promise((r) => setTimeout(r, 200));\n }\n }\n };\n\n private resetDecoders = (): void => {\n if (this.videoWriter) {\n try {\n this.videoWriter.abort('Stream stopped').catch(() => {});\n this.videoWriter.releaseLock();\n } catch (e) {\n console.warn('Error closing video writer:', e);\n }\n this.videoWriter = null;\n }\n\n if (this.videoDecoder) {\n try {\n if (this.videoDecoder.state !== 'closed') {\n this.videoDecoder.reset();\n this.videoDecoder.close();\n }\n } catch (e) {}\n this.videoDecoder = null;\n }\n\n if (this.audioDecoder) {\n try {\n if (this.audioDecoder.state !== 'closed') {\n this.audioDecoder.reset();\n this.audioDecoder.close();\n }\n } catch (e) {}\n this.audioDecoder = null;\n }\n\n // Đóng AudioContext\n if (this.audioContext) {\n try {\n this.audioContext.close();\n } catch (e) {\n console.warn('Error closing audio context:', e);\n }\n this.audioContext = null;\n }\n\n // Reset các biến\n this.isWaitingForKeyFrame = true;\n this.mediaDestination = null;\n this.nextStartTime = 0;\n this.lastVideoConfig = null;\n\n if (this.generatedStream) {\n this.generatedStream.getTracks().forEach((track) => track.stop());\n this.generatedStream = null;\n }\n };\n}\n","import { ErmisChat } from './client';\nimport init, { ErmisCall } from './wasm/ermis_call_node_wasm';\nimport {\n CallAction,\n CallEventData,\n CallStatus,\n DefaultGenerics,\n Event,\n ExtendableGenerics,\n Metadata,\n SignalData,\n UserCallInfo,\n} from './types';\nimport { MediaStreamSender } from './media_stream_sender';\nimport { MediaStreamReceiver } from './media_stream_receiver';\n\nexport class ErmisCallNode<ErmisChatGenerics extends ExtendableGenerics = DefaultGenerics> {\n wasmPath: string;\n\n relayUrl = 'https://test-iroh.ermis.network.:8443';\n\n /** Reference to the Ermis Chat client instance */\n _client: ErmisChat<ErmisChatGenerics>;\n\n /** Unique identifier for the current call session */\n sessionID: string;\n\n /** Channel ID for communication between users */\n cid?: string;\n\n /** Type of call: 'audio' or 'video' */\n callType?: string;\n\n /** ID of the current user */\n userID?: string | undefined;\n\n /** Current status of the call */\n callStatus? = '';\n\n metadata?: Metadata;\n\n callNode: ErmisCall | null = null;\n\n /** Local media stream from user's camera/microphone */\n localStream?: MediaStream | null = null;\n\n /** Remote media stream from the other participant */\n remoteStream?: MediaStream | null = null;\n\n /** Information about the caller */\n callerInfo?: UserCallInfo;\n\n /** Information about the call receiver */\n receiverInfo?: UserCallInfo;\n\n /** Callback triggered when call events occur (incoming/outgoing) */\n onCallEvent?: (data: CallEventData) => void;\n\n /** Callback triggered when local stream is available */\n onLocalStream?: (stream: MediaStream) => void;\n\n /** Callback triggered when remote stream is available */\n onRemoteStream?: (stream: MediaStream) => void;\n\n /** Callback for connection status message changes */\n onConnectionMessageChange?: (message: string | null) => void;\n\n /** Callback for call status changes */\n onCallStatus?: (status: string | null) => void;\n\n /** Callback for messages received through WebRTC data channel */\n onDataChannelMessage?: (data: any) => void;\n\n /** Callback for when a call is upgraded (e.g., audio to video) */\n onUpgradeCall?: (upgraderInfo: UserCallInfo) => void;\n\n /** Callback for screen sharing status changes */\n onScreenShareChange?: (isSharing: boolean) => void;\n\n /** Callback for error handling */\n onError?: (error: string) => void;\n\n /** Callback for device list changes */\n onDeviceChange?: (audioDevices: MediaDeviceInfo[], videoDevices: MediaDeviceInfo[]) => void;\n\n /** Available audio input devices */\n private availableAudioDevices: MediaDeviceInfo[] = [];\n\n /** Available video input devices */\n private availableVideoDevices: MediaDeviceInfo[] = [];\n\n /** Currently selected audio device ID */\n private selectedAudioDeviceId?: string;\n\n /** Currently selected video device ID */\n private selectedVideoDeviceId?: string;\n\n /** Timeout for ending call if not answered after a period */\n private missCallTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Interval for sending health check via WebRTC */\n private healthCallInterval: ReturnType<typeof setInterval> | null = null;\n\n /** Interval for sending health check via server */\n private healthCallServerInterval: ReturnType<typeof setInterval> | null = null;\n\n /** Timeout for detecting if remote peer has disconnected */\n private healthCallTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Timeout for showing warning when connection becomes unstable */\n private healthCallWarningTimeout: ReturnType<typeof setTimeout> | null = null;\n\n /** Handler for signal events */\n private signalHandler: any;\n\n /** Handler for connection change events */\n private connectionChangedHandler: any;\n\n /** Handler for message updated events */\n private messageUpdatedHandler: any;\n\n /** Flag indicating if the user is offline */\n private isOffline: boolean = false;\n\n /**\n * True if this call instance is destroyed (e.g., when another device accepts the call).\n * When true, SIGNAL_CALL events will be ignored.\n */\n private isDestroyed = false;\n\n public mediaSender: MediaStreamSender | null = null;\n public mediaReceiver: MediaStreamReceiver | null = null;\n\n constructor(client: ErmisChat<ErmisChatGenerics>, sessionID: string, wasmPath: string, relayUrl: string) {\n this._client = client;\n this.cid = '';\n this.callType = '';\n this.sessionID = sessionID;\n this.userID = client.userID;\n this.metadata = {};\n this.wasmPath = wasmPath;\n this.relayUrl = relayUrl;\n\n this.listenSocketEvents();\n this.setupDeviceChangeListener();\n this.loadWasm();\n }\n\n private async loadWasm(): Promise<void> {\n try {\n await init(this.wasmPath);\n } catch (error) {\n console.error('Failed to load ErmisCall WASM module:', error);\n throw error;\n }\n }\n\n private async initialize(): Promise<ErmisCall> {\n try {\n const node = new ErmisCall();\n await node.spawn([this.relayUrl]);\n this.callNode = node;\n\n // 1. Init Sender\n this.mediaSender = new MediaStreamSender(node as any);\n\n // 2. Init Receiver\n this.mediaReceiver = new MediaStreamReceiver(node as any, {\n onConnected: () => {\n this.setCallStatus(CallStatus.CONNECTED);\n this.connectCall();\n if (this.missCallTimeout) {\n clearTimeout(this.missCallTimeout);\n this.missCallTimeout = null;\n }\n if (this.healthCallServerInterval) clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = setInterval(() => {\n this.healthCall();\n }, 10000);\n\n const remoteStream = this.mediaReceiver?.getRemoteStream();\n\n if (remoteStream && this.onRemoteStream) {\n this.onRemoteStream(remoteStream);\n }\n },\n\n onTransceiverState: (state) => {\n if (typeof this.onDataChannelMessage === 'function') {\n this.onDataChannelMessage(state);\n }\n },\n\n onRequestConfig: () => {\n console.log('📤 Responding to REQUEST_CONFIG by sending configs');\n this.mediaSender?.sendConfigs();\n },\n\n onRequestKeyFrame: () => {\n console.log('📤 Responding to REQUEST_KEY_FRAME by forcing key frame');\n this.mediaSender?.requestKeyFrame();\n },\n\n onEndCall: () => {\n console.log('📥 Received END_CALL from remote peer');\n this.destroy();\n },\n });\n\n return node;\n } catch (error) {\n console.error('Failed to initialize Ermis SDK:', error);\n throw error;\n }\n }\n\n public async getLocalEndpointAddr(): Promise<string | null> {\n try {\n await this.initialize();\n\n if (!this.callNode) {\n console.error('ErmisCall is not initialized.');\n return null;\n }\n\n const address = await this.callNode.getLocalEndpointAddr();\n if (this.metadata) {\n this.metadata.address = address;\n }\n return address;\n } catch (error) {\n console.error('Failed to get address from ErmisCall:', error);\n return null;\n }\n }\n\n private getClient(): ErmisChat<ErmisChatGenerics> {\n return this._client;\n }\n\n private async _sendSignal(payload: SignalData) {\n try {\n return await this.getClient().post(this.getClient().baseURL + '/signal', {\n ...payload,\n cid: this.cid || payload.cid,\n is_video: this.callType === 'video' || payload.is_video,\n ios: false,\n session_id: this.sessionID,\n });\n } catch (error: any) {\n const action = payload.action;\n\n // Skip error message for HEALTH_CALL action\n if (action === CallAction.HEALTH_CALL) {\n return;\n }\n\n if (typeof this.onError === 'function') {\n if (error.code === 'ERR_NETWORK') {\n if (action === CallAction.CREATE_CALL) {\n this.onError('Unable to make the call. Please check your network connection');\n }\n } else {\n if (error.response.data.ermis_code === 20) {\n this.onError('Recipient was busy');\n } else {\n const errMsg = error.response.data?.message ? error.response.data?.message : 'Call failed';\n this.onError(errMsg);\n }\n }\n }\n }\n }\n\n private async getAvailableDevices(): Promise<{ audioDevices: MediaDeviceInfo[]; videoDevices: MediaDeviceInfo[] }> {\n try {\n const devices = await navigator.mediaDevices.enumerateDevices();\n\n const audioDevices = devices.filter((device) => device.kind === 'audioinput');\n const videoDevices = devices.filter((device) => device.kind === 'videoinput');\n\n this.availableAudioDevices = audioDevices;\n this.availableVideoDevices = videoDevices;\n\n return { audioDevices, videoDevices };\n } catch (error) {\n console.error('Error enumerating devices:', error);\n return { audioDevices: [], videoDevices: [] };\n }\n }\n\n private async getMediaConstraints() {\n // Get available devices first\n const { audioDevices, videoDevices } = await this.getAvailableDevices();\n\n // Notify UI about available devices\n if (this.onDeviceChange) {\n this.onDeviceChange(audioDevices, videoDevices);\n }\n\n // Auto-select default devices if none selected\n if (!this.selectedAudioDeviceId && audioDevices.length > 0) {\n this.selectedAudioDeviceId = audioDevices[0].deviceId;\n }\n if (!this.selectedVideoDeviceId && videoDevices.length > 0) {\n this.selectedVideoDeviceId = videoDevices[0].deviceId;\n }\n\n // Build constraints with specific device IDs if selected\n const audioConstraints = {\n deviceId: this.selectedAudioDeviceId ? { exact: this.selectedAudioDeviceId } : undefined,\n echoCancellation: true,\n noiseSuppression: true,\n sampleRate: 48000,\n };\n\n const videoConstraints =\n this.callType === 'video'\n ? {\n deviceId: this.selectedVideoDeviceId ? { exact: this.selectedVideoDeviceId } : undefined,\n width: 640,\n height: 360,\n }\n : false;\n\n const finalConstraints: MediaStreamConstraints = {\n audio: audioConstraints,\n video: videoConstraints,\n };\n\n return finalConstraints;\n }\n\n public async startLocalStream() {\n const mediaConstraints = await this.getMediaConstraints();\n\n try {\n const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n return this.applyLocalStream(stream);\n } catch (error: any) {\n console.warn('Error getting user media:', error?.message);\n\n // Video call: try fallback to audio-only (camera not available)\n if (this.callType === 'video' && mediaConstraints.video) {\n try {\n const audioOnlyStream = await navigator.mediaDevices.getUserMedia({\n audio: mediaConstraints.audio,\n video: false,\n });\n this.setConnectionMessage('Camera not available, using audio only');\n return this.applyLocalStream(audioOnlyStream);\n } catch {\n // Audio fallback also failed\n }\n }\n\n // No device found at all — report error\n if (typeof this.onError === 'function') {\n this.onError('No microphone or camera found. Please check your device.');\n }\n return null;\n }\n }\n\n private applyLocalStream(stream: MediaStream) {\n if (this.callStatus === CallStatus.ENDED) {\n stream.getTracks().forEach((track) => track.stop());\n this.destroy();\n return;\n }\n if (this.onLocalStream) {\n this.onLocalStream(stream);\n }\n this.localStream = stream;\n return stream;\n }\n\n private setConnectionMessage(message: string | null) {\n if (typeof this.onConnectionMessageChange === 'function') {\n this.onConnectionMessageChange(message);\n }\n }\n\n private setCallStatus(status: CallStatus) {\n this.callStatus = status;\n if (typeof this.onCallStatus === 'function') {\n this.onCallStatus(status);\n }\n }\n\n private setUserInfo(cid: string | undefined, eventUserId: string | undefined) {\n if (!cid || !eventUserId) return;\n\n // Get caller and receiver userId from activeChannels\n const channel = cid ? this.getClient().activeChannels[cid] : undefined;\n const members = channel?.state?.members || {};\n const memberIds = Object.keys(members);\n\n // callerId is eventUserId, receiverId is the other user in the channel\n const callerId = eventUserId || '';\n const receiverId = memberIds.find((id) => id !== callerId) || '';\n\n // Get user info from client.state.users\n const callerUser = this.getClient().state.users[callerId];\n const receiverUser = this.getClient().state.users[receiverId];\n\n this.callerInfo = {\n id: callerId,\n name: callerUser?.name,\n avatar: callerUser?.avatar || '',\n };\n this.receiverInfo = {\n id: receiverId,\n name: receiverUser?.name,\n avatar: receiverUser?.avatar || '',\n };\n }\n\n private listenSocketEvents() {\n this.signalHandler = async (event: Event<ErmisChatGenerics>) => {\n const { action, user_id: eventUserId, session_id: eventSessionId, cid, is_video, signal, metadata } = event;\n\n switch (action) {\n case CallAction.CREATE_CALL:\n if (eventUserId === this.userID && eventSessionId !== this.sessionID) {\n // If the event is triggered by the current user but the session ID is different,\n // it means another device (or tab) of the same user has started a call.\n // In this case, mark this call instance as destroyed and ignore further events.\n this.isDestroyed = true;\n this.destroy();\n return;\n }\n this.isDestroyed = false;\n this.callStatus = '';\n this.callType = is_video ? 'video' : 'audio';\n\n this.setUserInfo(cid, eventUserId);\n this.setCallStatus(CallStatus.RINGING);\n this.cid = cid || '';\n this.metadata = metadata || {};\n\n if (typeof this.onCallEvent === 'function') {\n this.onCallEvent({\n type: eventUserId !== this.userID ? 'incoming' : 'outgoing',\n callType: is_video ? 'video' : 'audio',\n cid: cid || '',\n callerInfo: this.callerInfo,\n receiverInfo: this.receiverInfo,\n metadata: this.metadata,\n });\n }\n\n await this.startLocalStream();\n if (this.callStatus === CallStatus.ENDED) return;\n\n if (eventUserId !== this.userID) {\n await this.initialize();\n }\n\n if (this.localStream && this.mediaSender && this.mediaReceiver) {\n this.mediaSender?.initEncoders(this.localStream);\n this.mediaReceiver?.initDecoders(this.callType);\n }\n\n if (eventUserId === this.userID) {\n // Set missCall timeout if no connection after 60s\n if (this.missCallTimeout) clearTimeout(this.missCallTimeout);\n this.missCallTimeout = setTimeout(async () => {\n await this.missCall();\n }, 60000);\n }\n break;\n\n case CallAction.ACCEPT_CALL:\n if (eventUserId === this.userID && eventSessionId !== this.sessionID) {\n this.isDestroyed = true;\n this.destroy();\n return;\n }\n\n if (eventUserId !== this.userID && !this.isDestroyed) {\n if (this.mediaReceiver && this.mediaSender) {\n await this.mediaReceiver.acceptConnection();\n await this.mediaSender.sendConnected();\n await this.mediaSender.sendConfigs();\n }\n }\n break;\n\n case CallAction.END_CALL:\n case CallAction.REJECT_CALL:\n case CallAction.MISS_CALL:\n // this.setCallStatus(CallStatus.ENDED);\n this.destroy();\n break;\n }\n };\n\n this.connectionChangedHandler = (event: Event<ErmisChatGenerics>) => {\n const online = event.online;\n this.isOffline = !online;\n if (!online) {\n this.setConnectionMessage('Your network connection is unstable');\n\n // Clear health_call intervals when offline\n if (this.healthCallInterval) {\n clearInterval(this.healthCallInterval);\n this.healthCallInterval = null;\n }\n if (this.healthCallServerInterval) {\n clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = null;\n }\n } else {\n this.setConnectionMessage(null);\n\n // When back online, if CONNECTED, set up health_call intervals again\n if (this.callStatus === CallStatus.CONNECTED) {\n if (!this.healthCallServerInterval) {\n this.healthCallServerInterval = setInterval(() => {\n this.healthCall();\n }, 10000);\n }\n }\n }\n };\n\n this.messageUpdatedHandler = (event: Event<ErmisChatGenerics>) => {\n if (this.callStatus === CallStatus.CONNECTED && event.cid === this.cid) {\n const upgradeUserId = event.user?.id;\n\n let upgraderInfo: UserCallInfo | undefined;\n\n if (upgradeUserId === this.callerInfo?.id) {\n upgraderInfo = this.callerInfo;\n } else if (upgradeUserId === this.receiverInfo?.id) {\n upgraderInfo = this.receiverInfo;\n }\n\n if (upgraderInfo && typeof this.onUpgradeCall === 'function') {\n this.onUpgradeCall(upgraderInfo);\n }\n }\n };\n\n this._client.on('signal', this.signalHandler);\n this._client.on('connection.changed', this.connectionChangedHandler);\n this._client.on('message.updated', this.messageUpdatedHandler);\n }\n\n private cleanupCall() {\n if (this.mediaSender) {\n this.mediaSender?.stop();\n this.mediaSender = null;\n }\n if (this.mediaReceiver) {\n this.mediaReceiver.stop();\n this.mediaReceiver = null;\n }\n\n if (this.callNode) {\n this.callNode?.closeEndpoint();\n\n if (this.callStatus === CallStatus.CONNECTED) {\n this.callNode?.closeConnection();\n }\n\n this.callNode = null;\n }\n\n // Clear all timeouts and intervals\n if (this.missCallTimeout) {\n clearTimeout(this.missCallTimeout);\n this.missCallTimeout = null;\n }\n\n if (this.healthCallInterval) {\n clearInterval(this.healthCallInterval);\n this.healthCallInterval = null;\n }\n\n if (this.healthCallServerInterval) {\n clearInterval(this.healthCallServerInterval);\n this.healthCallServerInterval = null;\n }\n\n if (this.healthCallTimeout) {\n clearTimeout(this.healthCallTimeout);\n this.healthCallTimeout = null;\n }\n\n if (this.healthCallWarningTimeout) {\n clearTimeout(this.healthCallWarningTimeout);\n this.healthCallWarningTimeout = null;\n }\n\n // this.setCallStatus(CallStatus.ENDED);\n this.setConnectionMessage(null);\n this.cid = '';\n this.callType = '';\n this.metadata = {};\n\n if (this.localStream) {\n this.localStream.getTracks().forEach((track) => track.stop());\n this.localStream = null;\n }\n\n if (this.remoteStream) {\n this.remoteStream.getTracks().forEach((track) => track.stop());\n this.remoteStream = null;\n }\n\n this.setCallStatus(CallStatus.ENDED);\n }\n\n private destroy() {\n // if (this.signalHandler) this._client.off('signal', this.signalHandler);\n // if (this.connectionChangedHandler) this._client.off('connection.changed', this.connectionChangedHandler);\n // if (this.messageUpdatedHandler) this._client.off('message.updated', this.messageUpdatedHandler);\n this.cleanupCall();\n }\n\n public async getDevices(): Promise<{ audioDevices: MediaDeviceInfo[]; videoDevices: MediaDeviceInfo[] }> {\n // Return cached devices if available, otherwise fetch new ones\n if (this.availableAudioDevices.length > 0 || this.availableVideoDevices.length > 0) {\n return {\n audioDevices: this.availableAudioDevices,\n videoDevices: this.availableVideoDevices,\n };\n }\n return await this.getAvailableDevices();\n }\n\n // Get current selected devices info\n public getSelectedDevices(): { audioDevice?: MediaDeviceInfo; videoDevice?: MediaDeviceInfo } {\n const audioDevice = this.selectedAudioDeviceId\n ? this.availableAudioDevices.find((device) => device.deviceId === this.selectedAudioDeviceId)\n : undefined;\n\n const videoDevice = this.selectedVideoDeviceId\n ? this.availableVideoDevices.find((device) => device.deviceId === this.selectedVideoDeviceId)\n : undefined;\n\n return { audioDevice, videoDevice };\n }\n\n // Get default devices (first available device)\n public getDefaultDevices(): { audioDevice?: MediaDeviceInfo; videoDevice?: MediaDeviceInfo } {\n return {\n audioDevice: this.availableAudioDevices[0],\n videoDevice: this.availableVideoDevices[0],\n };\n }\n\n public async createCall(callType: string, cid: string) {\n try {\n this.cid = cid;\n\n const address = await this.getLocalEndpointAddr();\n\n await this._sendSignal({\n action: CallAction.CREATE_CALL,\n cid,\n is_video: callType === 'video',\n metadata: { address },\n });\n } catch (error) {\n console.error('Failed to create call:', error);\n throw error;\n }\n }\n\n public async acceptCall() {\n try {\n await this._sendSignal({ action: CallAction.ACCEPT_CALL });\n\n if (this.mediaSender) {\n const address = this.metadata?.address || '';\n await this.mediaSender.connect(address);\n }\n } catch (error) {\n console.error('Failed to accept call:', error);\n throw error;\n }\n }\n\n public async endCall() {\n await this._sendSignal({ action: CallAction.END_CALL });\n this.destroy();\n }\n\n public async rejectCall() {\n await this._sendSignal({ action: CallAction.REJECT_CALL });\n this.destroy();\n }\n\n private async missCall() {\n await this._sendSignal({ action: CallAction.MISS_CALL });\n this.destroy();\n }\n\n private async connectCall() {\n return await this._sendSignal({ action: CallAction.CONNECT_CALL });\n }\n\n private async healthCall() {\n return await this._sendSignal({ action: CallAction.HEALTH_CALL });\n }\n\n private async addVideoTrackToLocalStream() {\n const mediaConstraints = await this.getMediaConstraints();\n const stream = await navigator.mediaDevices.getUserMedia(mediaConstraints);\n const newVideoTrack = stream.getVideoTracks()[0];\n if (this.localStream) {\n this.localStream.addTrack(newVideoTrack);\n\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n } else {\n this.localStream = stream;\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n }\n }\n\n public async upgradeCall() {\n try {\n this.callType = 'video';\n await this.addVideoTrackToLocalStream();\n await this._sendSignal({ action: CallAction.UPGRADE_CALL });\n\n if (this.localStream) {\n this.mediaSender?.initVideoEncoder(this.localStream?.getVideoTracks()[0]);\n const audioEnable = !!this.localStream?.getAudioTracks().some((track) => track.enabled);\n const videoEnable = !!this.localStream?.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n } catch (error) {\n console.error('Failed to upgrade call:', error);\n throw error;\n }\n }\n\n public async requestUpgradeCall(enabled: boolean) {\n if (enabled) {\n this.callType = 'video';\n await this.addVideoTrackToLocalStream();\n\n if (this.localStream) {\n this.mediaSender?.initVideoEncoder(this.localStream?.getVideoTracks()[0]);\n const audioEnable = !!this.localStream?.getAudioTracks().some((track) => track.enabled);\n const videoEnable = !!this.localStream?.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n }\n\n public async startScreenShare() {\n // @ts-ignore\n if (!navigator.mediaDevices.getDisplayMedia) {\n throw new Error('Screen sharing is not supported in this browser.');\n }\n\n // @ts-ignore\n const screenStream = await navigator.mediaDevices.getDisplayMedia({ video: true });\n const screenTrack = screenStream.getVideoTracks()[0];\n\n // Replace video track in localStream\n if (this.localStream) {\n // Stop old track\n this.localStream.getVideoTracks().forEach((track) => track.stop());\n // Add new track to localStream\n this.localStream.removeTrack(this.localStream.getVideoTracks()[0]);\n this.localStream.addTrack(screenTrack);\n } else {\n // If no localStream, create new one\n this.localStream = screenStream;\n }\n\n // When screen sharing stops, automatically switch back to camera\n screenTrack.onended = () => {\n this.stopScreenShare();\n };\n\n // Call callback if UI needs to update\n if (this.onLocalStream) {\n // @ts-ignore\n this.onLocalStream(this.localStream);\n\n this.mediaSender?.replaceVideoTrack(this.localStream.getVideoTracks()[0]);\n }\n\n // Call callback when screen sharing starts\n if (typeof this.onScreenShareChange === 'function') {\n this.onScreenShareChange(true);\n }\n }\n\n public async stopScreenShare() {\n const mediaConstraints = await this.getMediaConstraints();\n\n try {\n // Only request video; we already have an active audio track in localStream\n const cameraStream = await navigator.mediaDevices.getUserMedia({\n video: mediaConstraints.video,\n audio: false,\n });\n const cameraTrack = cameraStream.getVideoTracks()[0];\n\n // Replace video track in localStream\n if (this.localStream) {\n // Stop old screen tracks\n this.localStream.getVideoTracks().forEach((track) => {\n track.stop();\n this.localStream?.removeTrack(track);\n });\n \n // Add new camera track\n this.localStream.addTrack(cameraTrack);\n } else {\n this.localStream = cameraStream;\n }\n\n // Call callback if UI needs to update\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n this.mediaSender?.replaceVideoTrack(this.localStream.getVideoTracks()[0]);\n }\n\n // Call callback when screen sharing stops\n if (typeof this.onScreenShareChange === 'function') {\n this.onScreenShareChange(false);\n }\n } catch (error) {\n console.error('Error stopping screen share and reverting to camera:', error);\n }\n }\n\n public async toggleMic(enabled: boolean) {\n if (this.localStream) {\n this.localStream.getAudioTracks().forEach((track) => {\n track.enabled = enabled;\n });\n\n const audioEnable = enabled;\n const videoEnable = this.localStream.getVideoTracks().some((track) => track.enabled);\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n\n public async toggleCamera(enabled: boolean) {\n if (this.localStream) {\n this.localStream.getVideoTracks().forEach((track) => {\n track.enabled = enabled;\n });\n\n const audioEnable = this.localStream.getAudioTracks().some((track) => track.enabled);\n const videoEnable = enabled;\n await this.mediaSender?.sendTransceiverState(audioEnable, videoEnable);\n }\n }\n\n // Public method to switch audio device\n public async switchAudioDevice(deviceId: string): Promise<boolean> {\n try {\n // Validate device exists in available devices\n const targetDevice = this.availableAudioDevices.find((device) => device.deviceId === deviceId);\n if (!targetDevice) {\n console.error('Audio device not found:', deviceId);\n if (this.onError) {\n this.onError('Selected microphone not found');\n }\n return false;\n }\n\n this.selectedAudioDeviceId = deviceId;\n\n if (!this.localStream) return false;\n\n // Get new audio stream with selected device\n const newStream = await navigator.mediaDevices.getUserMedia({\n audio: { deviceId: { exact: deviceId } },\n video: false,\n });\n\n const newAudioTrack = newStream.getAudioTracks()[0];\n const oldAudioTrack = this.localStream.getAudioTracks()[0];\n\n // Replace audio track in peer connection\n // if (this.peer && oldAudioTrack) {\n // const sender = this.peer.getSenders().find((s) => s.track === oldAudioTrack);\n // if (sender) {\n // await sender.replaceTrack(newAudioTrack);\n // }\n // }\n\n // Replace audio track in local stream\n if (oldAudioTrack) {\n this.localStream.removeTrack(oldAudioTrack);\n oldAudioTrack.stop();\n }\n this.localStream.addTrack(newAudioTrack);\n\n // Update UI\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n\n return true;\n } catch (error) {\n console.error('Error switching audio device:', error);\n if (this.onError) {\n this.onError('Failed to switch microphone');\n }\n return false;\n }\n }\n\n // Public method to switch video device\n public async switchVideoDevice(deviceId: string): Promise<boolean> {\n try {\n // Validate device exists in available devices\n const targetDevice = this.availableVideoDevices.find((device) => device.deviceId === deviceId);\n if (!targetDevice) {\n console.error('Video device not found:', deviceId);\n if (this.onError) {\n this.onError('Selected camera not found');\n }\n return false;\n }\n\n this.selectedVideoDeviceId = deviceId;\n\n if (!this.localStream) return false;\n\n // Get new video stream with selected device\n const newStream = await navigator.mediaDevices.getUserMedia({\n audio: false,\n video: { deviceId: { exact: deviceId } },\n });\n\n const newVideoTrack = newStream.getVideoTracks()[0];\n const oldVideoTrack = this.localStream.getVideoTracks()[0];\n\n // Replace video track in local stream\n if (oldVideoTrack) {\n this.localStream.removeTrack(oldVideoTrack);\n oldVideoTrack.stop();\n }\n this.localStream.addTrack(newVideoTrack);\n\n // Update UI\n if (this.onLocalStream) {\n this.onLocalStream(this.localStream);\n }\n\n return true;\n } catch (error) {\n console.error('Error switching video device:', error);\n if (this.onError) {\n this.onError('Failed to switch camera');\n }\n return false;\n }\n }\n\n // Listen for device changes\n private setupDeviceChangeListener() {\n navigator.mediaDevices.addEventListener('devicechange', async () => {\n const { audioDevices, videoDevices } = await this.getAvailableDevices();\n if (this.onDeviceChange) {\n this.onDeviceChange(audioDevices, videoDevices);\n }\n });\n }\n}\n","import axios, { AxiosError, AxiosInstance, AxiosRequestConfig, AxiosResponse } from 'axios';\nimport { APIErrorResponse, ErmisChatOptions, ErrorFromResponse, Logger } from './types';\nimport { chatCodes, isFunction, randomId, retryInterval, sleep } from './utils';\nimport https from 'https';\nimport { isErrorResponse } from './errors';\n\nexport class ErmisAuthProvider {\n apiKey: string;\n baseURL?: string;\n options?: ErmisChatOptions;\n axiosInstance: AxiosInstance;\n disconnected: boolean;\n browser: boolean;\n node: boolean;\n logger: Logger;\n consecutiveFailures: number;\n userAgent?: string;\n /** Last identifier (phone or email) used for OTP */\n lastIdentifier?: string;\n /**\n * The last OTP method used ('Sms', 'Voice', or 'Email').\n * Used to verify OTP for the correct method.\n */\n lastMethod?: 'Sms' | 'Voice' | 'Email';\n /** Wallet address used for wallet authentication */\n address?: string;\n\n constructor(apiKey: string, baseURL: string, options?: ErmisChatOptions) {\n const inputOptions = options || {};\n this.apiKey = apiKey;\n this.baseURL = options?.userBaseURL || baseURL + '/uss/v1';\n\n this.browser = typeof inputOptions.browser !== 'undefined' ? inputOptions.browser : typeof window !== 'undefined';\n this.node = !this.browser;\n this.options = {\n // timeout: 3000,\n withCredentials: false, // making sure cookies are not sent\n warmUp: false,\n recoverStateOnReconnect: true,\n ...inputOptions,\n };\n if (this.node && !this.options.httpsAgent) {\n this.options.httpsAgent = new https.Agent({\n keepAlive: true,\n keepAliveMsecs: 3000,\n });\n }\n this.axiosInstance = axios.create(this.options);\n this.logger = isFunction(inputOptions.logger) ? inputOptions.logger : () => null;\n this.consecutiveFailures = 0;\n this.disconnected = false;\n }\n\n _logApiRequest(\n type: string,\n url: string,\n data: unknown,\n config: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n },\n ) {\n this.logger(\n 'info',\n `client: ${type} - Request - ${url}- ${JSON.stringify(data)} - ${JSON.stringify(config.params)}`,\n {\n tags: ['api', 'api_request', 'client'],\n url,\n payload: data,\n config,\n },\n );\n }\n\n _logApiResponse<T>(type: string, url: string, response: AxiosResponse<T>) {\n this.logger('info', `client:${type} - Response - url: ${url} > status ${response.status}`, {\n tags: ['api', 'api_response', 'client'],\n url,\n response,\n });\n }\n\n _logApiError(type: string, url: string, error: unknown, options: unknown) {\n this.logger(\n 'error',\n `client:${type} - Error: ${JSON.stringify(error)} - url: ${url} - options: ${JSON.stringify(options)}`,\n {\n tags: ['api', 'api_response', 'client'],\n url,\n error,\n },\n );\n }\n\n doAxiosRequest = async <T>(\n type: string,\n url: string,\n data?: unknown,\n options: AxiosRequestConfig & {\n config?: AxiosRequestConfig & { maxBodyLength?: number };\n } = {},\n ): Promise<T> => {\n const requestConfig = this._enrichAxiosOptions(options);\n\n try {\n let response: AxiosResponse<T>;\n this._logApiRequest(type, url, data, requestConfig);\n switch (type) {\n case 'get':\n response = await this.axiosInstance.get(url, requestConfig);\n break;\n case 'delete':\n response = await this.axiosInstance.delete(url, requestConfig);\n break;\n case 'post':\n response = await this.axiosInstance.post(url, data, requestConfig);\n break;\n case 'postForm':\n response = await this.axiosInstance.postForm(url, data, requestConfig);\n break;\n case 'put':\n response = await this.axiosInstance.put(url, data, requestConfig);\n break;\n case 'patch':\n response = await this.axiosInstance.patch(url, data, requestConfig);\n break;\n case 'options':\n response = await this.axiosInstance.options(url, requestConfig);\n break;\n default:\n throw new Error('Invalid request type');\n }\n this._logApiResponse<T>(type, url, response);\n this.consecutiveFailures = 0;\n return this.handleResponse(response);\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n } catch (e: any /**TODO: generalize error types */) {\n e.client_request_id = requestConfig.headers?.['x-client-request-id'];\n this._logApiError(type, url, e, options);\n this.consecutiveFailures += 1;\n if (e.response) {\n /** connection_fallback depends on this token expiration logic */\n if (e.response.data.code === chatCodes.TOKEN_EXPIRED) {\n if (this.consecutiveFailures > 1) {\n await sleep(retryInterval(this.consecutiveFailures));\n }\n return await this.doAxiosRequest<T>(type, url, data, requestConfig);\n }\n return this.handleResponse(e.response);\n } else {\n throw e as AxiosError<APIErrorResponse>;\n }\n }\n };\n\n get<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('get', url, null, { params });\n }\n\n put<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('put', url, data);\n }\n\n post<T>(url: string, data?: unknown, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('post', url, data, { params });\n }\n\n patch<T>(url: string, data?: unknown) {\n return this.doAxiosRequest<T>('patch', url, data);\n }\n\n delete<T>(url: string, params?: AxiosRequestConfig['params']) {\n return this.doAxiosRequest<T>('delete', url, null, { params });\n }\n errorFromResponse(response: AxiosResponse<APIErrorResponse>): ErrorFromResponse<APIErrorResponse> {\n let err: ErrorFromResponse<APIErrorResponse>;\n err = new ErrorFromResponse(`ErmisChat error HTTP code: ${response.status}`);\n if (response.data && response.data.code) {\n err = new Error(`ErmisChat error code ${response.data.code}: ${response.data.message}`);\n err.code = response.data.code;\n }\n err.response = response;\n err.status = response.status;\n return err;\n }\n\n handleResponse<T>(response: AxiosResponse<T>) {\n const data = response.data;\n if (isErrorResponse(response)) {\n throw this.errorFromResponse(response);\n }\n return data;\n }\n\n getUserAgent() {\n return (\n this.userAgent || `ermis-chat-sdk-javascript-client-${this.node ? 'node' : 'browser'}-${process.env.PKG_VERSION}`\n );\n }\n setUserAgent(userAgent: string) {\n this.userAgent = userAgent;\n }\n _enrichAxiosOptions(\n options: AxiosRequestConfig & { config?: AxiosRequestConfig } = {\n params: {},\n headers: {},\n config: {},\n },\n ): AxiosRequestConfig {\n let signal: AbortSignal | null = null;\n\n if (!options.headers?.['x-client-request-id']) {\n options.headers = {\n ...options.headers,\n 'x-client-request-id': randomId(),\n };\n }\n const {\n params: axiosRequestConfigParams,\n headers: axiosRequestConfigHeaders,\n ...axiosRequestConfigRest\n } = this.options?.axiosRequestConfig || {};\n\n let user_service_params = {\n // api_key: this.key,\n ...options.params,\n ...(axiosRequestConfigParams || {}),\n };\n\n return {\n params: user_service_params,\n headers: {\n 'X-Stream-Client': this.getUserAgent(),\n ...options.headers,\n ...(axiosRequestConfigHeaders || {}),\n },\n ...(signal ? { signal } : {}),\n ...options.config,\n ...(axiosRequestConfigRest || {}),\n };\n }\n\n /**\n * Send OTP to a phone number.\n * @param identifier Phone number\n * @param language Language code (e.g. 'En', 'Vi')\n * @param method Method type (e.g. 'Sms', 'Voice')\n */\n async sendOtpToPhone(identifier: string, method: 'Sms' | 'Voice'): Promise<{ success: boolean; message?: string }> {\n this.lastIdentifier = identifier;\n this.lastMethod = method;\n const data = {\n apikey: this.apiKey,\n identifier,\n language: 'Vi',\n method,\n otp_type: 'Login',\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/get_otp_new', data);\n }\n\n /**\n * Send OTP to a email.\n * @param identifier Email address\n * @param language Language code (e.g. 'En', 'Vi')\n * @param method Method type (e.g. 'Email')\n */\n async sendOtpToEmail(identifier: string): Promise<{ success: boolean; message?: string }> {\n this.lastIdentifier = identifier;\n this.lastMethod = 'Email';\n const data = {\n apikey: this.apiKey,\n identifier,\n language: 'Vi',\n method: 'Email',\n otp_type: 'Login',\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/get_otp_new', data);\n }\n\n /**\n * Verify OTP for phone or email.\n * @param otp OTP code\n */\n async verifyOtp(otp: string): Promise<{ success: boolean; message?: string }> {\n const data = {\n identifier: this.lastIdentifier,\n method: this.lastMethod,\n apikey: this.apiKey,\n otp,\n };\n\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/otp_login', data);\n }\n\n /**\n * Login with Google.\n * @param token Google OAuth token\n * @param apikey API key\n */\n async loginWithGoogle(token: string): Promise<{ success: boolean; message?: string }> {\n const data = {\n token,\n apikey: this.apiKey,\n };\n return this.post<{ success: boolean; message?: string }>(this.baseURL + '/auth/google_login', data);\n }\n\n /**\n * Get challenge for wallet login.\n * @param address Wallet address\n * @param apiKey API key\n */\n async getWalletChallenge(address: string): Promise<any> {\n this.address = address;\n const response = await this.post<{ challenge: string }>(this.baseURL + '/auth/get_challenge', {\n address,\n apikey: this.apiKey,\n });\n const challenge = JSON.parse(response.challenge);\n return challenge;\n }\n\n private createNonce(length: number): string {\n let result = '';\n const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';\n const charactersLength = characters.length;\n for (let i = 0; i < length; i++) {\n result += characters.charAt(Math.floor(Math.random() * charactersLength));\n }\n return result;\n }\n\n /**\n * Verify wallet signature after receiving the challenge.\n * @param address Wallet address\n * @param signature Signature generated by the wallet\n * @param nonce Nonce used in the challenge\n * @returns Verification result and token if successful\n */\n async verifyWalletSignature(signature: string): Promise<{ success: boolean; token?: string; message?: string }> {\n const data = {\n address: this.address,\n signature,\n nonce: this.createNonce(20),\n apikey: this.apiKey,\n };\n return this.post<{ success: boolean; token?: string; message?: string }>(\n this.baseURL + '/auth/verify_signature',\n data,\n );\n }\n}\n","/**\n * Duration lookup: milliseconds → human-readable text.\n */\nconst DURATION_MAP: Record<string, string> = {\n '10000': '10 seconds',\n '30000': '30 seconds',\n '60000': '1 minute',\n '300000': '5 minutes',\n '900000': '15 minutes',\n '3600000': '60 minutes',\n};\n\n/**\n * Resolve a user ID to a display name using the provided map.\n * Falls back to the raw userId if no entry is found.\n */\nfunction resolveUser(userId: string, userMap: Record<string, string>): string {\n return userMap[userId] ?? userId;\n}\n\n/**\n * Parse a raw system message string into a human-readable English sentence.\n *\n * The raw format is: `\"<formatId> <userID> [<param1> <param2> ...]\"`\n *\n * @param value - Raw system message string from the server\n * @param userMap - Mapping of user IDs → display names\n * @returns Parsed English text, or the original string if the format is unknown\n */\nexport function parseSystemMessage(\n value: string,\n userMap: Record<string, string>,\n): string {\n if (!value || typeof value !== 'string') return value ?? '';\n\n const trimmed = value.trim();\n if (!trimmed) return '';\n\n const parts = trimmed.split(' ');\n const formatId = parts[0];\n const userId = parts[1] ?? '';\n const userName = userId ? resolveUser(userId, userMap) : 'User';\n\n switch (formatId) {\n // 1: userName changed the channel name to channelName (may contain spaces)\n case '1': {\n const channelName = parts.slice(2).join(' ');\n return `${userName} changed the channel name to ${channelName}.`;\n }\n\n // 2–13, 16–17: single-user actions\n case '2':\n return `${userName} changed the channel avatar.`;\n case '3':\n return `${userName} changed the channel description.`;\n case '4':\n return `${userName} was removed from the channel.`;\n case '5':\n return `${userName} was banned.`;\n case '6':\n return `${userName} was unbanned.`;\n case '7':\n return `${userName} was promoted to moderator.`;\n case '8':\n return `${userName} was demoted from moderator.`;\n case '9':\n return `${userName}'s permissions were updated.`;\n case '10':\n return `${userName} joined the channel.`;\n case '11':\n return `${userName} declined the channel invitation.`;\n case '12':\n return `${userName} left the channel.`;\n case '13':\n return `${userName} cleared the chat history.`;\n\n // 14: channel type change (true = public, false = private)\n case '14': {\n const rawType = parts[2] ?? '';\n const channelType = rawType === 'true' ? 'public' : 'private';\n return `${userName} changed the channel to ${channelType}.`;\n }\n\n // 15: cooldown toggle / duration\n case '15': {\n const duration = parts[2] ?? '0';\n if (duration === '0') {\n return `${userName} disabled cooldown.`;\n }\n const durationText = DURATION_MAP[duration] ?? `${duration}ms`;\n return `${userName} enabled cooldown for ${durationText}.`;\n }\n\n case '16':\n return `${userName} updated the banned words.`;\n case '17':\n return `${userName} was added to the channel.`;\n\n // 18: admin transfer (two user IDs)\n case '18': {\n const oldUserId = parts[1] ?? '';\n const newUserId = parts[2] ?? '';\n const oldUserName = oldUserId ? resolveUser(oldUserId, userMap) : 'User';\n const newUserName = newUserId ? resolveUser(newUserId, userMap) : 'User';\n return `Admin ${oldUserName} left and assigned ${newUserName} as the new admin.`;\n }\n\n // 19–20: pin / unpin (userId + msgID)\n case '19':\n return `${userName} pinned a message.`;\n case '20':\n return `${userName} unpinned a message.`;\n\n default:\n return trimmed;\n }\n}\n","/**\n * Call type constants for signal messages.\n */\nexport const CallType = {\n AUDIO: 'audio',\n VIDEO: 'video',\n} as const;\n\nexport type CallTypeValue = (typeof CallType)[keyof typeof CallType];\n\n/**\n * Result of parsing a signal message.\n */\nexport interface SignalMessageResult {\n text: string;\n duration: string;\n callType: CallTypeValue | '';\n color: string;\n}\n\n/**\n * Format duration from milliseconds to \"X min, Y sec\" format.\n */\nfunction formatDuration(durationMs: string): string {\n if (!durationMs) return '';\n const ms = parseInt(durationMs, 10);\n if (isNaN(ms) || ms <= 0) return '';\n const totalSeconds = Math.floor(ms / 1000);\n const minutes = Math.floor(totalSeconds / 60);\n const seconds = totalSeconds % 60;\n return `${minutes} min, ${seconds} sec`;\n}\n\n/**\n * Parse a raw signal message string into a structured object\n * containing text, duration, call type, and color.\n *\n * Signal messages represent call events. The raw format is:\n * `\"<formatId> <callerId> [<enderId> <duration>]\"`\n *\n * @param value - Raw signal message string from the server\n * @param myUserId - The current user's ID (from client.userID)\n * @returns Parsed signal message object, or null if input is empty\n */\nexport function parseSignalMessage(\n value: string,\n myUserId: string,\n): SignalMessageResult | null {\n if (!value || typeof value !== 'string') return null;\n\n const trimmed = value.trim();\n if (!trimmed) return null;\n\n const parts = trimmed.split(' ');\n const number = parseInt(parts[0], 10);\n const callerId = parts[1] ?? '';\n const isMe = myUserId === callerId;\n\n let enderId = '';\n let duration = '';\n let callType: CallTypeValue | '' = '';\n let color = '';\n\n if (number === 3 || number === 6) {\n enderId = parts[2] ?? '';\n duration = parts[3] === '0' ? '' : (parts[3] ?? '');\n }\n\n let text: string;\n switch (number) {\n case 1: // AudioCallStarted\n text = isMe ? 'Calling...' : 'Incoming audio call...';\n callType = CallType.AUDIO;\n color = '#54D62C';\n break;\n case 2: // AudioCallMissed\n text = isMe ? 'Outgoing audio call' : 'You missed audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 3: // AudioCallEnded\n if (duration) {\n text = isMe ? 'Outgoing audio call' : 'Incoming audio call';\n color = '#54D62C';\n } else {\n if (enderId === myUserId) {\n text = 'You cancel audio call';\n } else {\n text = 'You missed audio call';\n }\n color = '#FF4842';\n }\n callType = CallType.AUDIO;\n break;\n case 4: // VideoCallStarted\n text = isMe ? 'Calling...' : 'Incoming video call...';\n callType = CallType.VIDEO;\n color = '#54D62C';\n break;\n case 5: // VideoCallMissed\n text = isMe ? 'Outgoing video call' : 'You missed video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n case 6: // VideoCallEnded\n if (duration) {\n text = isMe ? 'Outgoing video call' : 'Incoming video call';\n color = '#54D62C';\n } else {\n if (enderId === myUserId) {\n text = 'You cancel video call';\n } else {\n text = 'You missed video call';\n }\n color = '#FF4842';\n }\n callType = CallType.VIDEO;\n break;\n case 7: // AudioCallRejected\n text = isMe ? 'Recipient rejected audio call' : 'You rejected audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 8: // VideoCallRejected\n text = isMe ? 'Recipient rejected video call' : 'You rejected video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n case 9: // AudioCallBusy\n text = isMe ? 'Recipient was busy' : 'You missed audio call';\n callType = CallType.AUDIO;\n color = '#FF4842';\n break;\n case 10: // VideoCallBusy\n text = isMe ? 'Recipient was busy' : 'You missed video call';\n callType = CallType.VIDEO;\n color = '#FF4842';\n break;\n default:\n text = trimmed;\n callType = '';\n color = '';\n }\n\n return { text, duration: formatDuration(duration), callType, color };\n}\n"],"mappings":"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","names":["FormData","user","hardDelete","user","WebSocket","WebSocket","CallAction","CallStatus","FRAME_TYPE","channel","ptr","module","arg0","arg1","module","result","axios","axios"]}
|