@scalemule/chat 0.0.3 → 0.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.cts CHANGED
@@ -1,6 +1,77 @@
1
- export { C as ChatClient } from './ChatClient-lwyQYmNf.cjs';
2
- export { A as ApiError, a as ApiResponse, b as Attachment, C as ChannelSettings, c as ChannelWithSettings, d as ChatConfig, e as ChatEventMap, f as ChatMessage, g as ChatReaction, h as ConnectionStatus, i as Conversation, j as CreateConversationOptions, k as CreateEphemeralChannelOptions, l as CreateLargeRoomOptions, G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, P as Participant, m as PresenceMember, R as ReactionSummary, n as ReadStatus, S as SendMessageOptions, U as UnreadTotalResponse } from './types-FQcFhbJx.cjs';
1
+ import { C as ChatClient } from './ChatClient-BoZaTtyM.cjs';
2
+ export { d as ApiError, A as ApiResponse, e as Attachment, f as ChannelSettings, g as ChannelWithSettings, C as ChatConfig, h as ChatEventMap, a as ChatMessage, i as ChatReaction, b as ConnectionStatus, c as Conversation, j as CreateConversationOptions, k as CreateEphemeralChannelOptions, l as CreateLargeRoomOptions, G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, P as Participant, m as PresenceMember, R as ReactionSummary, n as ReadStatus, S as SendMessageOptions, U as UnreadTotalResponse } from './types-BmD7f1gV.cjs';
3
+
4
+ /**
5
+ * SupportClient — High-level client for the support chat widget.
6
+ *
7
+ * Handles visitor session lifecycle (create/restore/refresh) and exposes
8
+ * the underlying ChatClient for real-time messaging.
9
+ *
10
+ * Usage:
11
+ * ```ts
12
+ * const support = new SupportClient({ apiKey: 'pb_...', apiBaseUrl: 'https://api.scalemule.com' });
13
+ * await support.initVisitorSession({ name: 'Jane' });
14
+ * const conversation = await support.startConversation('Hi, I need help!', { page_url: location.href });
15
+ * support.chat.on('message', (msg) => console.log(msg));
16
+ * ```
17
+ */
18
+
19
+ interface SupportConversation {
20
+ id: string;
21
+ conversation_id: string;
22
+ status: string;
23
+ visitor_name?: string;
24
+ visitor_email?: string;
25
+ visitor_page_url?: string;
26
+ assigned_rep_id?: string;
27
+ assigned_rep_name?: string;
28
+ last_message_preview?: string;
29
+ last_message_at?: string;
30
+ created_at: string;
31
+ existing?: boolean;
32
+ }
33
+ interface SupportClientConfig {
34
+ apiKey: string;
35
+ apiBaseUrl?: string;
36
+ }
37
+ declare class SupportClient {
38
+ private chatClient;
39
+ private apiKey;
40
+ private apiBaseUrl;
41
+ private storageKey;
42
+ private anonymousId;
43
+ private refreshToken;
44
+ private accessToken;
45
+ private tokenExpiresAt;
46
+ private userId;
47
+ private visitorName;
48
+ private visitorEmail;
49
+ constructor(config: SupportClientConfig);
50
+ /** Create or restore a visitor session. Call before startConversation(). */
51
+ initVisitorSession(info?: {
52
+ name?: string;
53
+ email?: string;
54
+ }): Promise<void>;
55
+ /** Start a new support conversation with the first message. */
56
+ startConversation(message: string, meta?: {
57
+ page_url?: string;
58
+ }): Promise<SupportConversation>;
59
+ /** Get the visitor's active/waiting support conversation, if any. */
60
+ getActiveConversation(): Promise<SupportConversation | null>;
61
+ /** Get the underlying ChatClient for messaging, events, typing indicators, etc. */
62
+ get chat(): ChatClient;
63
+ /** Whether a visitor session has been initialized. */
64
+ get isInitialized(): boolean;
65
+ /** The visitor's user ID (available after initVisitorSession). */
66
+ get visitorUserId(): string | null;
67
+ /** Clean up all resources. */
68
+ destroy(): void;
69
+ private initChatClient;
70
+ private refreshAccessToken;
71
+ private loadState;
72
+ private saveState;
73
+ }
3
74
 
4
75
  declare const CHAT_VERSION = "0.0.1";
