@cstar.help/react 0.7.0 → 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/dist/index.cjs +66 -10
- package/dist/index.d.cts +38 -5
- package/dist/index.d.ts +38 -5
- package/dist/index.js +103 -47
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -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 [
|
|
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
|
-
|
|
114
|
-
client.
|
|
115
|
-
|
|
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,15 +129,59 @@ 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
|
-
|
|
169
|
+
setIsAuthenticated(false);
|
|
170
|
+
setAuthMode(null);
|
|
130
171
|
setIsRealtimeReady(false);
|
|
131
172
|
setError(null);
|
|
132
173
|
}, [client]);
|
|
133
|
-
return {
|
|
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
187
|
// src/chat/useTickets.ts
|
|
@@ -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
|
|
741
|
+
client?.realtime?.disconnect?.();
|
|
686
742
|
};
|
|
687
743
|
}, [client]);
|
|
688
744
|
return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(CStarDashboardContext.Provider, { value: contextValue, children });
|
package/dist/index.d.cts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode } from 'react';
|
|
3
|
-
import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
|
|
3
|
+
import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, LoginWithCredentialsParams, LoginWithCredentialsResult, LoginWithSessionParams, ChatAuthMode, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
|
|
4
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';
|
|
@@ -46,25 +46,58 @@ 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
|
-
/**
|
|
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;
|
|
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;
|
|
53
76
|
/** Whether the real-time connection is ready. */
|
|
54
77
|
isRealtimeReady: boolean;
|
|
55
|
-
/** The last error from
|
|
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
|
|
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,
|
|
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;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import * as react from 'react';
|
|
2
2
|
import react__default, { ReactNode } from 'react';
|
|
3
|
-
import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
|
|
3
|
+
import { ChatClient, ChatConfig, IdentifyParams, IdentifyResult, LoginWithCredentialsParams, LoginWithCredentialsResult, LoginWithSessionParams, ChatAuthMode, Ticket, TicketCreateParams, Message } from '@cstar.help/js/chat';
|
|
4
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';
|
|
@@ -46,25 +46,58 @@ 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
|
-
/**
|
|
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;
|
|
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;
|
|
53
76
|
/** Whether the real-time connection is ready. */
|
|
54
77
|
isRealtimeReady: boolean;
|
|
55
|
-
/** The last error from
|
|
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
|
|
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,
|
|
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;
|
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 [
|
|
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
|
-
|
|
59
|
-
client.
|
|
60
|
-
|
|
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,19 +74,63 @@ 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
|
-
|
|
114
|
+
setIsAuthenticated(false);
|
|
115
|
+
setAuthMode(null);
|
|
75
116
|
setIsRealtimeReady(false);
|
|
76
117
|
setError(null);
|
|
77
118
|
}, [client]);
|
|
78
|
-
return {
|
|
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
132
|
// src/chat/useTickets.ts
|
|
82
|
-
import { useState as useState2, useEffect as
|
|
133
|
+
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef2 } from "react";
|
|
83
134
|
function useTickets() {
|
|
84
135
|
const client = useChatClient();
|
|
85
136
|
const [tickets, setTickets] = useState2([]);
|
|
@@ -106,7 +157,7 @@ function useTickets() {
|
|
|
106
157
|
}
|
|
107
158
|
}
|
|
108
159
|
}, [client]);
|
|
109
|
-
|
|
160
|
+
useEffect3(() => {
|
|
110
161
|
mountedRef.current = true;
|
|
111
162
|
refresh();
|
|
112
163
|
return () => {
|
|
@@ -127,7 +178,7 @@ function useTickets() {
|
|
|
127
178
|
}
|
|
128
179
|
|
|
129
180
|
// src/chat/useMessages.ts
|
|
130
|
-
import { useState as useState3, useEffect as
|
|
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
|
-
|
|
209
|
+
useEffect4(() => {
|
|
159
210
|
mountedRef.current = true;
|
|
160
211
|
if (!ticketId) {
|
|
161
212
|
setMessages([]);
|
|
@@ -213,14 +264,14 @@ function useMessages(ticketId) {
|
|
|
213
264
|
}
|
|
214
265
|
|
|
215
266
|
// src/chat/useTyping.ts
|
|
216
|
-
import { useState as useState4, useEffect as
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
684
|
+
useEffect14(() => {
|
|
629
685
|
return () => {
|
|
630
|
-
client
|
|
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
|
|
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
|
-
|
|
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'`));
|
|
@@ -746,14 +802,14 @@ function useCStarMutation(resource) {
|
|
|
746
802
|
}
|
|
747
803
|
|
|
748
804
|
// src/dashboard/useCStarEvents.ts
|
|
749
|
-
import { useState as useState15, useEffect as
|
|
805
|
+
import { useState as useState15, useEffect as useEffect16 } from "react";
|
|
750
806
|
var MAX_EVENTS = 100;
|
|
751
807
|
function useCStarEvents(types) {
|
|
752
808
|
const client = useDashboardClient();
|
|
753
809
|
const [events, setEvents] = useState15([]);
|
|
754
810
|
const [connected, setConnected] = useState15(false);
|
|
755
811
|
const typesKey = types ? types.join(",") : "";
|
|
756
|
-
|
|
812
|
+
useEffect16(() => {
|
|
757
813
|
const realtime = client.realtime;
|
|
758
814
|
const handler = (event) => {
|
|
759
815
|
if (types && types.length > 0) {
|
|
@@ -785,14 +841,14 @@ function useCStarEvents(types) {
|
|
|
785
841
|
}
|
|
786
842
|
|
|
787
843
|
// src/dashboard/useBossBattle.ts
|
|
788
|
-
import { useState as useState16, useEffect as
|
|
844
|
+
import { useState as useState16, useEffect as useEffect17, useRef as useRef17, useCallback as useCallback14 } from "react";
|
|
789
845
|
function useBossBattle() {
|
|
790
846
|
const client = useDashboardClient();
|
|
791
847
|
const [boss, setBoss] = useState16(null);
|
|
792
848
|
const [loading, setLoading] = useState16(true);
|
|
793
849
|
const [error, setError] = useState16(null);
|
|
794
850
|
const subRef = useRef17(null);
|
|
795
|
-
|
|
851
|
+
useEffect17(() => {
|
|
796
852
|
const sub = client.game.subscribeBoss(client.realtime);
|
|
797
853
|
subRef.current = sub;
|
|
798
854
|
sub.on("change", (data) => {
|
|
@@ -816,14 +872,14 @@ function useBossBattle() {
|
|
|
816
872
|
}
|
|
817
873
|
|
|
818
874
|
// src/dashboard/usePlayerStats.ts
|
|
819
|
-
import { useState as useState17, useEffect as
|
|
875
|
+
import { useState as useState17, useEffect as useEffect18, useRef as useRef18, useCallback as useCallback15 } from "react";
|
|
820
876
|
function usePlayerStats(memberId) {
|
|
821
877
|
const client = useDashboardClient();
|
|
822
878
|
const [player, setPlayer] = useState17(null);
|
|
823
879
|
const [loading, setLoading] = useState17(true);
|
|
824
880
|
const [error, setError] = useState17(null);
|
|
825
881
|
const subRef = useRef18(null);
|
|
826
|
-
|
|
882
|
+
useEffect18(() => {
|
|
827
883
|
const sub = client.game.subscribePlayer(client.realtime, memberId);
|
|
828
884
|
subRef.current = sub;
|
|
829
885
|
sub.on("change", (data) => {
|
|
@@ -847,14 +903,14 @@ function usePlayerStats(memberId) {
|
|
|
847
903
|
}
|
|
848
904
|
|
|
849
905
|
// src/dashboard/useLeaderboard.ts
|
|
850
|
-
import { useState as useState18, useEffect as
|
|
906
|
+
import { useState as useState18, useEffect as useEffect19, useRef as useRef19, useCallback as useCallback16 } from "react";
|
|
851
907
|
function useLeaderboard(period) {
|
|
852
908
|
const client = useDashboardClient();
|
|
853
909
|
const [entries, setEntries] = useState18([]);
|
|
854
910
|
const [loading, setLoading] = useState18(true);
|
|
855
911
|
const [error, setError] = useState18(null);
|
|
856
912
|
const subRef = useRef19(null);
|
|
857
|
-
|
|
913
|
+
useEffect19(() => {
|
|
858
914
|
const sub = client.game.subscribeLeaderboard(client.realtime, period ? { period } : void 0);
|
|
859
915
|
subRef.current = sub;
|
|
860
916
|
sub.on("change", (data) => {
|
|
@@ -878,14 +934,14 @@ function useLeaderboard(period) {
|
|
|
878
934
|
}
|
|
879
935
|
|
|
880
936
|
// src/dashboard/useGameActivity.ts
|
|
881
|
-
import { useState as useState19, useEffect as
|
|
937
|
+
import { useState as useState19, useEffect as useEffect20, useRef as useRef20, useCallback as useCallback17 } from "react";
|
|
882
938
|
function useGameActivity() {
|
|
883
939
|
const client = useDashboardClient();
|
|
884
940
|
const [events, setEvents] = useState19([]);
|
|
885
941
|
const [loading, setLoading] = useState19(true);
|
|
886
942
|
const [error, setError] = useState19(null);
|
|
887
943
|
const subRef = useRef20(null);
|
|
888
|
-
|
|
944
|
+
useEffect20(() => {
|
|
889
945
|
const sub = client.game.subscribeActivity(client.realtime);
|
|
890
946
|
subRef.current = sub;
|
|
891
947
|
sub.on("change", (data) => {
|