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

65 lines (49 loc) 2.46 kB
import * as Ably from 'ably'; import { roomChannelName } from './channel.js'; import { Logger } from './logger.js'; import { DEFAULT_CHANNEL_OPTIONS, DEFAULT_CHANNEL_OPTIONS_REACT } from './version.js'; export type ChannelOptionsWithModes = Omit<Ably.ChannelOptions, 'modes'> & Required<Pick<Ably.ChannelOptions, 'modes'>>; export type ChannelOptionsMerger = (options: ChannelOptionsWithModes) => ChannelOptionsWithModes; export class ChannelManager { private readonly _realtime: Ably.Realtime; private readonly _logger: Logger; private _registeredOptions: ChannelOptionsWithModes; private readonly _isReact: boolean; private _resolvedChannel?: Ably.RealtimeChannel; private readonly _channelId: string; constructor(roomName: string, realtime: Ably.Realtime, logger: Logger, isReact: boolean) { logger.trace('ChannelManager();', { isReact }); this._realtime = realtime; this._logger = logger; this._isReact = isReact; this._registeredOptions = this._defaultChannelOptions(); this._channelId = roomChannelName(roomName); } mergeOptions(merger: ChannelOptionsMerger): void { this._logger.trace('ChannelManager.mergeOptions();'); if (this._resolvedChannel) { this._logger.error('channel options cannot be modified after the channel has been requested'); throw new Ably.ErrorInfo('channel options cannot be modified after the channel has been requested', 40000, 400); } this._registeredOptions = merger(this._registeredOptions); } get(): Ably.RealtimeChannel { this._logger.trace('ChannelManager.get();'); this._resolvedChannel ??= this._realtime.channels.get(this._channelId, this._registeredOptions); return this._resolvedChannel; } release(): void { this._logger.trace('ChannelManager.release();', { channelId: this._channelId }); if (!this._resolvedChannel) { return; } this._realtime.channels.release(this._channelId); } private _defaultChannelOptions(): ChannelOptionsWithModes { this._logger.trace('ChannelManager._defaultChannelOptions();'); const baseOptions = this._isReact ? DEFAULT_CHANNEL_OPTIONS_REACT : DEFAULT_CHANNEL_OPTIONS; this._logger.trace(this._isReact ? 'using react channel options' : 'using default channel options'); // Create a deep copy of the options, ensuring modes array is also copied return { ...baseOptions, modes: [...(baseOptions.modes ?? [])] } as ChannelOptionsWithModes; } }