UNPKG

@ably/chat

Version:

Ably Chat is a set of purpose-built APIs for a host of chat features enabling you to create 1:1, 1:Many, Many:1 and Many:Many chat rooms for any scale. It is designed to meet a wide range of chat use cases, such as livestreams, in-game communication, cust

185 lines (163 loc) 5.42 kB
import * as Ably from 'ably'; import { ChatClientOptions, normalizeClientOptions, NormalizedChatClientOptions } from './config.js'; import { Connection, DefaultConnection } from './connection.js'; import { randomId } from './id.js'; import { Logger, makeLogger } from './logger.js'; import { RealtimeWithOptions } from './realtime-extensions.js'; import { DefaultRooms, Rooms } from './rooms.js'; import { VERSION } from './version.js'; /** * This is the core client for Ably chat. It provides access to chat rooms. */ export class ChatClient { /** * @internal */ private readonly _realtime: Ably.Realtime; /** * @internal */ private readonly _rooms: DefaultRooms; /** * @internal */ private readonly _clientOptions: NormalizedChatClientOptions; /** * @internal */ private readonly _connection: Connection; /** * @internal */ private readonly _logger: Logger; /** * @internal */ private readonly _nonce: string; /** * Constructor for Chat * * **Important**: The Ably Realtime client must have a clientId set. This can be done by configuring * token-based authentication that returns a token with a clientId, or by setting * the clientId directly in the Realtime client options. * @example * ```typescript * import * as Ably from 'ably'; * import { ChatClient } from '@ably/chat'; * * // Preferred in production: Use auth URL that returns a token with clientId * const realtime = new Ably.Realtime({ * authUrl: '/api/ably-auth', // Your server endpoint that returns an Ably token with clientId * authMethod: 'POST' * }); * const chatClient = new ChatClient(realtime); * * // Alternative for development and server-side operations: Set clientId directly (requires API key) * const realtime = new Ably.Realtime({ * key: 'your-ably-api-key', * clientId: 'user-123' * }); * const chatClient = new ChatClient(realtime); * ``` * @param realtime - The Ably Realtime client. * @param clientOptions - The client options. */ constructor(realtime: Ably.Realtime, clientOptions?: ChatClientOptions) { this._realtime = realtime; this._clientOptions = normalizeClientOptions(clientOptions); this._nonce = randomId(); this._logger = makeLogger(this._clientOptions).withContext({ chatClientNonce: this._nonce, }); this._connection = new DefaultConnection(realtime, this._logger); this._rooms = new DefaultRooms(realtime, this._clientOptions, this._logger); this._addAgent('chat-js'); this._logger.trace(`ably chat client version ${VERSION}; initialized`); } /** * Returns the rooms object, which provides access to chat rooms. * @returns The rooms object. */ get rooms(): Rooms { return this._rooms; } /** * Returns the underlying connection to Ably, which can be used to monitor the client's * connection to Ably servers. * @returns The connection object. */ get connection(): Connection { return this._connection; } /** * Returns the clientId of the current client. * @returns The clientId. */ get clientId(): string { return this._realtime.auth.clientId; } /** * Returns the underlying Ably Realtime client. * @returns The Ably Realtime client. */ get realtime(): Ably.Realtime { return this._realtime; } /** * Returns the resolved client options for the client, including any defaults that have been set. * @returns The client options. */ get clientOptions(): ChatClientOptions { return this._clientOptions; } /** * Returns the logger instance for the client. * @internal * @returns The logger instance. */ get logger(): Logger { return this._logger; } /** * Adds additional agent information to the client. * Used internally to add React-specific agent information. * @internal */ public addReactAgent(): void { this._addAgent('chat-react'); this._rooms.useReact(); } /** * Adds additional agent information to the client. * This is used internally to add a specific agent with a version. * @param agent - The agent to add. * @param version - The version of the agent, defaults to the current client version. * @internal */ public addAgentWithVersion(agent: string, version: string): void { this._addAgent(agent, version); this._logger.trace(`Added agent ${agent} with version ${version}`); } /** * Disposes of the ChatClient instance, cleaning up any resources and rendering it unusable. * This method will release all rooms before disposing of the client. */ async dispose(): Promise<void> { this._logger.trace('ChatClient.dispose();'); // Release all rooms before disposing await this._rooms.dispose(); // Dispose of the connection instance this._connection.dispose(); this._logger.debug('ChatClient.dispose(); client disposed successfully'); } /** * Sets the agent string for the client. * @param agent - The agent to add. * @param version - The version of the agent, defaults to the current client version. * @internal */ private _addAgent(agent: string, version?: string): void { const realtime = this._realtime as RealtimeWithOptions; realtime.options.agents = { ...(realtime.options.agents ?? realtime.options.agents), [agent]: version ?? VERSION }; } }