{"version":3,"sources":["../src/core/chatChannel.ts"],"names":["invariant","ChatChannel","chatClient","gatewayClient","accountClient","roomId","senderId","lastKeys","NaluriChatError","eventsApi","EVENTS","data","error","GetRoomDocument","useFragment","UserFieldsFragmentDoc","user","userFragement_default","meta","limit","after","GetRoomChatsDocument","messagesList","ChatFieldsFragmentDoc","chat","message","messageFragement_default","currentRoomKeys","id","GetIndividualMessageDocument","replyTo","metadata","SendTextDocument","MessageTypes","err","file","SendMediaDocument","promises","messageId","promise","MarkReadDocument","cache","existingStatus","newStatus","currentRooms","chatCache","GetRoomsDocument","newRooms","room","onReceive","NewMessageDocument","newMessage","newMessageRef","existingChats","existingCount","newMessageData","errorValue","actingCoachId","list","CoachListStatus","el"],"mappings":";ubACA,OAAOA,MAAe,iBA0Df,IAAMC,EAAN,KAAkB,CACf,WAEA,cACA,cAED,OAEC,YAEA,aAED,SAEA,QAEC,WAEA,SAEA,aAAe,kBAEvB,YAAY,CACV,WAAAC,EACA,cAAAC,EACA,cAAAC,EACA,OAAAC,EACA,SAAAC,EACA,SAAAC,CACF,EAAuB,CACrBP,EAAUE,EAAY,yBAAyB,EAE/C,KAAK,WAAaA,EAClB,KAAK,cAAgBC,EACrB,KAAK,cAAgBC,EACrB,KAAK,OAASC,EACd,KAAK,YAAc,GACnB,KAAK,SAAWC,EAChB,KAAK,QAAU,GACf,KAAK,WAAa,CAAC,EACnB,KAAK,SAAWC,CAClB,CAOA,MAAa,YAA+B,CAC1C,GAAI,CAAC,KAAK,OACR,MAAM,IAAIC,EAAgB,CACxB,QAAS,uCACT,KAAM,OACR,CAAC,EAECC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,YAAa,CAClC,QAAS,KAAK,MAChB,CAAC,EAEH,GAAM,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAM,KAAK,WAAW,MAG5C,CACA,MAAOC,EACP,UAAW,CAAE,GAAI,KAAK,MAAO,CAC/B,CAAC,EAED,GAAIF,GAAM,KACR,MAAO,CACL,GAAIA,EAAK,KAAK,GACd,KAAMA,EAAK,KAAK,KAChB,KAAMA,EAAK,KAAK,KAChB,cAAeA,EAAK,KAAK,cAAgB,OACzC,OAAQA,EAAK,KAAK,QAAU,OAC5B,UAAWA,EAAK,KAAK,WACrB,UAAWA,EAAK,KAAK,WACrB,YAAaA,EAAK,KAAK,QAAU,EACjC,MAAOG,EAAYC,EAAuBJ,EAAK,KAAK,KAAK,EAAE,IAAKK,GAC9DC,EAAaD,CAAI,CACnB,EACA,SAAUL,EAAK,KAAK,UAAU,OAC1BA,EAAK,KAAK,UAAU,IAAKO,IAAU,CACjC,IAAKA,EAAK,IACV,MAAOA,EAAK,KACd,EAAE,EACF,MACN,EAGF,MAAIT,EAAU,QAAQ,GAAKG,GACzBH,EAAU,MAAMC,EAAO,kBAAmB,CACxC,QAAS,KAAK,OACd,MAAAE,CACF,CAAC,EAGG,IAAIJ,EAAgB,CACxB,QAAS,qCAAqCI,CAAK,GACnD,KAAM,OACR,CAAC,CACH,CAOA,MAAa,YACX,CAAE,MAAAO,EAAO,MAAAC,CAAM,EAAuB,CAAE,MAAO,EAAG,EACpB,CAC1BX,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,qBAAsB,CAC3C,QAAS,KAAK,MAChB,CAAC,EAEH,GAAI,CACF,GAAM,CAAE,KAAAC,EAAM,MAAAC,CAAM,EAAI,MAAM,KAAK,WAAW,MAG5C,CACA,MAAOS,EACP,UAAuC,CACrC,OAAQ,KAAK,OACb,GAAIF,EAAQ,CAAE,MAAAA,CAAM,EAAI,CAAE,MAAO,EAAG,EACpC,MAAAC,CACF,EACA,YAAa,cACf,CAAC,EAED,GAAIT,GAAM,MAAO,CACf,IAAMW,EAAeX,EAAK,MAAM,MAAM,OAClCG,EAAYS,EAAuBZ,EAAK,MAAM,KAAK,EAAE,IAAKa,GAAS,CACjE,IAAMC,EAAUC,EAAiBF,EAAM,KAAK,QAAQ,EACpD,OAAKC,EAAQ,YAAY,KAAK,WAAW,KAAKA,EAAQ,EAAE,EACjDA,CACT,CAAC,EACD,CAAC,EAEL,KAAK,QAAUd,EAAK,MAAM,UAAY,KAAK,aAE3C,IAAMgB,EAAkB,KAAK,SAAS,IAAI,KAAK,MAAM,EAErD,OAAKA,EAIH,KAAK,SAAS,IAAI,KAAK,OAAQ,CAC7B,GAAG,IAAI,IAAI,CAAChB,EAAK,MAAM,SAAU,GAAGgB,CAAe,CAAC,CACtD,CAAC,EALD,KAAK,SAAS,IAAI,KAAK,OAAQ,CAAChB,EAAK,MAAM,QAAQ,CAAC,EAQ/C,CACL,OAAQA,EAAK,MAAM,QACnB,MAAOA,EAAK,MAAM,MAClB,QAASA,EAAK,MAAM,UAAY,OAChC,MAAOW,CACT,CACF,CACA,MAAM,IAAId,EAAgB,CACxB,QAAS,sCAAsCI,CAAK,GACpD,KAAM,OACR,CAAC,CACH,OAASA,EAAO,CACd,MAAIH,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,2BAA4B,CAAE,MAAAE,CAAM,CAAC,EAExD,IAAIJ,EAAgB,CACxB,QAAS,sCAAsCI,CAAK,GACpD,KAAM,OACR,CAAC,CACH,CACF,CAQA,MAAa,qBAAqB,CAChC,GAAAgB,EACA,OAAAvB,CACF,EAAoD,CAClD,GAAI,CAACuB,EACH,MAAM,IAAIpB,EAAgB,CACxB,QAAS,mDACT,KAAM,OACR,CAAC,EAGCC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,YAAa,CAClC,QAAS,KAAK,OAEd,WAAYkB,CACd,CAAC,EAEH,GAAM,CAAE,KAAAjB,EAAM,MAAAC,CAAM,EAAI,MAAM,KAAK,WAAW,MAG5C,CACA,MAAOiB,EACP,UAA+C,CAC7C,OAAQxB,GAAU,KAAK,OACvB,GAAAuB,CACF,CACF,CAAC,EAED,GAAIjB,GAAM,KAMR,OALqBe,EACnBZ,EAAYS,EAAuBZ,EAAK,IAAI,EAC5C,KAAK,QACP,EAKF,MAAIF,EAAU,QAAQ,GAAKG,GACzBH,EAAU,MAAMC,EAAO,kBAAmB,CACxC,QAAS,KAAK,OAEd,WAAYkB,EACZ,MAAAhB,CACF,CAAC,EAGG,IAAIJ,EAAgB,CACxB,QAAS,+CAA+CI,CAAK,GAC7D,KAAM,OACR,CAAC,CACH,CAQA,MAAa,gBAAgB,CAC3B,QAAAa,EACA,QAAAK,CACF,EAAgD,CAC9C,GAAI,CAACL,EACH,MAAM,IAAIjB,EAAgB,CACxB,QAAS,2CACT,KAAM,OACR,CAAC,EAGCC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,kBAAmB,CACxC,QAAS,KAAK,MAChB,CAAC,EAEH,GAAI,CACF,IAAIqB,EAAW,CAAC,EAChBA,EAAW,MAAM,KAAK,uBAAuBA,CAAQ,EACrD,GAAM,CAAE,KAAApB,CAAK,EAAI,MAAM,KAAK,WAAW,OAGrC,CACA,SAAUqB,EACV,UAAsC,CACpC,OAAQ,KAAK,OACb,KAAMC,EAAa,KACnB,QAAAR,EACA,SAAAM,EACA,GAAID,GAAW,CAAE,QAASA,CAAQ,CACpC,CACF,CAAC,EAED,GAAInB,GAAM,SAMR,OALqBe,EACnBZ,EAAYS,EAAuBZ,EAAK,QAAQ,EAChD,KAAK,QACP,EAIA,MAAM,IAAIH,EAAgB,CACxB,QAAS,iEACT,KAAM,OACR,CAAC,CAEL,OAAS0B,EAAK,CACZ,MAAIzB,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,wBAAyB,CAAE,MAAOwB,CAAI,CAAC,EAE1D,IAAI1B,EAAgB,CACxB,QAAS,0CAA0C0B,CAAG,GACtD,KAAM,OACR,CAAC,CACH,CACF,CAEA,MAAa,iBAAiB,CAC5B,KAAAC,EACA,QAAAL,CACF,EAAiD,CAC/C,GAAI,CAACK,EACH,MAAM,IAAI3B,EAAgB,CACxB,QAAS,0CACT,KAAM,OACR,CAAC,EAGCC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,mBAAoB,CACzC,QAAS,KAAK,MAChB,CAAC,EAEH,GAAI,CACF,IAAIqB,EAAW,CAAC,EAChBA,EAAW,MAAM,KAAK,uBAAuBA,CAAQ,EACrD,GAAM,CAAE,KAAApB,CAAK,EAAI,MAAM,KAAK,WAAW,OAGrC,CACA,SAAUyB,EACV,UAAuC,CACrC,KAAAD,EACA,OAAQ,KAAK,OACb,KAAMF,EAAa,MACnB,GAAIH,GAAW,CAAE,QAASA,CAAQ,EAClC,SAAAC,CACF,EACA,QAAS,CACP,QAAS,CACP,eAAgB,qBAClB,CACF,CACF,CAAC,EAED,GAAIpB,GAAM,UAMR,OALsBe,EACpBZ,EAAYS,EAAuBZ,EAAK,SAAS,EACjD,KAAK,QACP,EAIA,MAAM,IAAIH,EAAgB,CACxB,QACE,gEACF,KAAM,OACR,CAAC,CAEL,OAAS0B,EAAK,CACZ,MAAIzB,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,yBAA0B,CAAE,MAAOwB,CAAI,CAAC,EAE3D,IAAI1B,EAAgB,CACxB,QAAS,0CAA0C0B,CAAG,GACtD,KAAM,OACR,CAAC,CACH,CACF,CAEA,MAAa,gBAAgB,CAC3B,KAAAC,EACA,QAAAL,CACF,EAAiD,CAC/C,GAAI,CAACK,EACH,MAAM,IAAI3B,EAAgB,CACxB,QAAS,yCACT,KAAM,OACR,CAAC,EAGCC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,kBAAmB,CACxC,QAAS,KAAK,MAChB,CAAC,EAEH,GAAI,CACF,IAAIqB,EAAW,CAAC,EAChBA,EAAW,MAAM,KAAK,uBAAuBA,CAAQ,EACrD,GAAM,CAAE,KAAApB,CAAK,EAAI,MAAM,KAAK,WAAW,OAGrC,CACA,SAAUyB,EACV,UAAuC,CACrC,KAAAD,EACA,OAAQ,KAAK,OACb,KAAMF,EAAa,IACnB,GAAIH,GAAW,CAAE,QAASA,CAAQ,EAClC,SAAAC,CACF,EACA,QAAS,CACP,QAAS,CACP,eAAgB,qBAClB,CACF,CACF,CAAC,EAED,GAAIpB,GAAM,UAMR,OALsBe,EACpBZ,EAAYS,EAAuBZ,EAAK,SAAS,EACjD,KAAK,QACP,EAIA,MAAM,IAAIH,EAAgB,CACxB,QACE,gEACF,KAAM,OACR,CAAC,CAEL,OAAS0B,EAAK,CACZ,MAAIzB,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,wBAAyB,CAAE,MAAOwB,CAAI,CAAC,EAE1D,IAAI1B,EAAgB,CACxB,QAAS,yCAAyC0B,CAAG,GACrD,KAAM,OACR,CAAC,CACH,CACF,CAQA,MAAa,iBAAiC,CAE5C,GAAI,GAAC,KAAK,YAAc,CAAC,KAAK,WAAW,QAIzC,GAAI,CACF,IAAMG,EAAqD,CAAC,EAE5D,QAAWC,KAAa,KAAK,WAAY,CACvC,IAAMC,EAAU,KAAK,WAAW,OAG9B,CACA,SAAUC,EACV,UAAW,CACT,OAAQF,CACV,EACA,mBAAoB,CAClB,WAAY,WACZ,SAAU,CACR,WAAY,aAEZ,QAASA,EACT,OAAQ,MACV,CACF,EACA,OAAQ,CAACG,EAAO,CAAE,KAAA9B,CAAK,IAAM,CACvBA,GAAM,UAAU,SAClB8B,EAAM,OAAO,CACX,GAAI,QAAQ9B,EAAK,SAAS,OAAO,GACjC,OAAQ,CACN,OAAO+B,EAAiB,CAAC,EAAG,CAC1B,IAAMC,EAAY,CAAC,GAAGD,CAAc,EACpC,OAAAC,EAAU,KAAK,CAEb,QAASL,EACT,OAAQ,OAER,QAAS,KAAK,UAAY,EAC5B,CAAC,EACMK,CACT,CACF,CACF,CAAC,CAEL,CACF,CAAC,EACDN,EAAS,KAAKE,CAAO,CACvB,CAEA,MAAM,QAAQ,IAAIF,CAAQ,EAG1B,IAAMO,EAAeC,EAAU,UAG7B,CACA,MAAOC,EACP,UAAW,CACT,OAAQ,EACV,CACF,CAAC,EAED,GAAIF,GAAc,MAAO,CACvB,IAAMG,EAAWH,EAAa,MAAM,IAAKI,GACnCA,EAAK,KAAO,KAAK,OACZ,CACL,GAAGA,EACH,OAAQ,CACV,EAEKA,CACR,EAEDH,EAAU,WAAkD,CAC1D,MAAOC,EACP,UAAW,CACT,OAAQ,EACV,EACA,KAAM,CACJ,MAAOC,CACT,CACF,CAAC,CACH,CAEItC,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,qBAAsB,CAC3C,QAAS,KAAK,OAEd,aAAc,KAAK,WAAW,MAChC,CAAC,EAEH,KAAK,WAAa,CAAC,CACrB,OAASwB,EAAK,CACZ,MAAM,IAAI1B,EAAgB,CACxB,QAAS,uCAAuC0B,CAAG,GACnD,KAAM,OACR,CAAC,CACH,CACF,CAQO,UAAUe,EAA4D,CAC3E,YAAK,aAAe,KAAK,WACtB,UAAkC,CACjC,MAAOC,EACP,UAAW,CACT,KAAM,KAAK,MACb,CACF,CAAC,EACA,UAAU,CACT,KAAOvC,GAAyB,CAC9B,IAAMwC,EAAarC,EACjBS,EACAZ,EAAK,KAAK,UACZ,EAEMyC,EAAgBP,EAAU,cAAkC,CAChE,GAAI,gBAAgBM,EAAW,EAAE,KACjC,SAAU,CACR,GAAG5B,EACH,YAAa,CACX,GAAGA,EAAsB,YACzB,GAAGR,EAAsB,WAC3B,CACF,EACA,aAAc,aACd,KAAMoC,CACR,CAAC,EAODN,EAAU,OAAO,CACf,GAAI,2BAA2B,KAAK,MAAM,KAC1C,OAAQ,CACN,MAAMQ,EAA4C,CAAC,EAAG,CACpD,MAAO,CAACD,EAAe,GAAGC,CAAa,CACzC,EACA,MAAMC,EAAgB,EAAG,CACvB,OAAOA,EAAgB,CACzB,CACF,CACF,CAAC,EAED,IAAMC,EAAiB7B,EACrBZ,EAAYS,EAAuBZ,EAAK,KAAK,UAAU,EACvD,KAAK,QACP,EAEA,KAAK,WAAW,KAAK4C,EAAe,EAAE,EAEtCN,EAAU,CAAE,KAAMM,EAAgB,UAAW,EAAK,CAAC,CACrD,EACA,MAAMC,EAAY,CACZ/C,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,2BAA4B,CACjD,MAAO8C,CACT,CAAC,EAEHP,EAAU,CACR,MAAO,IAAIzC,EAAgB,CACzB,QAAS,WAAWgD,CAAU,GAC9B,KAAM,OACR,CAAC,EACD,UAAW,EACb,CAAC,CACH,EACA,UAAW,CACTP,EAAU,CAAE,UAAW,EAAM,CAAC,CAChC,EACA,OAAQ,CACNA,EAAU,CAAE,UAAW,EAAK,CAAC,CAC/B,CACF,CAAC,EAEI,KAAK,YACd,CAEO,MAAa,CAEd,KAAK,aAAe,OACtB,KAAK,WAAW,eAAe,EAC/B,KAAK,YAAc,GAEvB,CAEO,aAAuB,CAC5B,OAAO,KAAK,WACd,CAEA,MAAc,uBAAuBlB,EAAU,CAC7C,GAAI,KAAK,cAAc,iBAAiB,IAAM,eAAgB,CAC5D,IAAI0B,EACJ,GAAI,CACF,GAAI,CAAC,KAAK,OAAQ,MAAM,MAAM,mBAAmB,EAEjD,IAAMC,EAAO,MAAM,KAAK,cAAc,aAAa,CACjD,OAAQC,EAAgB,IACxB,OAAQ,KAAK,MACf,CAAC,EAED,GAAID,EAAK,SAAW,EAAG,MAAM,MAAM,yBAAyB,EAE5DD,EAAgBC,EAAK,KAClBE,GAAOA,EAAG,SAAW,KAAK,cAAc,UAAU,CACrD,GAAG,cAEH7B,EAAS,KAAK,CACZ,IAAK,gBACL,MAAO0B,CACT,CAAC,CACH,MAAY,CACNhD,EAAU,QAAQ,GACpBA,EAAU,MAAMC,EAAO,qCAAsC,CAC3D,QAAS,KAAK,OAEd,SAAU,KAAK,cAAc,UAAU,EAEvC,gBAAiB+C,CACnB,CAAC,CACL,CACF,CACA,OAAO1B,CACT,CACF","sourcesContent":["import { FetchResult } from '@apollo/client';\nimport invariant from 'tiny-invariant';\nimport { Subscription } from 'zen-observable-ts';\nimport { AccountApi } from '@/api/account.api';\nimport { eventsApi, EVENTS } from '@/api/events.api';\nimport { GatewayApi } from '@/api/gateway.api';\nimport { CoachListStatus } from '@/constants/gateway';\nimport { NaluriChatError } from '@/errors';\nimport messagesFragment from '@/lib';\nimport userFragment from '@/lib/userFragement';\nimport {\n  Channel,\n  ChatChannelOptions,\n  GetIndividualMessageParam,\n  GetMessagesParams,\n  GetMessagesResponse,\n  NewMessageData,\n  SendMediaMessageParams,\n  SendTextMessageParams,\n  SubscriptionCallback,\n} from '@/types/channels';\nimport { ChatMessage, MessageTypes } from '@/types/messages';\n\nimport { ChatApi, chatCache } from '../api/chat.api';\nimport { useFragment } from '../generated';\nimport {\n  ChatFieldsFragment,\n  ChatFieldsFragmentDoc,\n  ChatResultsFieldFragment,\n  GetIndividualMessageDocument,\n  GetIndividualMessageQuery,\n  GetIndividualMessageQueryVariables,\n  GetRoomChatsDocument,\n  GetRoomChatsQuery,\n  GetRoomChatsQueryVariables,\n  GetRoomDocument,\n  GetRoomQuery,\n  GetRoomQueryVariables,\n  GetRoomsDocument,\n  GetRoomsQuery,\n  GetRoomsQueryVariables,\n  MarkReadDocument,\n  MarkReadMutation,\n  MarkReadMutationVariables,\n  NewMessageDocument,\n  NewMessageSubscription,\n  SendMediaDocument,\n  SendMediaMutation,\n  SendMediaMutationVariables,\n  SendTextDocument,\n  SendTextMutation,\n  SendTextMutationVariables,\n  UserFieldsFragmentDoc,\n} from '../generated/graphql';\n\n/**\n * Naluri Chat Channel\n * @class\n */\nexport class ChatChannel {\n  private chatClient: ChatApi;\n\n  private gatewayClient: GatewayApi;\n  private accountClient: AccountApi;\n\n  public roomId?: string;\n\n  private isConnected: boolean;\n\n  private subscription?: Subscription;\n\n  public senderId?: string;\n\n  public lastKey: string;\n\n  private unreadList: string[];\n\n  private lastKeys: Map<string, string[]>;\n\n  private emptyLastKey = '0000000-0000000';\n\n  constructor({\n    chatClient,\n    gatewayClient,\n    accountClient,\n    roomId,\n    senderId,\n    lastKeys,\n  }: ChatChannelOptions) {\n    invariant(chatClient, 'Chat client is required');\n\n    this.chatClient = chatClient;\n    this.gatewayClient = gatewayClient;\n    this.accountClient = accountClient;\n    this.roomId = roomId;\n    this.isConnected = false;\n    this.senderId = senderId;\n    this.lastKey = '';\n    this.unreadList = [];\n    this.lastKeys = lastKeys;\n  }\n\n  /**\n   * Get channel information\n   * @returns {PromiseLike<Channel>}\n   * @throws NaluriChatError if error\n   */\n  public async getChannel(): Promise<Channel> {\n    if (!this.roomId)\n      throw new NaluriChatError({\n        message: 'Please initialized the channel room.',\n        code: '40021',\n      });\n\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.GET_CHANNEL, {\n        channel: this.roomId,\n      });\n\n    const { data, error } = await this.chatClient.query<\n      GetRoomQuery,\n      GetRoomQueryVariables\n    >({\n      query: GetRoomDocument,\n      variables: { id: this.roomId },\n    });\n\n    if (data?.room) {\n      return {\n        id: data.room.id,\n        name: data.room.name,\n        type: data.room.type as Channel['type'],\n        lastMessageId: data.room.last_chat_id ?? undefined,\n        status: data.room.status ?? undefined,\n        createdAt: data.room.created_at,\n        updatedAt: data.room.updated_at,\n        unreadCount: data.room.unread ?? 0,\n        users: useFragment(UserFieldsFragmentDoc, data.room.users).map((user) =>\n          userFragment(user)\n        ),\n        metadata: data.room.metadata?.length\n          ? data.room.metadata?.map((meta) => ({\n              key: meta.key,\n              value: meta.value,\n            }))\n          : undefined,\n      };\n    }\n\n    if (eventsApi.isReady() && error) {\n      eventsApi.track(EVENTS.GET_CHANNEL_ERROR, {\n        channel: this.roomId,\n        error,\n      });\n    }\n\n    throw new NaluriChatError({\n      message: `Channel getChannel method error : ${error}`,\n      code: '40022',\n    });\n  }\n  /**\n   * Get messages from chat channel\n   * @param {GetMessageParams} params\n   * @returns {PromiseLike<GetMessagesResponse>}\n   * @throws NaluriChatError if error\n   */\n  public async getMessages(\n    { limit, after }: GetMessagesParams = { limit: 20 }\n  ): Promise<GetMessagesResponse> {\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.GET_CHANNEL_MESSAGES, {\n        channel: this.roomId,\n      });\n\n    try {\n      const { data, error } = await this.chatClient.query<\n        GetRoomChatsQuery,\n        GetRoomChatsQueryVariables\n      >({\n        query: GetRoomChatsDocument,\n        variables: <GetRoomChatsQueryVariables>{\n          roomId: this.roomId,\n          ...(limit ? { limit } : { limit: 20 }),\n          after,\n        },\n        fetchPolicy: 'network-only',\n      });\n\n      if (data?.chats) {\n        const messagesList = data.chats.chats.length\n          ? useFragment(ChatFieldsFragmentDoc, data.chats.chats).map((chat) => {\n              const message = messagesFragment(chat, this.senderId);\n              if (!message.readStatus) this.unreadList.push(message.id);\n              return message;\n            })\n          : [];\n\n        this.lastKey = data.chats.last_key ?? this.emptyLastKey;\n\n        const currentRoomKeys = this.lastKeys.get(this.roomId);\n\n        if (!currentRoomKeys) {\n          this.lastKeys.set(this.roomId, [data.chats.last_key]);\n        } else {\n          // push to the top\n          this.lastKeys.set(this.roomId, [\n            ...new Set([data.chats.last_key, ...currentRoomKeys]),\n          ]);\n        }\n\n        return {\n          roomId: data.chats.room_id,\n          count: data.chats.count,\n          lastKey: data.chats.last_key ?? undefined,\n          chats: messagesList,\n        };\n      }\n      throw new NaluriChatError({\n        message: `Channel getMessages method error : ${error}`,\n        code: '40023',\n      });\n    } catch (error) {\n      if (eventsApi.isReady())\n        eventsApi.track(EVENTS.GET_CHANNEL_MESSAGES_ERROR, { error });\n\n      throw new NaluriChatError({\n        message: `Channel getMessages method error : ${error}`,\n        code: '40023',\n      });\n    }\n  }\n\n  /**\n   * Get messages from chat channel\n   * @param {GetIndividualMessageParam} params\n   * @returns {PromiseLiKe<ChatMessage>}\n   * @throws NaluriChatError if error\n   */\n  public async getIndividualMessage({\n    id,\n    roomId,\n  }: GetIndividualMessageParam): Promise<ChatMessage> {\n    if (!id) {\n      throw new NaluriChatError({\n        message: `Channel getIndividualMessage requires message id`,\n        code: '40024',\n      });\n    }\n\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.GET_MESSAGE, {\n        channel: this.roomId,\n        // eslint-disable-next-line camelcase\n        message_id: id,\n      });\n\n    const { data, error } = await this.chatClient.query<\n      GetIndividualMessageQuery,\n      GetIndividualMessageQueryVariables\n    >({\n      query: GetIndividualMessageDocument,\n      variables: <GetIndividualMessageQueryVariables>{\n        roomId: roomId ?? this.roomId,\n        id,\n      },\n    });\n\n    if (data?.chat) {\n      const messagetData = messagesFragment(\n        useFragment(ChatFieldsFragmentDoc, data.chat),\n        this.senderId\n      );\n\n      return messagetData;\n    }\n\n    if (eventsApi.isReady() && error) {\n      eventsApi.track(EVENTS.GET_MESSAGE_ERROR, {\n        channel: this.roomId,\n        // eslint-disable-next-line camelcase\n        message_id: id,\n        error,\n      });\n    }\n\n    throw new NaluriChatError({\n      message: `Channel getIndividualMessage method error : ${error}`,\n      code: '40025',\n    });\n  }\n\n  /**\n   * Send text message to chat channel\n   * @param {SendTextMessageParams} params\n   * @returns {PromiseLike<ChatMessage>}\n   * @throws NaluriChatError if error\n   */\n  public async sendTextMessage({\n    message,\n    replyTo,\n  }: SendTextMessageParams): Promise<ChatMessage> {\n    if (!message) {\n      throw new NaluriChatError({\n        message: `Channel sendTextMessage requires message`,\n        code: '40025',\n      });\n    }\n\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.SEND_TEXT_MESSAGE, {\n        channel: this.roomId,\n      });\n\n    try {\n      let metadata = [];\n      metadata = await this.metadataAddActingCoach(metadata);\n      const { data } = await this.chatClient.mutate<\n        SendTextMutation,\n        SendTextMutationVariables\n      >({\n        mutation: SendTextDocument,\n        variables: <SendTextMutationVariables>{\n          roomId: this.roomId,\n          type: MessageTypes.TEXT,\n          message,\n          metadata,\n          ...(replyTo && { replyTo: replyTo }),\n        },\n      });\n\n      if (data?.sendText) {\n        const sendTextData = messagesFragment(\n          useFragment(ChatFieldsFragmentDoc, data.sendText),\n          this.senderId\n        );\n\n        return sendTextData;\n      } else {\n        throw new NaluriChatError({\n          message: `Channel sendTextMessage method error : missing returning data.`,\n          code: '40026',\n        });\n      }\n    } catch (err) {\n      if (eventsApi.isReady())\n        eventsApi.track(EVENTS.SEND_TEXT_MESSAGE_ERROR, { error: err });\n\n      throw new NaluriChatError({\n        message: `Channel sendTextMessage method error : ${err}`,\n        code: '40027',\n      });\n    }\n  }\n\n  public async sendImageMessage({\n    file,\n    replyTo,\n  }: SendMediaMessageParams): Promise<ChatMessage> {\n    if (!file) {\n      throw new NaluriChatError({\n        message: `Channel sendImageMessage requires file.`,\n        code: '40028',\n      });\n    }\n\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.SEND_IMAGE_MESSAGE, {\n        channel: this.roomId,\n      });\n\n    try {\n      let metadata = [];\n      metadata = await this.metadataAddActingCoach(metadata);\n      const { data } = await this.chatClient.mutate<\n        SendMediaMutation,\n        SendMediaMutationVariables\n      >({\n        mutation: SendMediaDocument,\n        variables: <SendMediaMutationVariables>{\n          file,\n          roomId: this.roomId,\n          type: MessageTypes.IMAGE,\n          ...(replyTo && { replyTo: replyTo }),\n          metadata,\n        },\n        context: {\n          headers: {\n            'content-type': 'multipart/form-data',\n          },\n        },\n      });\n\n      if (data?.sendMedia) {\n        const sendMediaData = messagesFragment(\n          useFragment(ChatFieldsFragmentDoc, data.sendMedia),\n          this.senderId\n        );\n\n        return sendMediaData;\n      } else {\n        throw new NaluriChatError({\n          message:\n            'Channel sendImageMessage method error: missing returning data',\n          code: '40029',\n        });\n      }\n    } catch (err) {\n      if (eventsApi.isReady())\n        eventsApi.track(EVENTS.SEND_IMAGE_MESSAGE_ERROR, { error: err });\n\n      throw new NaluriChatError({\n        message: `Channel sendImageMessage method error: ${err}`,\n        code: '40030',\n      });\n    }\n  }\n\n  public async sendFileMessage({\n    file,\n    replyTo,\n  }: SendMediaMessageParams): Promise<ChatMessage> {\n    if (!file) {\n      throw new NaluriChatError({\n        message: `Channel sendFileMessage requires file.`,\n        code: '40028',\n      });\n    }\n\n    if (eventsApi.isReady())\n      eventsApi.track(EVENTS.SEND_FILE_MESSAGE, {\n        channel: this.roomId,\n      });\n\n    try {\n      let metadata = [];\n      metadata = await this.metadataAddActingCoach(metadata);\n      const { data } = await this.chatClient.mutate<\n        SendMediaMutation,\n        SendMediaMutationVariables\n      >({\n        mutation: SendMediaDocument,\n        variables: <SendMediaMutationVariables>{\n          file,\n          roomId: this.roomId,\n          type: MessageTypes.PDF,\n          ...(replyTo && { replyTo: replyTo }),\n          metadata,\n        },\n        context: {\n          headers: {\n            'content-type': 'multipart/form-data',\n          },\n        },\n      });\n\n      if (data?.sendMedia) {\n        const sendMediaData = messagesFragment(\n          useFragment(ChatFieldsFragmentDoc, data.sendMedia),\n          this.senderId\n        );\n\n        return sendMediaData;\n      } else {\n        throw new NaluriChatError({\n          message:\n            'Channel sendFileMessage method error: missing returning data.',\n          code: '40031',\n        });\n      }\n    } catch (err) {\n      if (eventsApi.isReady())\n        eventsApi.track(EVENTS.SEND_FILE_MESSAGE_ERROR, { error: err });\n\n      throw new NaluriChatError({\n        message: `Channel sendFileMessage method error: ${err}`,\n        code: '40032',\n      });\n    }\n  }\n\n  /**\n   * Marks message read, this only mark those messages that query using\n   * getMessages method.\n   * @returns {Void}\n   * @throws NaluriChatError if error\n   */\n  public async markMessageRead(): Promise<void> {\n    // if there's no unreadList we just return as success\n    if (!this.unreadList || !this.unreadList.length) {\n      return;\n    }\n\n    try {\n      const promises: Promise<FetchResult<MarkReadMutation>>[] = [];\n\n      for (const messageId of this.unreadList) {\n        const promise = this.chatClient.mutate<\n          MarkReadMutation,\n          MarkReadMutationVariables\n        >({\n          mutation: MarkReadDocument,\n          variables: {\n            chatId: messageId,\n          },\n          optimisticResponse: {\n            __typename: 'Mutation',\n            markRead: {\n              __typename: 'ChatStatus',\n              // eslint-disable-next-line camelcase\n              chat_id: messageId,\n              status: 'READ',\n            },\n          },\n          update: (cache, { data }) => {\n            if (data?.markRead?.chat_id) {\n              cache.modify({\n                id: `Chat:${data.markRead.chat_id}`,\n                fields: {\n                  status(existingStatus = []) {\n                    const newStatus = [...existingStatus];\n                    newStatus.push({\n                      // eslint-disable-next-line camelcase\n                      chat_id: messageId,\n                      status: 'READ',\n                      // eslint-disable-next-line camelcase\n                      user_id: this.senderId ?? '',\n                    });\n                    return newStatus;\n                  },\n                },\n              });\n            }\n          },\n        });\n        promises.push(promise);\n      }\n\n      await Promise.all(promises);\n\n      // trust me, i do not know why we need to use Rooms instead of Room\n      const currentRooms = chatCache.readQuery<\n        GetRoomsQuery,\n        GetRoomsQueryVariables\n      >({\n        query: GetRoomsDocument,\n        variables: {\n          isChat: true,\n        },\n      });\n\n      if (currentRooms?.rooms) {\n        const newRooms = currentRooms.rooms.map((room) => {\n          if (room.id === this.roomId) {\n            return {\n              ...room,\n              unread: 0,\n            };\n          }\n          return room;\n        });\n\n        chatCache.writeQuery<GetRoomsQuery, GetRoomsQueryVariables>({\n          query: GetRoomsDocument,\n          variables: {\n            isChat: true,\n          },\n          data: {\n            rooms: newRooms,\n          },\n        });\n      }\n\n      if (eventsApi.isReady())\n        eventsApi.track(EVENTS.MARK_MESSAGE_AS_READ, {\n          channel: this.roomId,\n          // eslint-disable-next-line camelcase\n          unread_count: this.unreadList.length,\n        });\n\n      this.unreadList = [];\n    } catch (err) {\n      throw new NaluriChatError({\n        message: `Channel mark message as read error: ${err}`,\n        code: '40032',\n      });\n    }\n  }\n\n  /**\n   * subscribe method to individual channel\n   * @param {SubscriptionCallback} params\n   * @returns {Subscription}\n   * @throws NaluriChatError if error\n   */\n  public subscribe(onReceive: SubscriptionCallback<ChatMessage>): Subscription {\n    this.subscription = this.chatClient\n      .subscribe<NewMessageSubscription>({\n        query: NewMessageDocument,\n        variables: {\n          room: this.roomId,\n        },\n      })\n      .subscribe({\n        next: (data: NewMessageData) => {\n          const newMessage = useFragment(\n            ChatFieldsFragmentDoc,\n            data.data.newMessage\n          );\n\n          const newMessageRef = chatCache.writeFragment<ChatFieldsFragment>({\n            id: `Chat:{\"id\": \"${newMessage.id}\"}`,\n            fragment: {\n              ...ChatFieldsFragmentDoc,\n              definitions: [\n                ...ChatFieldsFragmentDoc.definitions,\n                ...UserFieldsFragmentDoc.definitions,\n              ],\n            },\n            fragmentName: 'ChatFields',\n            data: newMessage,\n          });\n\n          // last key will be null if there is no previous message\n          // const lastCachedKey = !this.lastKey\n          //   ? this.emptyLastKey\n          //   : this.lastKey;\n          //   ,\"last_key\":\"${lastCachedKey}\"\n          chatCache.modify({\n            id: `ChatResults:{\"room_id\":\"${this.roomId}\"}`,\n            fields: {\n              chats(existingChats: ChatResultsFieldFragment[] = []) {\n                return [newMessageRef, ...existingChats];\n              },\n              count(existingCount = 0) {\n                return existingCount + 1;\n              },\n            },\n          });\n\n          const newMessageData = messagesFragment(\n            useFragment(ChatFieldsFragmentDoc, data.data.newMessage),\n            this.senderId\n          );\n\n          this.unreadList.push(newMessageData.id);\n\n          onReceive({ data: newMessageData, connected: true });\n        },\n        error(errorValue) {\n          if (eventsApi.isReady())\n            eventsApi.track(EVENTS.CHANNEL_SUBSCRIPTION_ERROR, {\n              error: errorValue,\n            });\n\n          onReceive({\n            error: new NaluriChatError({\n              message: `Channel ${errorValue}`,\n              code: '40033',\n            }),\n            connected: false,\n          });\n        },\n        complete() {\n          onReceive({ connected: false });\n        },\n        start() {\n          onReceive({ connected: true });\n        },\n      });\n\n    return this.subscription;\n  }\n\n  public stop(): void {\n    console.debug('stop');\n    if (this.chatClient !== null) {\n      this.chatClient.unSubscribeAll();\n      this.isConnected = false;\n    }\n  }\n\n  public isListening(): boolean {\n    return this.isConnected;\n  }\n\n  private async metadataAddActingCoach(metadata) {\n    if (this.accountClient.getUserReference() === 'naluri_coach') {\n      let actingCoachId;\n      try {\n        if (!this.roomId) throw Error('room id not found');\n\n        const list = await this.gatewayClient.getCoachList({\n          status: CoachListStatus.ALL,\n          roomId: this.roomId,\n        });\n\n        if (list.length === 0) throw Error('coach not found in list');\n\n        actingCoachId = list.find(\n          (el) => el.userId === this.accountClient.getUserId()\n        )?.actingCoachId;\n\n        metadata.push({\n          key: 'actingCoachId',\n          value: actingCoachId,\n        });\n      } catch (e) {\n        if (eventsApi.isReady())\n          eventsApi.track(EVENTS.CHANNEL_ACTING_COACH_INJECTION_ERROR, {\n            channel: this.roomId,\n            // eslint-disable-next-line camelcase\n            coach_id: this.accountClient.getUserId(),\n            // eslint-disable-next-line camelcase\n            acting_coach_id: actingCoachId,\n          });\n      }\n    }\n    return metadata;\n  }\n}\n"]}