5
76
 
6
- export { CHAT_VERSION };
77
+ export { CHAT_VERSION, ChatClient, SupportClient, type SupportClientConfig, type SupportConversation };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,77 @@
1
- export { C as ChatClient } from './ChatClient-BD0sMudg.js';
2
- export { A as ApiError, a as ApiResponse, b as Attachment, C as ChannelSettings, c as ChannelWithSettings, d as ChatConfig, e as ChatEventMap, f as ChatMessage, g as ChatReaction, h as ConnectionStatus, i as Conversation, j as CreateConversationOptions, k as CreateEphemeralChannelOptions, l as CreateLargeRoomOptions, G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, P as Participant, m as PresenceMember, R as ReactionSummary, n as ReadStatus, S as SendMessageOptions, U as UnreadTotalResponse } from './types-FQcFhbJx.js';
1
+ import { C as ChatClient } from './ChatClient-COmdEJ11.js';
2
+ export { d as ApiError, A as ApiResponse, e as Attachment, f as ChannelSettings, g as ChannelWithSettings, C as ChatConfig, h as ChatEventMap, a as ChatMessage, i as ChatReaction, b as ConnectionStatus, c as Conversation, j as CreateConversationOptions, k as CreateEphemeralChannelOptions, l as CreateLargeRoomOptions, G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, P as Participant, m as PresenceMember, R as ReactionSummary, n as ReadStatus, S as SendMessageOptions, U as UnreadTotalResponse } from './types-BmD7f1gV.js';
3
+
4
+ /**
5
+ * SupportClient — High-level client for the support chat widget.
6
+ *
7
+ * Handles visitor session lifecycle (create/restore/refresh) and exposes
8
+ * the underlying ChatClient for real-time messaging.
9
+ *
10
+ * Usage:
11
+ * ```ts
12
+ * const support = new SupportClient({ apiKey: 'pb_...', apiBaseUrl: 'https://api.scalemule.com' });
13
+ * await support.initVisitorSession({ name: 'Jane' });
14
+ * const conversation = await support.startConversation('Hi, I need help!', { page_url: location.href });
15
+ * support.chat.on('message', (msg) => console.log(msg));
16
+ * ```
17
+ */
18
+
19
+ interface SupportConversation {
20
+ id: string;
21
+ conversation_id: string;
22
+ status: string;
23
+ visitor_name?: string;
24
+ visitor_email?: string;
25
+ visitor_page_url?: string;
26
+ assigned_rep_id?: string;
27
+ assigned_rep_name?: string;
28
+ last_message_preview?: string;
29
+ last_message_at?: string;
30
+ created_at: string;
31
+ existing?: boolean;
32
+ }
33
+ interface SupportClientConfig {
34
+ apiKey: string;
35
+ apiBaseUrl?: string;
36
+ }
37
+ declare class SupportClient {
38
+ private chatClient;
39
+ private apiKey;
40
+ private apiBaseUrl;
41
+ private storageKey;
42
+ private anonymousId;
43
+ private refreshToken;
44
+ private accessToken;
45
+ private tokenExpiresAt;
46
+ private userId;
47
+ private visitorName;
48
+ private visitorEmail;
49
+ constructor(config: SupportClientConfig);
50
+ /** Create or restore a visitor session. Call before startConversation(). */
51
+ initVisitorSession(info?: {
52
+ name?: string;
53
+ email?: string;
54
+ }): Promise<void>;
55
+ /** Start a new support conversation with the first message. */
56
+ startConversation(message: string, meta?: {
57
+ page_url?: string;
58
+ }): Promise<SupportConversation>;
59
+ /** Get the visitor's active/waiting support conversation, if any. */
60
+ getActiveConversation(): Promise<SupportConversation | null>;
61
+ /** Get the underlying ChatClient for messaging, events, typing indicators, etc. */
62
+ get chat(): ChatClient;
63
+ /** Whether a visitor session has been initialized. */
64
+ get isInitialized(): boolean;
65
+ /** The visitor's user ID (available after initVisitorSession). */
66
+ get visitorUserId(): string | null;
67
+ /** Clean up all resources. */
68
+ destroy(): void;
69
+ private initChatClient;
70
+ private refreshAccessToken;
71
+ private loadState;
72
+ private saveState;
73
+ }
3
74
 
