import { DiscontinuityListener, Message, MessageListener, Messages, MessageSubscriptionResponse, OnDiscontinuitySubscriptionResponse, PaginatedResult, QueryOptions, SendMessageParams, } from '@ably/chat'; import { RealtimeChannel } from 'ably'; import { nanoid } from 'nanoid'; import { jsonRpc, jsonRpcBlocking, registerCallback } from './jsonrpc'; import { RpcRealtimeChannel } from './pubsub'; import { RpcMessage } from './RpcMessage'; import { RpcOnDiscontinuitySubscriptionResponse } from './RpcOnDiscontinuitySubscriptionResponse'; import { RpcPaginatedResult } from './RpcPaginatedResult'; export class RpcMessages implements Messages { private readonly _instanceId: string; constructor(instanceId: string) { this._instanceId = instanceId; } subscribe(listener: MessageListener): MessageSubscriptionResponse { const callbackId = nanoid(); registerCallback(callbackId, listener); const { refId } = jsonRpcBlocking.request('Messages.subscribe', { refId: this._instanceId, callbackId, }); return new RpcMessageSubscriptionResponse(refId); } unsubscribeAll(): void { jsonRpcBlocking.request('Messages.unsubscribeAll', { refId: this._instanceId }); } async get(options: QueryOptions): Promise> { const { refId } = await jsonRpc.request('Messages.get', { refId: this._instanceId, args: { options }, }); return new RpcPaginatedResult(refId); } async send(params: SendMessageParams): Promise { const { refId } = await jsonRpc.request('Messages.send', { refId: this._instanceId, args: { params }, }); return new RpcMessage(refId); } get channel(): Promise { return jsonRpc .request('Messages#channel', { refId: this._instanceId, }) .then(({ refId }) => new RpcRealtimeChannel(refId)); } onDiscontinuity(listener: DiscontinuityListener): OnDiscontinuitySubscriptionResponse { const callbackId = nanoid(); registerCallback(callbackId, listener); const { refId } = jsonRpcBlocking.request('Messages.onDiscontinuity', { refId: this._instanceId, callbackId, }); return new RpcOnDiscontinuitySubscriptionResponse(refId); } } export class RpcMessageSubscriptionResponse implements MessageSubscriptionResponse { private readonly _instanceId: string; constructor(instanceId: string) { this._instanceId = instanceId; // it is common to destructure this object when received from the subscription function, // so we need to bind its functions to preserve reference to this this.unsubscribe = this.unsubscribe.bind(this); this.getPreviousMessages = this.getPreviousMessages.bind(this); } unsubscribe(): void { jsonRpcBlocking.request('MessageSubscriptionResponse.unsubscribe', { refId: this._instanceId }); } async getPreviousMessages(params: Omit): Promise> { const { refId } = await jsonRpc.request('MessageSubscriptionResponse.getPreviousMessages', { refId: this._instanceId, args: { params }, }); return new RpcPaginatedResult(refId); } }