@cstar.help/react 0.6.1 → 0.8.0

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/README.md CHANGED
@@ -24,7 +24,7 @@ import { CStarChatProvider } from '@cstar.help/react';
24
24
 
25
25
  function App() {
26
26
  return (
27
- <CStarChatProvider teamSlug="acme" supabaseUrl="..." supabaseAnonKey="...">
27
+ <CStarChatProvider teamSlug="acme">
28
28
  <ChatWidget />
29
29
  </CStarChatProvider>
30
30
  );
@@ -47,24 +47,24 @@ function ChatWidget() {
47
47
  }, []);
48
48
 
49
49
  if (!isIdentified) return <p>Connecting...</p>;
50
- return <ConversationList />;
50
+ return <TicketList />;
51
51
  }
52
52
  ```
53
53
 
54
- ### Conversations
54
+ ### Tickets
55
55
 
56
56
  ```tsx
57
- import { useConversations } from '@cstar.help/react';
57
+ import { useTickets } from '@cstar.help/react';
58
58
 
59
- function ConversationList() {
60
- const { conversations, isLoading, create, refresh, hasMore } = useConversations();
59
+ function TicketList() {
60
+ const { tickets, isLoading, create, refresh, hasMore } = useTickets();
61
61
 
62
62
  if (isLoading) return <Spinner />;
63
63
 
64
64
  return (
65
65
  <ul>
66
- {conversations.map((c) => (
67
- <li key={c.id}>{c.subject}</li>
66
+ {tickets.map((t) => (
67
+ <li key={t.id}>{t.subject}</li>
68
68
  ))}
69
69
  </ul>
70
70
  );
@@ -270,7 +270,7 @@ function CommunitySearch() {
270
270
  | Hook | Returns | Description |
271
271
  | ----------------------- | ---------------------------------------------------------------- | ---------------------------------------------------- |
272
272
  | `useChat()` | `{ identify, disconnect, isIdentified, isRealtimeReady, error }` | Identity verification and connection state |
273
- | `useConversations()` | `{ conversations, isLoading, error, hasMore, refresh, create }` | List and create conversations |
273
+ | `useTickets()` | `{ tickets, isLoading, error, hasMore, refresh, create }` | List and create tickets |
274
274
  | `useMessages(ticketId)` | `{ messages, isLoading, error, send, refresh }` | Messages with real-time updates and optimistic send |
275
275
  | `useTyping(ticketId)` | `{ typingAgents, sendTyping }` | Agent typing indicators with auto-clear (4s timeout) |
276
276
 
package/dist/index.cjs CHANGED
@@ -39,7 +39,6 @@ __export(src_exports, {
39
39
  useChatClient: () => useChatClient,
40
40
  useCommunityClient: () => useCommunityClient,
41
41
  useCommunitySearch: () => useCommunitySearch,
42
- useConversations: () => useConversations,
43
42
  useDashboardClient: () => useDashboardClient,
44
43
  useGameActivity: () => useGameActivity,
45
44
  useLeaderboard: () => useLeaderboard,
@@ -48,6 +47,7 @@ __export(src_exports, {
48
47
  usePlayerStats: () => usePlayerStats,
49
48
  usePost: () => usePost,
50
49
  usePosts: () => usePosts,
50
+ useTickets: () => useTickets,
51
51
  useTopics: () => useTopics,
52
52
  useTyping: () => useTyping
53
53
  });
@@ -102,19 +102,26 @@ function CStarChatProvider({ children, ...config }) {
102
102
  var import_react3 = require("react");
103
103
  function useChat() {
104
104
  const client = useChatClient();
105
- const [isIdentified, setIsIdentified] = (0, import_react3.useState)(false);
105
+ const [isAuthenticated, setIsAuthenticated] = (0, import_react3.useState)(false);
106
+ const [authMode, setAuthMode] = (0, import_react3.useState)(() => client.getAuthMode());
106
107
  const [isRealtimeReady, setIsRealtimeReady] = (0, import_react3.useState)(false);
107
108
  const [error, setError] = (0, import_react3.useState)(null);
109
+ (0, import_react3.useEffect)(() => {
110
+ const current = client.getAuthMode();
111
+ if (current !== authMode) setAuthMode(current);
112
+ }, [client, authMode]);
113
+ const wireRealtime = (0, import_react3.useCallback)(() => {
114
+ client.waitForRealtime().then(() => setIsRealtimeReady(true)).catch(() => {
115
+ });
116
+ }, [client]);
108
117
  const identify = (0, import_react3.useCallback)(
109
118
  async (customer, signature) => {
110
119
  setError(null);
111
120
  try {
112
121
  const result = await client.identify(customer, signature);
113
- setIsIdentified(true);
114
- client.waitForRealtime().then(() => {
115
- setIsRealtimeReady(true);
116
- }).catch(() => {
117
- });
122
+ setIsAuthenticated(true);
123
+ setAuthMode(client.getAuthMode());
124
+ wireRealtime();
118
125
  return result;
119
126
  } catch (err) {
120
127
  const e = err instanceof Error ? err : new Error(String(err));
@@ -122,22 +129,66 @@ function useChat() {
122
129
  throw e;
123
130
  }
124
131
  },
125
- [client]
132
+ [client, wireRealtime]
133
+ );
134
+ const loginWithCredentials = (0, import_react3.useCallback)(
135
+ async (params) => {
136
+ setError(null);
137
+ try {
138
+ const result = await client.loginWithCredentials(params);
139
+ setIsAuthenticated(true);
140
+ setAuthMode(client.getAuthMode());
141
+ wireRealtime();
142
+ return result;
143
+ } catch (err) {
144
+ const e = err instanceof Error ? err : new Error(String(err));
145
+ setError(e);
146
+ throw e;
147
+ }
148
+ },
149
+ [client, wireRealtime]
150
+ );
151
+ const loginWithSession = (0, import_react3.useCallback)(
152
+ async (params) => {
153
+ setError(null);
154
+ try {
155
+ await client.loginWithSession(params);
156
+ setIsAuthenticated(true);
157
+ setAuthMode(client.getAuthMode());
158
+ wireRealtime();
159
+ } catch (err) {
160
+ const e = err instanceof Error ? err : new Error(String(err));
161
+ setError(e);
162
+ throw e;
163
+ }
164
+ },
165
+ [client, wireRealtime]
126
166
  );
127
167
  const disconnect = (0, import_react3.useCallback)(() => {
128
168
  client.disconnect();
129
- setIsIdentified(false);
169
+ setIsAuthenticated(false);
170
+ setAuthMode(null);
130
171
  setIsRealtimeReady(false);
131
172
  setError(null);
132
173
  }, [client]);
133
- return { identify, disconnect, isIdentified, isRealtimeReady, error };
174
+ return {
175
+ identify,
176
+ loginWithCredentials,
177
+ loginWithSession,
178
+ disconnect,
179
+ isIdentified: isAuthenticated,
180
+ isAuthenticated,
181
+ authMode,
182
+ isRealtimeReady,
183
+ error
184
+ };
134
185
  }
135
186
 
136
- // src/chat/useConversations.ts
187
+ // src/chat/useTickets.ts
137
188
  var import_react4 = require("react");
138
- function useConversations() {
189
+ function useTickets() {
139
190
  const client = useChatClient();
140
- const [conversations, setConversations] = (0, import_react4.useState)([]);
191
+ const [tickets, setTickets] = (0, import_react4.useState)([]);
141
192
  const [isLoading, setIsLoading] = (0, import_react4.useState)(true);
142
193
  const [error, setError] = (0, import_react4.useState)(null);
143
194
  const [hasMore, setHasMore] = (0, import_react4.useState)(false);
@@ -146,9 +197,9 @@ function useConversations() {
146
197
  setIsLoading(true);
147
198
  setError(null);
148
199
  try {
149
- const result = await client.conversations.list();
200
+ const result = await client.tickets.list();
150
201
  if (mountedRef.current) {
151
- setConversations(result.conversations);
202
+ setTickets(result.tickets);
152
203
  setHasMore(result.hasMore);
153
204
  }
154
205
  } catch (err) {
@@ -170,15 +221,15 @@ function useConversations() {
170
221
  }, [refresh]);
171
222
  const create = (0, import_react4.useCallback)(
172
223
  async (params) => {
173
- const conversation = await client.conversations.create(params);
224
+ const ticket = await client.tickets.create(params);
174
225
  if (mountedRef.current) {
175
- setConversations((prev) => [conversation, ...prev]);
226
+ setTickets((prev) => [ticket, ...prev]);
176
227
  }
177
- return conversation;
228
+ return ticket;
178
229
  },
179
230
  [client]
180
231
  );
181
- return { conversations, isLoading, error, hasMore, refresh, create };
232
+ return { tickets, isLoading, error, hasMore, refresh, create };
182
233
  }
183
234
 
184
235
  // src/chat/useMessages.ts
@@ -241,7 +292,7 @@ function useMessages(ticketId) {
241
292
  }, [client, ticketId, refresh]);
242
293
  const send = (0, import_react5.useCallback)(
243
294
  async (content) => {
244
- if (!ticketId) throw new Error("No conversation selected");
295
+ if (!ticketId) throw new Error("No ticket selected");
245
296
  const optimistic = {
246
297
  id: `optimistic-${Date.now()}`,
247
298
  content,
@@ -679,10 +730,15 @@ var import_react17 = require("react");
679
730
  var import_jsx_runtime4 = require("react/jsx-runtime");
680
731
  var CStarDashboardContext = (0, import_react17.createContext)(null);
681
732
  function CStarDashboardProvider({ client, children }) {
733
+ if (!client) {
734
+ throw new Error(
735
+ "CStarDashboardProvider requires a `client` prop. Build it server-side with `new CStarClient({ apiKey: process.env.CSTAR_API_KEY, teamId })` and pass via SSR. See https://cstar.help/developers/sdk/react#dashboard"
736
+ );
737
+ }
682
738
  const contextValue = (0, import_react17.useRef)({ client }).current;
683
739
  (0, import_react17.useEffect)(() => {
684
740
  return () => {
685
- client.realtime.disconnect();
741
+ client?.realtime?.disconnect?.();
686
742
  };
687
743
  }, [client]);
688
744
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CStarDashboardContext.Provider, { value: contextValue, children });
@@ -754,7 +810,8 @@ function resolveMutation(client, path) {
754
810
  const methodName = parts[1];
755
811
  const resource = client[resourceName];
756
812
  if (!resource || typeof resource !== "object") return null;
757
- const method = resource[methodName];
813
+ const lookupName = methodName === "delete" ? "del" : methodName;
814
+ const method = resource[lookupName];
758
815
  if (typeof method !== "function") return null;
759
816
  if (methodName === "update") {
760
817
  return (params) => {
@@ -982,7 +1039,6 @@ function useGameActivity() {
982
1039
  useChatClient,
983
1040
  useCommunityClient,
984
1041
  useCommunitySearch,
985
- useConversations,
986
1042
  useDashboardClient,
987
1043
  useGameActivity,
988
1044
  useLeaderboard,
@@ -991,6 +1047,7 @@ function useGameActivity() {
991
1047
  usePlayerStats,
992
1048
  usePost,
993
1049
  usePosts,
1050
+ useTickets,
994
1051
  useTopics,
995
1052
  useTyping
996
1053
  });
package/dist/index.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { ReactNode } from 'react';
3
- import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, Conversation, ConversationCreateParams, WidgetMessage } from '@cstar.help/js/chat';
4
- export { ChatConfig, Conversation, ConversationCreateParams, ConversationListResponse, IdentifyParams, IdentifyResult, TypingPayload, WidgetMessage } from '@cstar.help/js/chat';
3
+ import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, LoginWithCredentialsParams, LoginWithCredentialsResult, LoginWithSessionParams, ChatAuthMode, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
4
+ export { ChatConfig, IdentifyParams, IdentifyResult, Message, Ticket, TicketCreateParams, TicketListResponse, TypingPayload } from '@cstar.help/js/chat';
5
5
  import { LibraryClient, LibraryConfig, Category, LibraryArticle, LibraryArticleListParams } from '@cstar.help/js/library';
6
6
  export { Category, LibraryArticle, LibraryArticleListParams, LibraryConfig, LibrarySearchParams, LibrarySearchResult } from '@cstar.help/js/library';
7
7
  import { CommunityClient, CommunityConfig, CommunityTopic, CommunityPost, CommunityPostListParams, CommunityPostDetail, CommunitySearchResult } from '@cstar.help/js/community';
@@ -36,7 +36,7 @@ interface CStarChatProviderProps extends ChatConfig {
36
36
  * Creates the client on mount and disconnects on unmount.
37
37
  *
38
38
  * ```tsx
39
- * <CStarChatProvider teamSlug="acme" supabaseUrl="..." supabaseAnonKey="...">
39
+ * <CStarChatProvider teamSlug="acme">
40
40
  * <ChatWidget />
41
41
  * </CStarChatProvider>
42
42
  * ```
@@ -46,66 +46,99 @@ declare function CStarChatProvider({ children, ...config }: CStarChatProviderPro
46
46
  interface UseChatReturn {
47
47
  /** Identify a customer with HMAC signature. */
48
48
  identify: (customer: IdentifyParams, signature: string) => Promise<IdentifyResult>;
49
+ /**
50
+ * Log in with cStar's hosted password auth (no separate auth backend
51
+ * required). Updates `isAuthenticated` and `authMode` to `'session'`.
52
+ */
53
+ loginWithCredentials: (params: LoginWithCredentialsParams) => Promise<LoginWithCredentialsResult>;
54
+ /**
55
+ * Use an existing Supabase access token (e.g. forwarded from your own
56
+ * auth). Updates `isAuthenticated` and `authMode` to `'session'`.
57
+ */
58
+ loginWithSession: (params: LoginWithSessionParams) => Promise<void>;
49
59
  /** Disconnect the client and clean up all subscriptions. */
50
60
  disconnect: () => void;
51
- /** Whether a customer has been successfully identified. */
61
+ /**
62
+ * `true` once the client has authenticated through any of the four modes
63
+ * (HMAC `identify`, credentials login, session login, or anonymous). Use
64
+ * this for "is the customer signed in?" branches.
65
+ *
66
+ * @deprecated since 0.8.0 — use `isAuthenticated`. Kept as an alias.
67
+ */
52
68
  isIdentified: boolean;
53
- /** Whether the Supabase Realtime connection is ready. */
69
+ /** Same as `isIdentified` — kept under the more accurate name. */
70
+ isAuthenticated: boolean;
71
+ /**
72
+ * The auth mode the underlying ChatClient is using right now. `null`
73
+ * before any auth call has resolved (or after `disconnect()`).
74
+ */
75
+ authMode: ChatAuthMode | null;
76
+ /** Whether the real-time connection is ready. */
54
77
  isRealtimeReady: boolean;
55
- /** The last error from identify, or null. */
78
+ /** The last error from any auth call, or null. */
56
79
  error: Error | null;
57
80
  }
58
81
  /**
59
- * Core chat hook — manages identity verification and realtime readiness.
82
+ * Core chat hook — manages identity verification (any of four auth modes)
83
+ * and realtime readiness. Closes F-041 / F-044: previously the hook only
84
+ * tracked HMAC `identify()` and ignored `loginWithCredentials` /
85
+ * `loginWithSession`, leaving consumer UI stuck on the unauthenticated
86
+ * branch even after a successful session login.
60
87
  *
61
88
  * ```tsx
62
- * const { identify, disconnect, isIdentified, isRealtimeReady, error } = useChat();
89
+ * const { identify, loginWithCredentials, isAuthenticated, authMode } = useChat();
63
90
  *
64
91
  * await identify(
65
92
  * { externalId: 'usr_123', email: 'jane@co.com', timestamp: Date.now() / 1000 },
66
93
  * hmacSignature
67
94
  * );
95
+ * // OR
96
+ * await loginWithCredentials({ email: 'jane@co.com', password: 'hunter2' });
97
+ *
98
+ * if (isAuthenticated && authMode === 'session') {
99
+ * // show "Sign out" button
100
+ * }
68
101
  * ```
69
102
  */
70
103
  declare function useChat(): UseChatReturn;
71
104
 
72
- interface UseConversationsReturn {
73
- /** List of conversations for the identified customer. */
74
- conversations: Conversation[];
105
+ interface UseTicketsReturn {
106
+ /** List of tickets for the identified customer. */
107
+ tickets: Ticket[];
75
108
  /** Whether the initial fetch is in progress. */
76
109
  isLoading: boolean;
77
110
  /** The last error, or null. */
78
111
  error: Error | null;
79
- /** Whether there are more conversations to load. */
112
+ /** Whether there are more tickets to load. */
80
113
  hasMore: boolean;
81
- /** Re-fetch the conversation list. */
114
+ /** Re-fetch the ticket list. */
82
115
  refresh: () => Promise<void>;
83
- /** Create a new conversation. */
84
- create: (params: ConversationCreateParams) => Promise<Conversation>;
116
+ /** Create a new ticket. */
117
+ create: (params: TicketCreateParams) => Promise<Ticket>;
85
118
  }
86
119
  /**
87
- * Manage the customer's conversation list.
120
+ * Manage the customer's ticket list.
88
121
  *
89
122
  * ```tsx
90
- * const { conversations, isLoading, create, refresh } = useConversations();
123
+ * const { tickets, isLoading, create, refresh } = useTickets();
91
124
  * ```
92
125
  */
93
- declare function useConversations(): UseConversationsReturn;
126
+ declare function useTickets(): UseTicketsReturn;
94
127
 
95
128
  interface UseMessagesReturn {
96
- /** Messages in the conversation, oldest first. */
97
- messages: WidgetMessage[];
129
+ /** Messages on the ticket, oldest first. */
130
+ messages: Message[];
98
131
  /** Whether the initial fetch is in progress. */
99
132
  isLoading: boolean;
100
133
  /** The last error, or null. */
101
134
  error: Error | null;
102
135
  /** Send a message. Optimistically appended, replaced with server response. */
103
- send: (content: string) => Promise<WidgetMessage>;
136
+ send: (content: string) => Promise<Message>;
104
137
  /** Re-fetch messages from the API. */
105
138
  refresh: () => Promise<void>;
106
139
  }
107
140
  /**
108
- * Manage messages for a single conversation with automatic real-time updates.
141
+ * Manage messages for a single ticket with automatic real-time updates.
109
142
  *
110
143
  * ```tsx
111
144
  * const { messages, isLoading, send } = useMessages(ticketId);
@@ -125,7 +158,7 @@ interface UseTypingReturn {
125
158
  sendTyping: (isTyping: boolean) => Promise<void>;
126
159
  }
127
160
  /**
128
- * Track agent typing indicators for a conversation.
161
+ * Track agent typing indicators for a ticket.
129
162
  *
130
163
  * ```tsx
131
164
  * const { typingAgents, sendTyping } = useTyping(ticketId);
@@ -477,4 +510,4 @@ interface UseGameActivityReturn {
477
510
  */
478
511
  declare function useGameActivity(): UseGameActivityReturn;
479
512
 
480
- export { CStarChatContext, CStarChatProvider, type CStarChatProviderProps, CStarCommunityContext, CStarCommunityProvider, type CStarCommunityProviderProps, CStarDashboardProvider, type CStarDashboardProviderProps, CStarLibraryContext, CStarLibraryProvider, type CStarLibraryProviderProps, type TypingAgent, type UseArticleReturn, type UseArticleSearchReturn, type UseArticlesReturn, type UseBossBattleReturn, type UseCStarEventsReturn, type UseCStarMutationReturn, type UseCStarQueryReturn, type UseCategoriesReturn, type UseChatReturn, type UseCommunitySearchReturn, type UseConversationsReturn, type UseGameActivityReturn, type UseLeaderboardReturn, type UseMessagesReturn, type UsePlayerStatsReturn, type UsePostReturn, type UsePostsReturn, type UseTopicsReturn, type UseTypingReturn, useArticle, useArticleSearch, useArticles, useBossBattle, useCStarEvents, useCStarMutation, useCStarQuery, useCategories, useChat, useChatClient, useCommunityClient, useCommunitySearch, useConversations, useDashboardClient, useGameActivity, useLeaderboard, useLibraryClient, useMessages, usePlayerStats, usePost, usePosts, useTopics, useTyping };
513
+ export { CStarChatContext, CStarChatProvider, type CStarChatProviderProps, CStarCommunityContext, CStarCommunityProvider, type CStarCommunityProviderProps, CStarDashboardProvider, type CStarDashboardProviderProps, CStarLibraryContext, CStarLibraryProvider, type CStarLibraryProviderProps, type TypingAgent, type UseArticleReturn, type UseArticleSearchReturn, type UseArticlesReturn, type UseBossBattleReturn, type UseCStarEventsReturn, type UseCStarMutationReturn, type UseCStarQueryReturn, type UseCategoriesReturn, type UseChatReturn, type UseCommunitySearchReturn, type UseGameActivityReturn, type UseLeaderboardReturn, type UseMessagesReturn, type UsePlayerStatsReturn, type UsePostReturn, type UsePostsReturn, type UseTicketsReturn, type UseTopicsReturn, type UseTypingReturn, useArticle, useArticleSearch, useArticles, useBossBattle, useCStarEvents, useCStarMutation, useCStarQuery, useCategories, useChat, useChatClient, useCommunityClient, useCommunitySearch, useDashboardClient, useGameActivity, useLeaderboard, useLibraryClient, useMessages, usePlayerStats, usePost, usePosts, useTickets, useTopics, useTyping };
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react from 'react';
2
2
  import react__default, { ReactNode } from 'react';
3
- import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, Conversation, ConversationCreateParams, WidgetMessage } from '@cstar.help/js/chat';
4
- export { ChatConfig, Conversation, ConversationCreateParams, ConversationListResponse, IdentifyParams, IdentifyResult, TypingPayload, WidgetMessage } from '@cstar.help/js/chat';
3
+ import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, LoginWithCredentialsParams, LoginWithCredentialsResult, LoginWithSessionParams, ChatAuthMode, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
4
+ export { ChatConfig, IdentifyParams, IdentifyResult, Message, Ticket, TicketCreateParams, TicketListResponse, TypingPayload } from '@cstar.help/js/chat';
5
5
  import { LibraryClient, LibraryConfig, Category, LibraryArticle, LibraryArticleListParams } from '@cstar.help/js/library';
6
6
  export { Category, LibraryArticle, LibraryArticleListParams, LibraryConfig, LibrarySearchParams, LibrarySearchResult } from '@cstar.help/js/library';
7
7
  import { CommunityClient, CommunityConfig, CommunityTopic, CommunityPost, CommunityPostListParams, CommunityPostDetail, CommunitySearchResult } from '@cstar.help/js/community';
@@ -36,7 +36,7 @@ interface CStarChatProviderProps extends ChatConfig {
36
36
  * Creates the client on mount and disconnects on unmount.
37
37
  *
38
38
  * ```tsx
39
- * <CStarChatProvider teamSlug="acme" supabaseUrl="..." supabaseAnonKey="...">
39
+ * <CStarChatProvider teamSlug="acme">
40
40
  * <ChatWidget />
41
41
  * </CStarChatProvider>
42
42
  * ```
@@ -46,66 +46,99 @@ declare function CStarChatProvider({ children, ...config }: CStarChatProviderPro
46
46
  interface UseChatReturn {
47
47
  /** Identify a customer with HMAC signature. */
48
48
  identify: (customer: IdentifyParams, signature: string) => Promise<IdentifyResult>;
49
+ /**
50
+ * Log in with cStar's hosted password auth (no separate auth backend
51
+ * required). Updates `isAuthenticated` and `authMode` to `'session'`.
52
+ */
53
+ loginWithCredentials: (params: LoginWithCredentialsParams) => Promise<LoginWithCredentialsResult>;
54
+ /**
55
+ * Use an existing Supabase access token (e.g. forwarded from your own
56
+ * auth). Updates `isAuthenticated` and `authMode` to `'session'`.
57
+ */
58
+ loginWithSession: (params: LoginWithSessionParams) => Promise<void>;
49
59
  /** Disconnect the client and clean up all subscriptions. */
50
60
  disconnect: () => void;
51
- /** Whether a customer has been successfully identified. */
61
+ /**
62
+ * `true` once the client has authenticated through any of the four modes
63
+ * (HMAC `identify`, credentials login, session login, or anonymous). Use
64
+ * this for "is the customer signed in?" branches.
65
+ *
66
+ * @deprecated since 0.8.0 — use `isAuthenticated`. Kept as an alias.
67
+ */
52
68
  isIdentified: boolean;
53
- /** Whether the Supabase Realtime connection is ready. */
69
+ /** Same as `isIdentified` — kept under the more accurate name. */
70
+ isAuthenticated: boolean;
71
+ /**
72
+ * The auth mode the underlying ChatClient is using right now. `null`
73
+ * before any auth call has resolved (or after `disconnect()`).
74
+ */
75
+ authMode: ChatAuthMode | null;
76
+ /** Whether the real-time connection is ready. */
54
77
  isRealtimeReady: boolean;
55
- /** The last error from identify, or null. */
78
+ /** The last error from any auth call, or null. */
56
79
  error: Error | null;
57
80
  }
58
81
  /**
59
- * Core chat hook — manages identity verification and realtime readiness.
82
+ * Core chat hook — manages identity verification (any of four auth modes)
83
+ * and realtime readiness. Closes F-041 / F-044: previously the hook only
84
+ * tracked HMAC `identify()` and ignored `loginWithCredentials` /
85
+ * `loginWithSession`, leaving consumer UI stuck on the unauthenticated
86
+ * branch even after a successful session login.
60
87
  *
61
88
  * ```tsx
62
- * const { identify, disconnect, isIdentified, isRealtimeReady, error } = useChat();
89
+ * const { identify, loginWithCredentials, isAuthenticated, authMode } = useChat();
63
90
  *
64
91
  * await identify(
65
92
  * { externalId: 'usr_123', email: 'jane@co.com', timestamp: Date.now() / 1000 },
66
93
  * hmacSignature
67
94
  * );
95
+ * // OR
96
+ * await loginWithCredentials({ email: 'jane@co.com', password: 'hunter2' });
97
+ *
98
+ * if (isAuthenticated && authMode === 'session') {
99
+ * // show "Sign out" button
100
+ * }
68
101
  * ```
69
102
  */
70
103
  declare function useChat(): UseChatReturn;
71
104
 
72
- interface UseConversationsReturn {
73
- /** List of conversations for the identified customer. */
74
- conversations: Conversation[];
105
+ interface UseTicketsReturn {
106
+ /** List of tickets for the identified customer. */
107
+ tickets: Ticket[];
75
108
  /** Whether the initial fetch is in progress. */
76
109
  isLoading: boolean;
77
110
  /** The last error, or null. */
78
111
  error: Error | null;
79
- /** Whether there are more conversations to load. */
112
+ /** Whether there are more tickets to load. */
80
113
  hasMore: boolean;
81
- /** Re-fetch the conversation list. */
114
+ /** Re-fetch the ticket list. */
82
115
  refresh: () => Promise<void>;
83
- /** Create a new conversation. */
84
- create: (params: ConversationCreateParams) => Promise<Conversation>;
116
+ /** Create a new ticket. */
117
+ create: (params: TicketCreateParams) => Promise<Ticket>;
85
118
  }
86
119
  /**
87
- * Manage the customer's conversation list.
120
+ * Manage the customer's ticket list.
88
121
  *
89
122
  * ```tsx
90
- * const { conversations, isLoading, create, refresh } = useConversations();
123
+ * const { tickets, isLoading, create, refresh } = useTickets();
91
124
  * ```
92
125
  */
93
- declare function useConversations(): UseConversationsReturn;
126
+ declare function useTickets(): UseTicketsReturn;
94
127
 
95
128
  interface UseMessagesReturn {
96
- /** Messages in the conversation, oldest first. */
97
- messages: WidgetMessage[];
129
+ /** Messages on the ticket, oldest first. */
130
+ messages: Message[];
98
131
  /** Whether the initial fetch is in progress. */
99
132
  isLoading: boolean;
100
133
  /** The last error, or null. */
101
134
  error: Error | null;
102
135
  /** Send a message. Optimistically appended, replaced with server response. */
103
- send: (content: string) => Promise<WidgetMessage>;
136
+ send: (content: string) => Promise<Message>;
104
137
  /** Re-fetch messages from the API. */
105
138
  refresh: () => Promise<void>;
106
139
  }
107
140
  /**
108
- * Manage messages for a single conversation with automatic real-time updates.
141
+ * Manage messages for a single ticket with automatic real-time updates.
109
142
  *
110
143
  * ```tsx
111
144
  * const { messages, isLoading, send } = useMessages(ticketId);
@@ -125,7 +158,7 @@ interface UseTypingReturn {
125
158
  sendTyping: (isTyping: boolean) => Promise<void>;
126
159
  }
127
160
  /**
128
- * Track agent typing indicators for a conversation.
161
+ * Track agent typing indicators for a ticket.
129
162
  *
130
163
  * ```tsx
131
164
  * const { typingAgents, sendTyping } = useTyping(ticketId);
@@ -477,4 +510,4 @@ interface UseGameActivityReturn {
477
510
  */
478
511
  declare function useGameActivity(): UseGameActivityReturn;
479
512
 
480
- export { CStarChatContext, CStarChatProvider, type CStarChatProviderProps, CStarCommunityContext, CStarCommunityProvider, type CStarCommunityProviderProps, CStarDashboardProvider, type CStarDashboardProviderProps, CStarLibraryContext, CStarLibraryProvider, type CStarLibraryProviderProps, type TypingAgent, type UseArticleReturn, type UseArticleSearchReturn, type UseArticlesReturn, type UseBossBattleReturn, type UseCStarEventsReturn, type UseCStarMutationReturn, type UseCStarQueryReturn, type UseCategoriesReturn, type UseChatReturn, type UseCommunitySearchReturn, type UseConversationsReturn, type UseGameActivityReturn, type UseLeaderboardReturn, type UseMessagesReturn, type UsePlayerStatsReturn, type UsePostReturn, type UsePostsReturn, type UseTopicsReturn, type UseTypingReturn, useArticle, useArticleSearch, useArticles, useBossBattle, useCStarEvents, useCStarMutation, useCStarQuery, useCategories, useChat, useChatClient, useCommunityClient, useCommunitySearch, useConversations, useDashboardClient, useGameActivity, useLeaderboard, useLibraryClient, useMessages, usePlayerStats, usePost, usePosts, useTopics, useTyping };
513
+ export { CStarChatContext, CStarChatProvider, type CStarChatProviderProps, CStarCommunityContext, CStarCommunityProvider, type CStarCommunityProviderProps, CStarDashboardProvider, type CStarDashboardProviderProps, CStarLibraryContext, CStarLibraryProvider, type CStarLibraryProviderProps, type TypingAgent, type UseArticleReturn, type UseArticleSearchReturn, type UseArticlesReturn, type UseBossBattleReturn, type UseCStarEventsReturn, type UseCStarMutationReturn, type UseCStarQueryReturn, type UseCategoriesReturn, type UseChatReturn, type UseCommunitySearchReturn, type UseGameActivityReturn, type UseLeaderboardReturn, type UseMessagesReturn, type UsePlayerStatsReturn, type UsePostReturn, type UsePostsReturn, type UseTicketsReturn, type UseTopicsReturn, type UseTypingReturn, useArticle, useArticleSearch, useArticles, useBossBattle, useCStarEvents, useCStarMutation, useCStarQuery, useCategories, useChat, useChatClient, useCommunityClient, useCommunitySearch, useDashboardClient, useGameActivity, useLeaderboard, useLibraryClient, useMessages, usePlayerStats, usePost, usePosts, useTickets, useTopics, useTyping };
package/dist/index.js CHANGED
@@ -44,22 +44,29 @@ function CStarChatProvider({ children, ...config }) {
44
44
  }
45
45
 
46
46
  // src/chat/useChat.ts
47
- import { useState, useCallback } from "react";
47
+ import { useState, useCallback, useEffect as useEffect2 } from "react";
48
48
  function useChat() {
49
49
  const client = useChatClient();
50
- const [isIdentified, setIsIdentified] = useState(false);
50
+ const [isAuthenticated, setIsAuthenticated] = useState(false);
51
+ const [authMode, setAuthMode] = useState(() => client.getAuthMode());
51
52
  const [isRealtimeReady, setIsRealtimeReady] = useState(false);
52
53
  const [error, setError] = useState(null);
54
+ useEffect2(() => {
55
+ const current = client.getAuthMode();
56
+ if (current !== authMode) setAuthMode(current);
57
+ }, [client, authMode]);
58
+ const wireRealtime = useCallback(() => {
59
+ client.waitForRealtime().then(() => setIsRealtimeReady(true)).catch(() => {
60
+ });
61
+ }, [client]);
53
62
  const identify = useCallback(
54
63
  async (customer, signature) => {
55
64
  setError(null);
56
65
  try {
57
66
  const result = await client.identify(customer, signature);
58
- setIsIdentified(true);
59
- client.waitForRealtime().then(() => {
60
- setIsRealtimeReady(true);
61
- }).catch(() => {
62
- });
67
+ setIsAuthenticated(true);
68
+ setAuthMode(client.getAuthMode());
69
+ wireRealtime();
63
70
  return result;
64
71
  } catch (err) {
65
72
  const e = err instanceof Error ? err : new Error(String(err));
@@ -67,22 +74,66 @@ function useChat() {
67
74
  throw e;
68
75
  }
69
76
  },
70
- [client]
77
+ [client, wireRealtime]
78
+ );
79
+ const loginWithCredentials = useCallback(
80
+ async (params) => {
81
+ setError(null);
82
+ try {
83
+ const result = await client.loginWithCredentials(params);
84
+ setIsAuthenticated(true);
85
+ setAuthMode(client.getAuthMode());
86
+ wireRealtime();
87
+ return result;
88
+ } catch (err) {
89
+ const e = err instanceof Error ? err : new Error(String(err));
90
+ setError(e);
91
+ throw e;
92
+ }
93
+ },
94
+ [client, wireRealtime]
95
+ );
96
+ const loginWithSession = useCallback(
97
+ async (params) => {
98
+ setError(null);
99
+ try {
100
+ await client.loginWithSession(params);
101
+ setIsAuthenticated(true);
102
+ setAuthMode(client.getAuthMode());
103
+ wireRealtime();
104
+ } catch (err) {
105
+ const e = err instanceof Error ? err : new Error(String(err));
106
+ setError(e);
107
+ throw e;
108
+ }
109
+ },
110
+ [client, wireRealtime]
71
111
  );
72
112
  const disconnect = useCallback(() => {
73
113
  client.disconnect();
74
- setIsIdentified(false);
114
+ setIsAuthenticated(false);
115
+ setAuthMode(null);
75
116
  setIsRealtimeReady(false);
76
117
  setError(null);
77
118
  }, [client]);
78
- return { identify, disconnect, isIdentified, isRealtimeReady, error };
119
+ return {
120
+ identify,
121
+ loginWithCredentials,
122
+ loginWithSession,
123
+ disconnect,
124
+ isIdentified: isAuthenticated,
125
+ isAuthenticated,
126
+ authMode,
127
+ isRealtimeReady,
128
+ error
129
+ };
79
130
  }
80
131
 
81
- // src/chat/useConversations.ts
82
- import { useState as useState2, useEffect as useEffect2, useCallback as useCallback2, useRef as useRef2 } from "react";
83
- function useConversations() {
132
+ // src/chat/useTickets.ts
133
+ import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef2 } from "react";
134
+ function useTickets() {
84
135
  const client = useChatClient();
85
- const [conversations, setConversations] = useState2([]);
136
+ const [tickets, setTickets] = useState2([]);
86
137
  const [isLoading, setIsLoading] = useState2(true);
87
138
  const [error, setError] = useState2(null);
88
139
  const [hasMore, setHasMore] = useState2(false);
@@ -91,9 +142,9 @@ function useConversations() {
91
142
  setIsLoading(true);
92
143
  setError(null);
93
144
  try {
94
- const result = await client.conversations.list();
145
+ const result = await client.tickets.list();
95
146
  if (mountedRef.current) {
96
- setConversations(result.conversations);
147
+ setTickets(result.tickets);
97
148
  setHasMore(result.hasMore);
98
149
  }
99
150
  } catch (err) {
@@ -106,7 +157,7 @@ function useConversations() {
106
157
  }
107
158
  }
108
159
  }, [client]);
109
- useEffect2(() => {
160
+ useEffect3(() => {
110
161
  mountedRef.current = true;
111
162
  refresh();
112
163
  return () => {
@@ -115,19 +166,19 @@ function useConversations() {
115
166
  }, [refresh]);
116
167
  const create = useCallback2(
117
168
  async (params) => {
118
- const conversation = await client.conversations.create(params);
169
+ const ticket = await client.tickets.create(params);
119
170
  if (mountedRef.current) {
120
- setConversations((prev) => [conversation, ...prev]);
171
+ setTickets((prev) => [ticket, ...prev]);
121
172
  }
122
- return conversation;
173
+ return ticket;
123
174
  },
124
175
  [client]
125
176
  );
126
- return { conversations, isLoading, error, hasMore, refresh, create };
177
+ return { tickets, isLoading, error, hasMore, refresh, create };
127
178
  }
128
179
 
129
180
  // src/chat/useMessages.ts
130
- import { useState as useState3, useEffect as useEffect3, useCallback as useCallback3, useRef as useRef3 } from "react";
181
+ import { useState as useState3, useEffect as useEffect4, useCallback as useCallback3, useRef as useRef3 } from "react";
131
182
  function useMessages(ticketId) {
132
183
  const client = useChatClient();
133
184
  const [messages, setMessages] = useState3([]);
@@ -155,7 +206,7 @@ function useMessages(ticketId) {
155
206
  }
156
207
  }
157
208
  }, [client, ticketId]);
158
- useEffect3(() => {
209
+ useEffect4(() => {
159
210
  mountedRef.current = true;
160
211
  if (!ticketId) {
161
212
  setMessages([]);
@@ -186,7 +237,7 @@ function useMessages(ticketId) {
186
237
  }, [client, ticketId, refresh]);
187
238
  const send = useCallback3(
188
239
  async (content) => {
189
- if (!ticketId) throw new Error("No conversation selected");
240
+ if (!ticketId) throw new Error("No ticket selected");
190
241
  const optimistic = {
191
242
  id: `optimistic-${Date.now()}`,
192
243
  content,
@@ -213,14 +264,14 @@ function useMessages(ticketId) {
213
264
  }
214
265
 
215
266
  // src/chat/useTyping.ts
216
- import { useState as useState4, useEffect as useEffect4, useCallback as useCallback4, useRef as useRef4 } from "react";
267
+ import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4, useRef as useRef4 } from "react";
217
268
  var TYPING_TIMEOUT = 4e3;
218
269
  function useTyping(ticketId) {
219
270
  const client = useChatClient();
220
271
  const [typingAgents, setTypingAgents] = useState4([]);
221
272
  const timersRef = useRef4(/* @__PURE__ */ new Map());
222
273
  const mountedRef = useRef4(true);
223
- useEffect4(() => {
274
+ useEffect5(() => {
224
275
  mountedRef.current = true;
225
276
  if (!ticketId) {
226
277
  setTypingAgents([]);
@@ -280,7 +331,7 @@ function CStarLibraryProvider({ children, ...config }) {
280
331
  }
281
332
 
282
333
  // src/library/useCategories.ts
283
- import { useState as useState5, useEffect as useEffect5, useCallback as useCallback5, useRef as useRef6 } from "react";
334
+ import { useState as useState5, useEffect as useEffect6, useCallback as useCallback5, useRef as useRef6 } from "react";
284
335
  function useCategories() {
285
336
  const client = useLibraryClient();
286
337
  const [categories, setCategories] = useState5([]);
@@ -305,7 +356,7 @@ function useCategories() {
305
356
  }
306
357
  }
307
358
  }, [client]);
308
- useEffect5(() => {
359
+ useEffect6(() => {
309
360
  mountedRef.current = true;
310
361
  refresh();
311
362
  return () => {
@@ -316,7 +367,7 @@ function useCategories() {
316
367
  }
317
368
 
318
369
  // src/library/useArticles.ts
319
- import { useState as useState6, useEffect as useEffect6, useCallback as useCallback6, useRef as useRef7 } from "react";
370
+ import { useState as useState6, useEffect as useEffect7, useCallback as useCallback6, useRef as useRef7 } from "react";
320
371
  function useArticles(params) {
321
372
  const client = useLibraryClient();
322
373
  const [articles, setArticles] = useState6([]);
@@ -344,7 +395,7 @@ function useArticles(params) {
344
395
  }
345
396
  }
346
397
  }, [client, categorySlug, limit, offset]);
347
- useEffect6(() => {
398
+ useEffect7(() => {
348
399
  mountedRef.current = true;
349
400
  refresh();
350
401
  return () => {
@@ -355,7 +406,7 @@ function useArticles(params) {
355
406
  }
356
407
 
357
408
  // src/library/useArticle.ts
358
- import { useState as useState7, useEffect as useEffect7, useCallback as useCallback7, useRef as useRef8 } from "react";
409
+ import { useState as useState7, useEffect as useEffect8, useCallback as useCallback7, useRef as useRef8 } from "react";
359
410
  function useArticle(slug) {
360
411
  const client = useLibraryClient();
361
412
  const [article, setArticle] = useState7(null);
@@ -388,7 +439,7 @@ function useArticle(slug) {
388
439
  } catch {
389
440
  }
390
441
  }, [client, slug]);
391
- useEffect7(() => {
442
+ useEffect8(() => {
392
443
  mountedRef.current = true;
393
444
  if (!slug) {
394
445
  setArticle(null);
@@ -404,7 +455,7 @@ function useArticle(slug) {
404
455
  }
405
456
 
406
457
  // src/library/useArticleSearch.ts
407
- import { useState as useState8, useEffect as useEffect8, useRef as useRef9 } from "react";
458
+ import { useState as useState8, useEffect as useEffect9, useRef as useRef9 } from "react";
408
459
  var DEBOUNCE_MS = 300;
409
460
  function useArticleSearch(query) {
410
461
  const client = useLibraryClient();
@@ -413,7 +464,7 @@ function useArticleSearch(query) {
413
464
  const [isLoading, setIsLoading] = useState8(false);
414
465
  const [error, setError] = useState8(null);
415
466
  const mountedRef = useRef9(true);
416
- useEffect8(() => {
467
+ useEffect9(() => {
417
468
  mountedRef.current = true;
418
469
  const trimmed = query.trim();
419
470
  if (!trimmed) {
@@ -463,7 +514,7 @@ function CStarCommunityProvider({ children, ...config }) {
463
514
  }
464
515
 
465
516
  // src/community/useTopics.ts
466
- import { useState as useState9, useEffect as useEffect9, useCallback as useCallback8, useRef as useRef11 } from "react";
517
+ import { useState as useState9, useEffect as useEffect10, useCallback as useCallback8, useRef as useRef11 } from "react";
467
518
  function useTopics() {
468
519
  const client = useCommunityClient();
469
520
  const [topics, setTopics] = useState9([]);
@@ -488,7 +539,7 @@ function useTopics() {
488
539
  }
489
540
  }
490
541
  }, [client]);
491
- useEffect9(() => {
542
+ useEffect10(() => {
492
543
  mountedRef.current = true;
493
544
  refresh();
494
545
  return () => {
@@ -499,7 +550,7 @@ function useTopics() {
499
550
  }
500
551
 
501
552
  // src/community/usePosts.ts
502
- import { useState as useState10, useEffect as useEffect10, useCallback as useCallback9, useRef as useRef12 } from "react";
553
+ import { useState as useState10, useEffect as useEffect11, useCallback as useCallback9, useRef as useRef12 } from "react";
503
554
  function usePosts(params) {
504
555
  const client = useCommunityClient();
505
556
  const [posts, setPosts] = useState10([]);
@@ -531,7 +582,7 @@ function usePosts(params) {
531
582
  }
532
583
  }
533
584
  }, [client, topicSlug, status, sort, limit, offset]);
534
- useEffect10(() => {
585
+ useEffect11(() => {
535
586
  mountedRef.current = true;
536
587
  refresh();
537
588
  return () => {
@@ -542,7 +593,7 @@ function usePosts(params) {
542
593
  }
543
594
 
544
595
  // src/community/usePost.ts
545
- import { useState as useState11, useEffect as useEffect11, useCallback as useCallback10, useRef as useRef13 } from "react";
596
+ import { useState as useState11, useEffect as useEffect12, useCallback as useCallback10, useRef as useRef13 } from "react";
546
597
  function usePost(slug) {
547
598
  const client = useCommunityClient();
548
599
  const [data, setData] = useState11(null);
@@ -567,7 +618,7 @@ function usePost(slug) {
567
618
  }
568
619
  }
569
620
  }, [client, slug]);
570
- useEffect11(() => {
621
+ useEffect12(() => {
571
622
  mountedRef.current = true;
572
623
  refresh();
573
624
  return () => {
@@ -578,14 +629,14 @@ function usePost(slug) {
578
629
  }
579
630
 
580
631
  // src/community/useCommunitySearch.ts
581
- import { useState as useState12, useEffect as useEffect12, useCallback as useCallback11, useRef as useRef14 } from "react";
632
+ import { useState as useState12, useEffect as useEffect13, useCallback as useCallback11, useRef as useRef14 } from "react";
582
633
  function useCommunitySearch() {
583
634
  const client = useCommunityClient();
584
635
  const [results, setResults] = useState12(null);
585
636
  const [isLoading, setIsLoading] = useState12(false);
586
637
  const [error, setError] = useState12(null);
587
638
  const mountedRef = useRef14(true);
588
- useEffect12(() => {
639
+ useEffect13(() => {
589
640
  mountedRef.current = true;
590
641
  return () => {
591
642
  mountedRef.current = false;
@@ -620,14 +671,19 @@ function useCommunitySearch() {
620
671
  }
621
672
 
622
673
  // src/dashboard/CStarDashboardProvider.tsx
623
- import { createContext as createContext2, useContext as useContext2, useEffect as useEffect13, useRef as useRef15 } from "react";
674
+ import { createContext as createContext2, useContext as useContext2, useEffect as useEffect14, useRef as useRef15 } from "react";
624
675
  import { jsx as jsx4 } from "react/jsx-runtime";
625
676
  var CStarDashboardContext = createContext2(null);
626
677
  function CStarDashboardProvider({ client, children }) {
678
+ if (!client) {
679
+ throw new Error(
680
+ "CStarDashboardProvider requires a `client` prop. Build it server-side with `new CStarClient({ apiKey: process.env.CSTAR_API_KEY, teamId })` and pass via SSR. See https://cstar.help/developers/sdk/react#dashboard"
681
+ );
682
+ }
627
683
  const contextValue = useRef15({ client }).current;
628
- useEffect13(() => {
684
+ useEffect14(() => {
629
685
  return () => {
630
- client.realtime.disconnect();
686
+ client?.realtime?.disconnect?.();
631
687
  };
632
688
  }, [client]);
633
689
  return /* @__PURE__ */ jsx4(CStarDashboardContext.Provider, { value: contextValue, children });
@@ -641,7 +697,7 @@ function useDashboardClient() {
641
697
  }
642
698
 
643
699
  // src/dashboard/useCStarQuery.ts
644
- import { useState as useState13, useEffect as useEffect14, useRef as useRef16, useCallback as useCallback12 } from "react";
700
+ import { useState as useState13, useEffect as useEffect15, useRef as useRef16, useCallback as useCallback12 } from "react";
645
701
  function resolveResource(client, path) {
646
702
  const parts = path.split(".");
647
703
  if (parts.length < 2 || parts[1] !== "list") return null;
@@ -659,7 +715,7 @@ function useCStarQuery(resource, params) {
659
715
  const [error, setError] = useState13(null);
660
716
  const subscriptionRef = useRef16(null);
661
717
  const paramsKey = params ? JSON.stringify(params) : "";
662
- useEffect14(() => {
718
+ useEffect15(() => {
663
719
  const resolved = resolveResource(client, resource);
664
720
  if (!resolved) {
665
721
  setError(new Error(`Invalid resource path: ${resource}. Expected format: 'tickets.list'`));
@@ -699,7 +755,8 @@ function resolveMutation(client, path) {
699
755
  const methodName = parts[1];
700
756
  const resource = client[resourceName];
701
757
  if (!resource || typeof resource !== "object") return null;
702
- const method = resource[methodName];
758
+ const lookupName = methodName === "delete" ? "del" : methodName;
759
+ const method = resource[lookupName];
703
760
  if (typeof method !== "function") return null;
704
761
  if (methodName === "update") {
705
762
  return (params) => {
@@ -745,14 +802,14 @@ function useCStarMutation(resource) {
745
802
  }
746
803
 
747
804
  // src/dashboard/useCStarEvents.ts
748
- import { useState as useState15, useEffect as useEffect15 } from "react";
805
+ import { useState as useState15, useEffect as useEffect16 } from "react";
749
806
  var MAX_EVENTS = 100;
750
807
  function useCStarEvents(types) {
751
808
  const client = useDashboardClient();
752
809
  const [events, setEvents] = useState15([]);
753
810
  const [connected, setConnected] = useState15(false);
754
811
  const typesKey = types ? types.join(",") : "";
755
- useEffect15(() => {
812
+ useEffect16(() => {
756
813
  const realtime = client.realtime;
757
814
  const handler = (event) => {
758
815
  if (types && types.length > 0) {
@@ -784,14 +841,14 @@ function useCStarEvents(types) {
784
841
  }
785
842
 
786
843
  // src/dashboard/useBossBattle.ts
787
- import { useState as useState16, useEffect as useEffect16, useRef as useRef17, useCallback as useCallback14 } from "react";
844
+ import { useState as useState16, useEffect as useEffect17, useRef as useRef17, useCallback as useCallback14 } from "react";
788
845
  function useBossBattle() {
789
846
  const client = useDashboardClient();
790
847
  const [boss, setBoss] = useState16(null);
791
848
  const [loading, setLoading] = useState16(true);
792
849
  const [error, setError] = useState16(null);
793
850
  const subRef = useRef17(null);
794
- useEffect16(() => {
851
+ useEffect17(() => {
795
852
  const sub = client.game.subscribeBoss(client.realtime);
796
853
  subRef.current = sub;
797
854
  sub.on("change", (data) => {
@@ -815,14 +872,14 @@ function useBossBattle() {
815
872
  }
816
873
 
817
874
  // src/dashboard/usePlayerStats.ts
818
- import { useState as useState17, useEffect as useEffect17, useRef as useRef18, useCallback as useCallback15 } from "react";
875
+ import { useState as useState17, useEffect as useEffect18, useRef as useRef18, useCallback as useCallback15 } from "react";
819
876
  function usePlayerStats(memberId) {
820
877
  const client = useDashboardClient();
821
878
  const [player, setPlayer] = useState17(null);
822
879
  const [loading, setLoading] = useState17(true);
823
880
  const [error, setError] = useState17(null);
824
881
  const subRef = useRef18(null);
825
- useEffect17(() => {
882
+ useEffect18(() => {
826
883
  const sub = client.game.subscribePlayer(client.realtime, memberId);
827
884
  subRef.current = sub;
828
885
  sub.on("change", (data) => {
@@ -846,14 +903,14 @@ function usePlayerStats(memberId) {
846
903
  }
847
904
 
848
905
  // src/dashboard/useLeaderboard.ts
849
- import { useState as useState18, useEffect as useEffect18, useRef as useRef19, useCallback as useCallback16 } from "react";
906
+ import { useState as useState18, useEffect as useEffect19, useRef as useRef19, useCallback as useCallback16 } from "react";
850
907
  function useLeaderboard(period) {
851
908
  const client = useDashboardClient();
852
909
  const [entries, setEntries] = useState18([]);
853
910
  const [loading, setLoading] = useState18(true);
854
911
  const [error, setError] = useState18(null);
855
912
  const subRef = useRef19(null);
856
- useEffect18(() => {
913
+ useEffect19(() => {
857
914
  const sub = client.game.subscribeLeaderboard(client.realtime, period ? { period } : void 0);
858
915
  subRef.current = sub;
859
916
  sub.on("change", (data) => {
@@ -877,14 +934,14 @@ function useLeaderboard(period) {
877
934
  }
878
935
 
879
936
  // src/dashboard/useGameActivity.ts
880
- import { useState as useState19, useEffect as useEffect19, useRef as useRef20, useCallback as useCallback17 } from "react";
937
+ import { useState as useState19, useEffect as useEffect20, useRef as useRef20, useCallback as useCallback17 } from "react";
881
938
  function useGameActivity() {
882
939
  const client = useDashboardClient();
883
940
  const [events, setEvents] = useState19([]);
884
941
  const [loading, setLoading] = useState19(true);
885
942
  const [error, setError] = useState19(null);
886
943
  const subRef = useRef20(null);
887
- useEffect19(() => {
944
+ useEffect20(() => {
888
945
  const sub = client.game.subscribeActivity(client.realtime);
889
946
  subRef.current = sub;
890
947
  sub.on("change", (data) => {
@@ -926,7 +983,6 @@ export {
926
983
  useChatClient,
927
984
  useCommunityClient,
928
985
  useCommunitySearch,
929
- useConversations,
930
986
  useDashboardClient,
931
987
  useGameActivity,
932
988
  useLeaderboard,
@@ -935,6 +991,7 @@ export {
935
991
  usePlayerStats,
936
992
  usePost,
937
993
  usePosts,
994
+ useTickets,
938
995
  useTopics,
939
996
  useTyping
940
997
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cstar.help/react",
3
- "version": "0.6.1",
3
+ "version": "0.8.0",
4
4
  "description": "React hooks for the cStar customer support platform",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -30,7 +30,7 @@
30
30
  },
31
31
  "peerDependencies": {
32
32
  "react": ">=18.0.0",
33
- "@cstar.help/js": ">=0.2.0"
33
+ "@cstar.help/js": ">=0.11.0"
34
34
  },
35
35
  "devDependencies": {
36
36
  "react": "^18.3.1",