4
75
  declare const CHAT_VERSION = "0.0.1";
5
76
 
6
- export { CHAT_VERSION };
77
+ export { CHAT_VERSION, ChatClient, SupportClient, type SupportClientConfig, type SupportConversation };
package/dist/index.js CHANGED
@@ -1,6 +1,202 @@
1
- export { ChatClient } from './chunk-FXO4ZYQB.js';
1
+ import { ChatClient } from './chunk-ZLMMNFZL.js';
2
+ export { ChatClient } from './chunk-ZLMMNFZL.js';
3
+
4
+ // src/support.ts
5
+ var STORAGE_PREFIX = "sm_support_";
6
+ var SupportClient = class {
7
+ constructor(config) {
8
+ this.chatClient = null;
9
+ this.refreshToken = null;
10
+ this.accessToken = null;
11
+ this.tokenExpiresAt = 0;
12
+ this.userId = null;
13
+ this.apiKey = config.apiKey;
14
+ this.apiBaseUrl = config.apiBaseUrl ?? "https://api.scalemule.com";
15
+ this.storageKey = STORAGE_PREFIX + config.apiKey.substring(0, 8);
16
+ const stored = this.loadState();
17
+ if (stored) {
18
+ this.anonymousId = stored.anonymous_id;
19
+ this.refreshToken = stored.refresh_token;
20
+ this.userId = stored.user_id;
21
+ } else {
22
+ this.anonymousId = crypto.randomUUID();
23
+ }
24
+ }
25
+ /** Create or restore a visitor session. Call before startConversation(). */
26
+ async initVisitorSession(info) {
27
+ this.visitorName = info?.name;
28
+ this.visitorEmail = info?.email;
29
+ if (this.refreshToken) {
30
+ try {
31
+ await this.refreshAccessToken();
32
+ this.initChatClient();
33
+ return;
34
+ } catch {
35
+ this.refreshToken = null;
36
+ }
37
+ }
38
+ const resp = await fetch(`${this.apiBaseUrl}/v1/auth/visitor-session`, {
39
+ method: "POST",
40
+ headers: {
41
+ "Content-Type": "application/json",
42
+ "x-api-key": this.apiKey
43
+ },
44
+ body: JSON.stringify({
45
+ anonymous_id: this.anonymousId,
46
+ name: info?.name,
47
+ email: info?.email,
48
+ page_url: typeof location !== "undefined" ? location.href : void 0
49
+ })
50
+ });
51
+ if (!resp.ok) {
52
+ const body = await resp.text();
53
+ throw new Error(`Visitor session failed: ${resp.status} ${body}`);
54
+ }
55
+ const result = await resp.json();
56
+ const data = result.data;
57
+ this.accessToken = data.access_token;
58
+ this.refreshToken = data.refresh_token;
59
+ this.userId = data.user_id;
60
+ this.tokenExpiresAt = Date.now() + data.expires_in * 1e3;
61
+ this.saveState();
62
+ this.initChatClient();
63
+ }
64
+ /** Start a new support conversation with the first message. */
65
+ async startConversation(message, meta) {
66
+ if (!this.accessToken) {
67
+ throw new Error("Call initVisitorSession() first");
68
+ }
69
+ const resp = await fetch(`${this.apiBaseUrl}/v1/chat/support/conversations`, {
70
+ method: "POST",
71
+ headers: {
72
+ "Content-Type": "application/json",
73
+ "x-api-key": this.apiKey,
74
+ Authorization: `Bearer ${this.accessToken}`
75
+ },
76
+ body: JSON.stringify({
77
+ message,
78
+ name: this.visitorName,
79
+ email: this.visitorEmail,
80
+ page_url: meta?.page_url ?? (typeof location !== "undefined" ? location.href : void 0),
81
+ user_agent: typeof navigator !== "undefined" ? navigator.userAgent : void 0
82
+ })
83
+ });
84
+ if (!resp.ok) {
85
+ const body = await resp.text();
86
+ throw new Error(`Create support conversation failed: ${resp.status} ${body}`);
87
+ }
88
+ const result = await resp.json();
89
+ const conversation = result.data;
90
+ if (this.chatClient) {
91
+ this.chatClient.conversationTypes?.set(conversation.conversation_id, "support");
92
+ }
93
+ return conversation;
94
+ }
95
+ /** Get the visitor's active/waiting support conversation, if any. */
96
+ async getActiveConversation() {
97
+ if (!this.accessToken) return null;
98
+ const resp = await fetch(`${this.apiBaseUrl}/v1/chat/support/conversations/mine`, {
99
+ headers: {
100
+ "x-api-key": this.apiKey,
101
+ Authorization: `Bearer ${this.accessToken}`
102
+ }
103
+ });
104
+ if (!resp.ok) return null;
105
+ const result = await resp.json();
106
+ const conversations = result.data;
107
+ const active = conversations.find((c) => c.status === "active" || c.status === "waiting");
108
+ if (active && this.chatClient) {
109
+ this.chatClient.conversationTypes?.set(active.conversation_id, "support");
110
+ }
111
+ return active ?? null;
112
+ }
113
+ /** Get the underlying ChatClient for messaging, events, typing indicators, etc. */
114
+ get chat() {
115
+ if (!this.chatClient) {
116
+ throw new Error("Call initVisitorSession() first");
117
+ }
118
+ return this.chatClient;
119
+ }
120
+ /** Whether a visitor session has been initialized. */
121
+ get isInitialized() {
122
+ return this.chatClient !== null;
123
+ }
124
+ /** The visitor's user ID (available after initVisitorSession). */
125
+ get visitorUserId() {
126
+ return this.userId;
127
+ }
128
+ /** Clean up all resources. */
129
+ destroy() {
130
+ this.chatClient?.destroy();
131
+ this.chatClient = null;
132
+ }
133
+ // ============ Private ============
134
+ initChatClient() {
135
+ if (this.chatClient) {
136
+ this.chatClient.destroy();
137
+ }
138
+ const config = {
139
+ apiKey: this.apiKey,
140
+ apiBaseUrl: this.apiBaseUrl,
141
+ // Proactive token refresh: check expiry before each request.
142
+ // HttpTransport and WebSocketTransport call getToken() once per request
143
+ // and do NOT retry on 401/null, so the token must be valid when returned.
144
+ getToken: async () => {
145
+ if (!this.accessToken) return null;
146
+ if (Date.now() > this.tokenExpiresAt - 6e4) {
147
+ try {
148
+ await this.refreshAccessToken();
149
+ } catch {
150
+ }
151
+ }
152
+ return this.accessToken;
153
+ }
154
+ };
155
+ this.chatClient = new ChatClient(config);
156
+ }
157
+ async refreshAccessToken() {
158
+ if (!this.refreshToken) throw new Error("No refresh token");
159
+ const resp = await fetch(`${this.apiBaseUrl}/v1/auth/token/refresh`, {
160
+ method: "POST",
161
+ headers: {
162
+ "Content-Type": "application/json",
163
+ "x-api-key": this.apiKey
164
+ },
165
+ body: JSON.stringify({ refresh_token: this.refreshToken })
166
+ });
167
+ if (!resp.ok) {
168
+ throw new Error(`Token refresh failed: ${resp.status}`);
169
+ }
170
+ const result = await resp.json();
171
+ const data = result.data;
172
+ this.accessToken = data.access_token;
173
+ this.tokenExpiresAt = Date.now() + data.expires_in * 1e3;
174
+ }
175
+ loadState() {
176
+ try {
177
+ const raw = localStorage.getItem(this.storageKey);
178
+ if (!raw) return null;
179
+ return JSON.parse(raw);
180
+ } catch {
181
+ return null;
182
+ }
183
+ }
184
+ saveState() {
185
+ try {
186
+ localStorage.setItem(
187
+ this.storageKey,
188
+ JSON.stringify({
189
+ anonymous_id: this.anonymousId,
190
+ refresh_token: this.refreshToken,
191
+ user_id: this.userId
192
+ })
193
+ );
194
+ } catch {
195
+ }
196
+ }
197
+ };
2
198
 
