import { DiscontinuityListener, OnDiscontinuitySubscriptionResponse, Typing, TypingListener, TypingSubscriptionResponse, } from '@ably/chat'; import { RealtimeChannel } from 'ably'; import { nanoid } from 'nanoid'; import { jsonRpc, jsonRpcBlocking, registerCallback } from './jsonrpc'; import { RpcRealtimeChannel } from './pubsub'; import { RpcOnDiscontinuitySubscriptionResponse } from './RpcOnDiscontinuitySubscriptionResponse'; export class RpcTyping implements Typing { private readonly _instanceId: string; constructor(instanceId: string) { this._instanceId = instanceId; } subscribe(listener: TypingListener): TypingSubscriptionResponse { const callbackId = nanoid(); registerCallback(callbackId, listener); const { refId } = jsonRpcBlocking.request('Typing.subscribe', { refId: this._instanceId, callbackId, }); return new RpcTypingSubscriptionResponse(refId); } unsubscribeAll(): void { jsonRpcBlocking.request('Typing.unsubscribeAll', { refId: this._instanceId }); } async get(): Promise> { const { response } = await jsonRpc.request('Typing.get', { refId: this._instanceId, }); return new Set(response); } async start(): Promise { await jsonRpc.request('Typing.start', { refId: this._instanceId, }); } async stop(): Promise { await jsonRpc.request('Typing.stop', { refId: this._instanceId, }); } get channel(): Promise { return jsonRpc .request('Typing#channel', { refId: this._instanceId, }) .then(({ refId }) => new RpcRealtimeChannel(refId)); } onDiscontinuity(listener: DiscontinuityListener): OnDiscontinuitySubscriptionResponse { const callbackId = nanoid(); registerCallback(callbackId, listener); const { refId } = jsonRpcBlocking.request('Typing.onDiscontinuity', { refId: this._instanceId, callbackId, }); return new RpcOnDiscontinuitySubscriptionResponse(refId); } } export class RpcTypingSubscriptionResponse implements TypingSubscriptionResponse { 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); } unsubscribe(): void { jsonRpcBlocking.request('TypingSubscriptionResponse.unsubscribe', { refId: this._instanceId }); } }