3
199
  // src/version.ts
4
200
  var CHAT_VERSION = "0.0.1";
5
201
 
6
- export { CHAT_VERSION };
202
+ export { CHAT_VERSION, SupportClient };
package/dist/react.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  'use strict';
2
2
 
3
- var chunkWYFNZUAL_cjs = require('./chunk-WYFNZUAL.cjs');
3
+ var chunkYDLRISR7_cjs = require('./chunk-YDLRISR7.cjs');
4
4
  var react = require('react');
5
5
  var jsxRuntime = require('react/jsx-runtime');
6
6
 
@@ -11,7 +11,7 @@ function useChatContext() {
11
11
  return ctx;
12
12
  }
13
13
  function ChatProvider({ config, children }) {
14
- const [client] = react.useState(() => new chunkWYFNZUAL_cjs.ChatClient(config));
14
+ const [client] = react.useState(() => new chunkYDLRISR7_cjs.ChatClient(config));
15
15
  react.useEffect(() => {
16
16
  return () => {
17
17
  client.destroy();
@@ -19,6 +19,9 @@ function ChatProvider({ config, children }) {
19
19
  }, [client]);
20
20
  return /* @__PURE__ */ jsxRuntime.jsx(ChatContext.Provider, { value: { client }, children });
21
21
  }
22
+ function useChatClient() {
23
+ return useChatContext().client;
24
+ }
22
25
  function useConnection() {
23
26
  const { client } = useChatContext();
24
27
  const [status, setStatus] = react.useState(client.status);
@@ -31,11 +34,9 @@ function useConnection() {
31
34
  react.useEffect(() => {
32
35
  return client.on("reconnecting", () => setStatus("reconnecting"));
33
36
  }, [client]);
34
- return {
35
- status,
36
- connect: () => client.connect(),
37
- disconnect: () => client.disconnect()
38
- };
37
+ const connect = react.useCallback(() => client.connect(), [client]);
38
+ const disconnect = react.useCallback(() => client.disconnect(), [client]);
39
+ return { status, connect, disconnect };
39
40
  }
40
41
  function useChat(conversationId) {
41
42
  const { client } = useChatContext();
@@ -300,10 +301,11 @@ function useUnreadCount() {
300
301
 
301
302
  Object.defineProperty(exports, "ChatClient", {
302
303
  enumerable: true,
303
- get: function () { return chunkWYFNZUAL_cjs.ChatClient; }
304
+ get: function () { return chunkYDLRISR7_cjs.ChatClient; }
304
305
  });
305
306
  exports.ChatProvider = ChatProvider;
306
307
  exports.useChat = useChat;
308
+ exports.useChatClient = useChatClient;
307
309
  exports.useConnection = useConnection;
308
310
  exports.useConversations = useConversations;
309
311
  exports.usePresence = usePresence;
package/dist/react.d.cts CHANGED
@@ -1,13 +1,15 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { d as ChatConfig, f as ChatMessage, S as SendMessageOptions, a as ApiResponse, h as ConnectionStatus, i as Conversation } from './types-FQcFhbJx.cjs';
3
- export { G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, R as ReactionSummary, U as UnreadTotalResponse } from './types-FQcFhbJx.cjs';
4
- export { C as ChatClient } from './ChatClient-lwyQYmNf.cjs';
2
+ import { C as ChatClient } from './ChatClient-BoZaTtyM.cjs';
3
+ import { C as ChatConfig, a as ChatMessage, S as SendMessageOptions, A as ApiResponse, b as ConnectionStatus, c as Conversation } from './types-BmD7f1gV.cjs';
4
+ export { G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, R as ReactionSummary, U as UnreadTotalResponse } from './types-BmD7f1gV.cjs';
5
5
 
6
6
  interface ChatProviderProps {
7
7
  config: ChatConfig;
8
8
  children: ReactNode;
9
9
  }
10
10
  declare function ChatProvider({ config, children }: ChatProviderProps): React.JSX.Element;
11
+ /** Direct access to the ChatClient instance for custom event subscriptions (e.g., support:new). */
12
+ declare function useChatClient(): ChatClient;
11
13
  declare function useConnection(): {
12
14
  status: ConnectionStatus;
13
15
  connect: () => void;
@@ -44,4 +46,4 @@ declare function useUnreadCount(): {
44
46
  totalUnread: number;
45
47
  };
46
48
 
47
- export { ApiResponse, ChatConfig, ChatMessage, ChatProvider, ConnectionStatus, Conversation, SendMessageOptions, useChat, useConnection, useConversations, usePresence, useTyping, useUnreadCount };
49
+ export { ApiResponse, ChatClient, ChatConfig, ChatMessage, ChatProvider, ConnectionStatus, Conversation, SendMessageOptions, useChat, useChatClient, useConnection, useConversations, usePresence, useTyping, useUnreadCount };
package/dist/react.d.ts CHANGED
@@ -1,13 +1,15 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { d as ChatConfig, f as ChatMessage, S as SendMessageOptions, a as ApiResponse, h as ConnectionStatus, i as Conversation } from './types-FQcFhbJx.js';
3
- export { G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, R as ReactionSummary, U as UnreadTotalResponse } from './types-FQcFhbJx.js';
4
- export { C as ChatClient } from './ChatClient-BD0sMudg.js';
2
+ import { C as ChatClient } from './ChatClient-COmdEJ11.js';
3
+ import { C as ChatConfig, a as ChatMessage, S as SendMessageOptions, A as ApiResponse, b as ConnectionStatus, c as Conversation } from './types-BmD7f1gV.js';
4
+ export { G as GetMessagesOptions, L as ListConversationsOptions, M as MessagesResponse, R as ReactionSummary, U as UnreadTotalResponse } from './types-BmD7f1gV.js';
5
5
 
6
6
  interface ChatProviderProps {
7
7
  config: ChatConfig;
8
8
  children: ReactNode;
9
9
  }
10
10
  declare function ChatProvider({ config, children }: ChatProviderProps): React.JSX.Element;
11
+ /** Direct access to the ChatClient instance for custom event subscriptions (e.g., support:new). */
12
+ declare function useChatClient(): ChatClient;
11
13
  declare function useConnection(): {
12
14
  status: ConnectionStatus;
13
15
  connect: () => void;
@@ -44,4 +46,4 @@ declare function useUnreadCount(): {
44
46
  totalUnread: number;
45
47
  };
46
48
 
47
- export { ApiResponse, ChatConfig, ChatMessage, ChatProvider, ConnectionStatus, Conversation, SendMessageOptions, useChat, useConnection, useConversations, usePresence, useTyping, useUnreadCount };
49
+ export { ApiResponse, ChatClient, ChatConfig, ChatMessage, ChatProvider, ConnectionStatus, Conversation, SendMessageOptions, useChat, useChatClient, useConnection, useConversations, usePresence, useTyping, useUnreadCount };
package/dist/react.js CHANGED
@@ -1,5 +1,5 @@
1
- import { ChatClient } from './chunk-FXO4ZYQB.js';
2
- export { ChatClient } from './chunk-FXO4ZYQB.js';
1
+ import { ChatClient } from './chunk-ZLMMNFZL.js';
2
+ export { ChatClient } from './chunk-ZLMMNFZL.js';
3
3
  import { createContext, useState, useEffect, useCallback, useRef, useContext } from 'react';
4
4
  import { jsx } from 'react/jsx-runtime';
5
5
 
@@ -18,6 +18,9 @@ function ChatProvider({ config, children }) {
18
18
  }, [client]);
19
19
  return /* @__PURE__ */ jsx(ChatContext.Provider, { value: { client }, children });
20
20
  }
21
+ function useChatClient() {
22
+ return useChatContext().client;
23
+ }
21
24
  function useConnection() {
22
25
  const { client } = useChatContext();
23
26
  const [status, setStatus] = useState(client.status);
@@ -30,11 +33,9 @@ function useConnection() {
30
33
  useEffect(() => {
31
34
  return client.on("reconnecting", () => setStatus("reconnecting"));
32
35
  }, [client]);
33
- return {
34
- status,
35
- connect: () => client.connect(),
36
- disconnect: () => client.disconnect()
37
- };
36
+ const connect = useCallback(() => client.connect(), [client]);
37
+ const disconnect = useCallback(() => client.disconnect(), [client]);
38
+ return { status, connect, disconnect };
38
39
  }
39
40
  function useChat(conversationId) {
40
41
  const { client } = useChatContext();
@@ -297,4 +298,4 @@ function useUnreadCount() {
297
298
  return { totalUnread };
298
299
  }
299
300
 
300
- export { ChatProvider, useChat, useConnection, useConversations, usePresence, useTyping, useUnreadCount };
301
+ export { ChatProvider, useChat, useChatClient, useConnection, useConversations, usePresence, useTyping, useUnreadCount };