@cstar.help/react 0.10.1 → 0.10.3
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 +32 -21
- package/dist/index.cjs +178 -163
- package/dist/index.d.cts +19 -12
- package/dist/index.d.ts +19 -12
- package/dist/index.js +80 -64
- package/package.json +3 -3
package/dist/index.d.cts
CHANGED
|
@@ -32,7 +32,9 @@ interface CStarChatProviderProps extends ChatConfig {
|
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Provides a ChatClient instance to all child components.
|
|
35
|
-
* Creates the client
|
|
35
|
+
* Creates the client once and disconnects it on a real unmount. The client
|
|
36
|
+
* survives StrictMode's simulated unmount, so an identified customer stays
|
|
37
|
+
* identified.
|
|
36
38
|
*
|
|
37
39
|
* ```tsx
|
|
38
40
|
* <CStarChatProvider teamSlug="acme">
|
|
@@ -88,7 +90,7 @@ interface UseChatReturn {
|
|
|
88
90
|
* const { identify, loginWithCredentials, isAuthenticated, authMode } = useChat();
|
|
89
91
|
*
|
|
90
92
|
* await identify(
|
|
91
|
-
* { externalId: '
|
|
93
|
+
* { externalId: 'user_123', email: 'jane@co.com', timestamp: Date.now() / 1000 },
|
|
92
94
|
* hmacSignature
|
|
93
95
|
* );
|
|
94
96
|
* // OR
|
|
@@ -359,7 +361,11 @@ interface CStarDashboardProviderProps {
|
|
|
359
361
|
* provider builds the `CStarClient` internally so this prop can be passed
|
|
360
362
|
* across the React Server Components boundary without tripping the
|
|
361
363
|
* "Classes or null prototypes are not supported" runtime error.
|
|
362
|
-
*
|
|
364
|
+
* Every dashboard hook calls team endpoints, which need a secret key
|
|
365
|
+
* (a publishable key gets 403 publishable_key_forbidden). Config reaches
|
|
366
|
+
* the browser, so use the provider only where everyone who loads the page
|
|
367
|
+
* may hold that key (an internal tool behind your own login, a desktop
|
|
368
|
+
* app). On a public site, call your own backend instead.
|
|
363
369
|
*
|
|
364
370
|
* Either `config` or `client` is required.
|
|
365
371
|
*/
|
|
@@ -378,17 +384,18 @@ interface CStarDashboardProviderProps {
|
|
|
378
384
|
/**
|
|
379
385
|
* Provides a `CStarClient` to dashboard hooks.
|
|
380
386
|
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
387
|
+
* Every hook calls team endpoints, which need a secret key: publishable keys
|
|
388
|
+
* get 403 publishable_key_forbidden on reads and publishable_key_write on
|
|
389
|
+
* writes. Provider props and bundled clients are visible to the browser, so
|
|
390
|
+
* use the provider only in a trusted environment (an internal tool behind
|
|
391
|
+
* your own login, a desktop app), with a secret key scoped to what the
|
|
392
|
+
* dashboard needs. For anything public, have the app call your own backend,
|
|
393
|
+
* where a secret-key `CStarClient` stays on the server.
|
|
385
394
|
*
|
|
386
395
|
* ```tsx
|
|
387
|
-
* // app/providers.tsx
|
|
396
|
+
* // app/providers.tsx (an internal tool behind your own login)
|
|
388
397
|
* 'use client';
|
|
389
|
-
* <CStarDashboardProvider
|
|
390
|
-
* config={{ apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!, teamId }}
|
|
391
|
-
* >
|
|
398
|
+
* <CStarDashboardProvider config={{ apiKey: secretKeyFromYourServer, teamId }}>
|
|
392
399
|
* <TicketList />
|
|
393
400
|
* </CStarDashboardProvider>
|
|
394
401
|
* ```
|
|
@@ -493,7 +500,7 @@ interface UsePlayerStatsReturn {
|
|
|
493
500
|
* Subscribe to player stats (XP, level, streaks).
|
|
494
501
|
*
|
|
495
502
|
* ```tsx
|
|
496
|
-
* const { player, loading, error } = usePlayerStats('
|
|
503
|
+
* const { player, loading, error } = usePlayerStats('550e8400-e29b-41d4-a716-446655440001');
|
|
497
504
|
* ```
|
|
498
505
|
*/
|
|
499
506
|
declare function usePlayerStats(memberId?: string): UsePlayerStatsReturn;
|
package/dist/index.d.ts
CHANGED
|
@@ -32,7 +32,9 @@ interface CStarChatProviderProps extends ChatConfig {
|
|
|
32
32
|
}
|
|
33
33
|
/**
|
|
34
34
|
* Provides a ChatClient instance to all child components.
|
|
35
|
-
* Creates the client
|
|
35
|
+
* Creates the client once and disconnects it on a real unmount. The client
|
|
36
|
+
* survives StrictMode's simulated unmount, so an identified customer stays
|
|
37
|
+
* identified.
|
|
36
38
|
*
|
|
37
39
|
* ```tsx
|
|
38
40
|
* <CStarChatProvider teamSlug="acme">
|
|
@@ -88,7 +90,7 @@ interface UseChatReturn {
|
|
|
88
90
|
* const { identify, loginWithCredentials, isAuthenticated, authMode } = useChat();
|
|
89
91
|
*
|
|
90
92
|
* await identify(
|
|
91
|
-
* { externalId: '
|
|
93
|
+
* { externalId: 'user_123', email: 'jane@co.com', timestamp: Date.now() / 1000 },
|
|
92
94
|
* hmacSignature
|
|
93
95
|
* );
|
|
94
96
|
* // OR
|
|
@@ -359,7 +361,11 @@ interface CStarDashboardProviderProps {
|
|
|
359
361
|
* provider builds the `CStarClient` internally so this prop can be passed
|
|
360
362
|
* across the React Server Components boundary without tripping the
|
|
361
363
|
* "Classes or null prototypes are not supported" runtime error.
|
|
362
|
-
*
|
|
364
|
+
* Every dashboard hook calls team endpoints, which need a secret key
|
|
365
|
+
* (a publishable key gets 403 publishable_key_forbidden). Config reaches
|
|
366
|
+
* the browser, so use the provider only where everyone who loads the page
|
|
367
|
+
* may hold that key (an internal tool behind your own login, a desktop
|
|
368
|
+
* app). On a public site, call your own backend instead.
|
|
363
369
|
*
|
|
364
370
|
* Either `config` or `client` is required.
|
|
365
371
|
*/
|
|
@@ -378,17 +384,18 @@ interface CStarDashboardProviderProps {
|
|
|
378
384
|
/**
|
|
379
385
|
* Provides a `CStarClient` to dashboard hooks.
|
|
380
386
|
*
|
|
381
|
-
*
|
|
382
|
-
*
|
|
383
|
-
*
|
|
384
|
-
*
|
|
387
|
+
* Every hook calls team endpoints, which need a secret key: publishable keys
|
|
388
|
+
* get 403 publishable_key_forbidden on reads and publishable_key_write on
|
|
389
|
+
* writes. Provider props and bundled clients are visible to the browser, so
|
|
390
|
+
* use the provider only in a trusted environment (an internal tool behind
|
|
391
|
+
* your own login, a desktop app), with a secret key scoped to what the
|
|
392
|
+
* dashboard needs. For anything public, have the app call your own backend,
|
|
393
|
+
* where a secret-key `CStarClient` stays on the server.
|
|
385
394
|
*
|
|
386
395
|
* ```tsx
|
|
387
|
-
* // app/providers.tsx
|
|
396
|
+
* // app/providers.tsx (an internal tool behind your own login)
|
|
388
397
|
* 'use client';
|
|
389
|
-
* <CStarDashboardProvider
|
|
390
|
-
* config={{ apiKey: process.env.NEXT_PUBLIC_CSTAR_PUBLISHABLE_KEY!, teamId }}
|
|
391
|
-
* >
|
|
398
|
+
* <CStarDashboardProvider config={{ apiKey: secretKeyFromYourServer, teamId }}>
|
|
392
399
|
* <TicketList />
|
|
393
400
|
* </CStarDashboardProvider>
|
|
394
401
|
* ```
|
|
@@ -493,7 +500,7 @@ interface UsePlayerStatsReturn {
|
|
|
493
500
|
* Subscribe to player stats (XP, level, streaks).
|
|
494
501
|
*
|
|
495
502
|
* ```tsx
|
|
496
|
-
* const { player, loading, error } = usePlayerStats('
|
|
503
|
+
* const { player, loading, error } = usePlayerStats('550e8400-e29b-41d4-a716-446655440001');
|
|
497
504
|
* ```
|
|
498
505
|
*/
|
|
499
506
|
declare function usePlayerStats(memberId?: string): UsePlayerStatsReturn;
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
'use client';
|
|
2
|
+
|
|
1
3
|
// src/context.tsx
|
|
2
4
|
import { createContext, useContext } from "react";
|
|
3
5
|
var CStarChatContext = createContext(null);
|
|
@@ -26,20 +28,39 @@ function useCommunityClient() {
|
|
|
26
28
|
}
|
|
27
29
|
|
|
28
30
|
// src/chat/CStarChatProvider.tsx
|
|
29
|
-
import {
|
|
31
|
+
import { useRef as useRef2 } from "react";
|
|
30
32
|
import { ChatClient } from "@cstar.help/js/chat";
|
|
33
|
+
|
|
34
|
+
// src/useDisconnectOnUnmount.ts
|
|
35
|
+
import { useEffect, useRef } from "react";
|
|
36
|
+
function useDisconnectOnUnmount(target, disconnect) {
|
|
37
|
+
const pending = useRef(null);
|
|
38
|
+
const disconnectRef = useRef(disconnect);
|
|
39
|
+
disconnectRef.current = disconnect;
|
|
40
|
+
useEffect(() => {
|
|
41
|
+
if (target === null) return;
|
|
42
|
+
if (pending.current?.target === target) {
|
|
43
|
+
clearTimeout(pending.current.timer);
|
|
44
|
+
pending.current = null;
|
|
45
|
+
}
|
|
46
|
+
return () => {
|
|
47
|
+
const timer = setTimeout(() => {
|
|
48
|
+
if (pending.current?.target === target) pending.current = null;
|
|
49
|
+
disconnectRef.current(target);
|
|
50
|
+
}, 0);
|
|
51
|
+
pending.current = { target, timer };
|
|
52
|
+
};
|
|
53
|
+
}, [target]);
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
// src/chat/CStarChatProvider.tsx
|
|
31
57
|
import { jsx } from "react/jsx-runtime";
|
|
32
58
|
function CStarChatProvider({ children, ...config }) {
|
|
33
|
-
const clientRef =
|
|
59
|
+
const clientRef = useRef2(null);
|
|
34
60
|
if (!clientRef.current) {
|
|
35
61
|
clientRef.current = new ChatClient(config);
|
|
36
62
|
}
|
|
37
|
-
|
|
38
|
-
return () => {
|
|
39
|
-
clientRef.current?.disconnect();
|
|
40
|
-
clientRef.current = null;
|
|
41
|
-
};
|
|
42
|
-
}, []);
|
|
63
|
+
useDisconnectOnUnmount(clientRef.current, (client) => client.disconnect());
|
|
43
64
|
return /* @__PURE__ */ jsx(CStarChatContext.Provider, { value: clientRef.current, children });
|
|
44
65
|
}
|
|
45
66
|
|
|
@@ -135,14 +156,14 @@ function useChat() {
|
|
|
135
156
|
}
|
|
136
157
|
|
|
137
158
|
// src/chat/useTickets.ts
|
|
138
|
-
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2, useRef as
|
|
159
|
+
import { useState as useState2, useEffect as useEffect3, useCallback as useCallback2, useRef as useRef3 } from "react";
|
|
139
160
|
function useTickets() {
|
|
140
161
|
const client = useChatClient();
|
|
141
162
|
const [tickets, setTickets] = useState2([]);
|
|
142
163
|
const [isLoading, setIsLoading] = useState2(true);
|
|
143
164
|
const [error, setError] = useState2(null);
|
|
144
165
|
const [hasMore, setHasMore] = useState2(false);
|
|
145
|
-
const mountedRef =
|
|
166
|
+
const mountedRef = useRef3(true);
|
|
146
167
|
const refresh = useCallback2(async () => {
|
|
147
168
|
setIsLoading(true);
|
|
148
169
|
setError(null);
|
|
@@ -183,17 +204,17 @@ function useTickets() {
|
|
|
183
204
|
}
|
|
184
205
|
|
|
185
206
|
// src/chat/useMessages.ts
|
|
186
|
-
import { useState as useState3, useEffect as useEffect4, useCallback as useCallback3, useRef as
|
|
207
|
+
import { useState as useState3, useEffect as useEffect4, useCallback as useCallback3, useRef as useRef4 } from "react";
|
|
187
208
|
function useMessages(ticketId) {
|
|
188
209
|
const client = useChatClient();
|
|
189
210
|
const [messages, setMessages] = useState3([]);
|
|
190
211
|
const [isLoading, setIsLoading] = useState3(true);
|
|
191
212
|
const [error, setError] = useState3(null);
|
|
192
|
-
const mountedRef =
|
|
193
|
-
const seenIdsRef =
|
|
194
|
-
const requestRef =
|
|
195
|
-
const scopeRef =
|
|
196
|
-
const optimisticRef =
|
|
213
|
+
const mountedRef = useRef4(true);
|
|
214
|
+
const seenIdsRef = useRef4(/* @__PURE__ */ new Set());
|
|
215
|
+
const requestRef = useRef4(0);
|
|
216
|
+
const scopeRef = useRef4(0);
|
|
217
|
+
const optimisticRef = useRef4(0);
|
|
197
218
|
const refresh = useCallback3(async () => {
|
|
198
219
|
if (!ticketId) return;
|
|
199
220
|
const request = ++requestRef.current;
|
|
@@ -287,13 +308,13 @@ function useMessages(ticketId) {
|
|
|
287
308
|
}
|
|
288
309
|
|
|
289
310
|
// src/chat/useTyping.ts
|
|
290
|
-
import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4, useRef as
|
|
311
|
+
import { useState as useState4, useEffect as useEffect5, useCallback as useCallback4, useRef as useRef5 } from "react";
|
|
291
312
|
var TYPING_TIMEOUT = 4e3;
|
|
292
313
|
function useTyping(ticketId) {
|
|
293
314
|
const client = useChatClient();
|
|
294
315
|
const [typingAgents, setTypingAgents] = useState4([]);
|
|
295
|
-
const timersRef =
|
|
296
|
-
const mountedRef =
|
|
316
|
+
const timersRef = useRef5(/* @__PURE__ */ new Map());
|
|
317
|
+
const mountedRef = useRef5(true);
|
|
297
318
|
useEffect5(() => {
|
|
298
319
|
mountedRef.current = true;
|
|
299
320
|
if (!ticketId) {
|
|
@@ -342,11 +363,11 @@ function useTyping(ticketId) {
|
|
|
342
363
|
}
|
|
343
364
|
|
|
344
365
|
// src/library/CStarLibraryProvider.tsx
|
|
345
|
-
import { useRef as
|
|
366
|
+
import { useRef as useRef6 } from "react";
|
|
346
367
|
import { LibraryClient } from "@cstar.help/js/library";
|
|
347
368
|
import { jsx as jsx2 } from "react/jsx-runtime";
|
|
348
369
|
function CStarLibraryProvider({ children, ...config }) {
|
|
349
|
-
const clientRef =
|
|
370
|
+
const clientRef = useRef6(null);
|
|
350
371
|
if (!clientRef.current) {
|
|
351
372
|
clientRef.current = new LibraryClient(config);
|
|
352
373
|
}
|
|
@@ -354,13 +375,13 @@ function CStarLibraryProvider({ children, ...config }) {
|
|
|
354
375
|
}
|
|
355
376
|
|
|
356
377
|
// src/library/useCategories.ts
|
|
357
|
-
import { useState as useState5, useEffect as useEffect6, useCallback as useCallback5, useRef as
|
|
378
|
+
import { useState as useState5, useEffect as useEffect6, useCallback as useCallback5, useRef as useRef7 } from "react";
|
|
358
379
|
function useCategories() {
|
|
359
380
|
const client = useLibraryClient();
|
|
360
381
|
const [categories, setCategories] = useState5([]);
|
|
361
382
|
const [isLoading, setIsLoading] = useState5(true);
|
|
362
383
|
const [error, setError] = useState5(null);
|
|
363
|
-
const mountedRef =
|
|
384
|
+
const mountedRef = useRef7(true);
|
|
364
385
|
const refresh = useCallback5(async () => {
|
|
365
386
|
setIsLoading(true);
|
|
366
387
|
setError(null);
|
|
@@ -390,13 +411,13 @@ function useCategories() {
|
|
|
390
411
|
}
|
|
391
412
|
|
|
392
413
|
// src/library/useArticles.ts
|
|
393
|
-
import { useState as useState6, useEffect as useEffect7, useCallback as useCallback6, useRef as
|
|
414
|
+
import { useState as useState6, useEffect as useEffect7, useCallback as useCallback6, useRef as useRef8 } from "react";
|
|
394
415
|
function useArticles(params) {
|
|
395
416
|
const client = useLibraryClient();
|
|
396
417
|
const [articles, setArticles] = useState6([]);
|
|
397
418
|
const [isLoading, setIsLoading] = useState6(true);
|
|
398
419
|
const [error, setError] = useState6(null);
|
|
399
|
-
const mountedRef =
|
|
420
|
+
const mountedRef = useRef8(true);
|
|
400
421
|
const categorySlug = params?.categorySlug;
|
|
401
422
|
const limit = params?.limit;
|
|
402
423
|
const offset = params?.offset;
|
|
@@ -429,13 +450,13 @@ function useArticles(params) {
|
|
|
429
450
|
}
|
|
430
451
|
|
|
431
452
|
// src/library/useArticle.ts
|
|
432
|
-
import { useState as useState7, useEffect as useEffect8, useCallback as useCallback7, useRef as
|
|
453
|
+
import { useState as useState7, useEffect as useEffect8, useCallback as useCallback7, useRef as useRef9 } from "react";
|
|
433
454
|
function useArticle(slug) {
|
|
434
455
|
const client = useLibraryClient();
|
|
435
456
|
const [article, setArticle] = useState7(null);
|
|
436
457
|
const [isLoading, setIsLoading] = useState7(true);
|
|
437
458
|
const [error, setError] = useState7(null);
|
|
438
|
-
const mountedRef =
|
|
459
|
+
const mountedRef = useRef9(true);
|
|
439
460
|
const refresh = useCallback7(async () => {
|
|
440
461
|
if (!slug) return;
|
|
441
462
|
setIsLoading(true);
|
|
@@ -478,7 +499,7 @@ function useArticle(slug) {
|
|
|
478
499
|
}
|
|
479
500
|
|
|
480
501
|
// src/library/useArticleSearch.ts
|
|
481
|
-
import { useState as useState8, useEffect as useEffect9, useRef as
|
|
502
|
+
import { useState as useState8, useEffect as useEffect9, useRef as useRef10 } from "react";
|
|
482
503
|
var DEBOUNCE_MS = 300;
|
|
483
504
|
function useArticleSearch(query) {
|
|
484
505
|
const client = useLibraryClient();
|
|
@@ -486,7 +507,7 @@ function useArticleSearch(query) {
|
|
|
486
507
|
const [totalCount, setTotalCount] = useState8(0);
|
|
487
508
|
const [isLoading, setIsLoading] = useState8(false);
|
|
488
509
|
const [error, setError] = useState8(null);
|
|
489
|
-
const mountedRef =
|
|
510
|
+
const mountedRef = useRef10(true);
|
|
490
511
|
useEffect9(() => {
|
|
491
512
|
mountedRef.current = true;
|
|
492
513
|
const trimmed = query.trim();
|
|
@@ -525,11 +546,11 @@ function useArticleSearch(query) {
|
|
|
525
546
|
}
|
|
526
547
|
|
|
527
548
|
// src/community/CStarCommunityProvider.tsx
|
|
528
|
-
import { useRef as
|
|
549
|
+
import { useRef as useRef11 } from "react";
|
|
529
550
|
import { CommunityClient } from "@cstar.help/js/community";
|
|
530
551
|
import { jsx as jsx3 } from "react/jsx-runtime";
|
|
531
552
|
function CStarCommunityProvider({ children, ...config }) {
|
|
532
|
-
const clientRef =
|
|
553
|
+
const clientRef = useRef11(null);
|
|
533
554
|
if (!clientRef.current) {
|
|
534
555
|
clientRef.current = new CommunityClient(config);
|
|
535
556
|
}
|
|
@@ -537,13 +558,13 @@ function CStarCommunityProvider({ children, ...config }) {
|
|
|
537
558
|
}
|
|
538
559
|
|
|
539
560
|
// src/community/useTopics.ts
|
|
540
|
-
import { useState as useState9, useEffect as useEffect10, useCallback as useCallback8, useRef as
|
|
561
|
+
import { useState as useState9, useEffect as useEffect10, useCallback as useCallback8, useRef as useRef12 } from "react";
|
|
541
562
|
function useTopics() {
|
|
542
563
|
const client = useCommunityClient();
|
|
543
564
|
const [topics, setTopics] = useState9([]);
|
|
544
565
|
const [isLoading, setIsLoading] = useState9(true);
|
|
545
566
|
const [error, setError] = useState9(null);
|
|
546
|
-
const mountedRef =
|
|
567
|
+
const mountedRef = useRef12(true);
|
|
547
568
|
const refresh = useCallback8(async () => {
|
|
548
569
|
setIsLoading(true);
|
|
549
570
|
setError(null);
|
|
@@ -573,14 +594,14 @@ function useTopics() {
|
|
|
573
594
|
}
|
|
574
595
|
|
|
575
596
|
// src/community/usePosts.ts
|
|
576
|
-
import { useState as useState10, useEffect as useEffect11, useCallback as useCallback9, useRef as
|
|
597
|
+
import { useState as useState10, useEffect as useEffect11, useCallback as useCallback9, useRef as useRef13 } from "react";
|
|
577
598
|
function usePosts(params) {
|
|
578
599
|
const client = useCommunityClient();
|
|
579
600
|
const [posts, setPosts] = useState10([]);
|
|
580
601
|
const [count, setCount] = useState10(0);
|
|
581
602
|
const [isLoading, setIsLoading] = useState10(true);
|
|
582
603
|
const [error, setError] = useState10(null);
|
|
583
|
-
const mountedRef =
|
|
604
|
+
const mountedRef = useRef13(true);
|
|
584
605
|
const topicSlug = params?.topicSlug;
|
|
585
606
|
const status = params?.status;
|
|
586
607
|
const sort = params?.sort;
|
|
@@ -616,13 +637,13 @@ function usePosts(params) {
|
|
|
616
637
|
}
|
|
617
638
|
|
|
618
639
|
// src/community/usePost.ts
|
|
619
|
-
import { useState as useState11, useEffect as useEffect12, useCallback as useCallback10, useRef as
|
|
640
|
+
import { useState as useState11, useEffect as useEffect12, useCallback as useCallback10, useRef as useRef14 } from "react";
|
|
620
641
|
function usePost(slug) {
|
|
621
642
|
const client = useCommunityClient();
|
|
622
643
|
const [data, setData] = useState11(null);
|
|
623
644
|
const [isLoading, setIsLoading] = useState11(true);
|
|
624
645
|
const [error, setError] = useState11(null);
|
|
625
|
-
const mountedRef =
|
|
646
|
+
const mountedRef = useRef14(true);
|
|
626
647
|
const refresh = useCallback10(async () => {
|
|
627
648
|
setIsLoading(true);
|
|
628
649
|
setError(null);
|
|
@@ -652,13 +673,13 @@ function usePost(slug) {
|
|
|
652
673
|
}
|
|
653
674
|
|
|
654
675
|
// src/community/useCommunitySearch.ts
|
|
655
|
-
import { useState as useState12, useEffect as useEffect13, useCallback as useCallback11, useRef as
|
|
676
|
+
import { useState as useState12, useEffect as useEffect13, useCallback as useCallback11, useRef as useRef15 } from "react";
|
|
656
677
|
function useCommunitySearch() {
|
|
657
678
|
const client = useCommunityClient();
|
|
658
679
|
const [results, setResults] = useState12(null);
|
|
659
680
|
const [isLoading, setIsLoading] = useState12(false);
|
|
660
681
|
const [error, setError] = useState12(null);
|
|
661
|
-
const mountedRef =
|
|
682
|
+
const mountedRef = useRef15(true);
|
|
662
683
|
useEffect13(() => {
|
|
663
684
|
mountedRef.current = true;
|
|
664
685
|
return () => {
|
|
@@ -694,7 +715,7 @@ function useCommunitySearch() {
|
|
|
694
715
|
}
|
|
695
716
|
|
|
696
717
|
// src/dashboard/CStarDashboardProvider.tsx
|
|
697
|
-
import { createContext as createContext2, useContext as useContext2,
|
|
718
|
+
import { createContext as createContext2, useContext as useContext2, useMemo } from "react";
|
|
698
719
|
import { CStarClient } from "@cstar.help/js";
|
|
699
720
|
import { jsx as jsx4 } from "react/jsx-runtime";
|
|
700
721
|
var CStarDashboardContext = createContext2(null);
|
|
@@ -705,7 +726,7 @@ function CStarDashboardProvider({
|
|
|
705
726
|
}) {
|
|
706
727
|
if (!config && !providedClient) {
|
|
707
728
|
throw new Error(
|
|
708
|
-
"CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }
|
|
729
|
+
"CStarDashboardProvider requires either a `config` prop (`{ apiKey, teamId }`, recommended) or a `client` prop (a pre-built CStarClient instance, deprecated). See https://www.cstar.help/developers/sdk/react#dashboard"
|
|
709
730
|
);
|
|
710
731
|
}
|
|
711
732
|
const client = useMemo(() => {
|
|
@@ -721,12 +742,7 @@ function CStarDashboardProvider({
|
|
|
721
742
|
config?.timeout
|
|
722
743
|
]);
|
|
723
744
|
const contextValue = useMemo(() => ({ client }), [client]);
|
|
724
|
-
|
|
725
|
-
if (providedClient) return;
|
|
726
|
-
return () => {
|
|
727
|
-
client?.realtime?.disconnect?.();
|
|
728
|
-
};
|
|
729
|
-
}, [client, providedClient]);
|
|
745
|
+
useDisconnectOnUnmount(providedClient ? null : client, (owned) => owned.realtime?.disconnect?.());
|
|
730
746
|
return /* @__PURE__ */ jsx4(CStarDashboardContext.Provider, { value: contextValue, children });
|
|
731
747
|
}
|
|
732
748
|
function useDashboardClient() {
|
|
@@ -738,7 +754,7 @@ function useDashboardClient() {
|
|
|
738
754
|
}
|
|
739
755
|
|
|
740
756
|
// src/dashboard/useCStarQuery.ts
|
|
741
|
-
import { useState as useState13, useEffect as
|
|
757
|
+
import { useState as useState13, useEffect as useEffect14, useRef as useRef16, useCallback as useCallback12 } from "react";
|
|
742
758
|
import { CStarValidationError } from "@cstar.help/js";
|
|
743
759
|
function resolveResource(client, path) {
|
|
744
760
|
const parts = path.split(".");
|
|
@@ -760,9 +776,9 @@ function useCStarQuery(resource, params) {
|
|
|
760
776
|
const [data, setData] = useState13(null);
|
|
761
777
|
const [loading, setLoading] = useState13(true);
|
|
762
778
|
const [error, setError] = useState13(null);
|
|
763
|
-
const subscriptionRef =
|
|
779
|
+
const subscriptionRef = useRef16(null);
|
|
764
780
|
const paramsKey = params ? JSON.stringify(params) : "";
|
|
765
|
-
|
|
781
|
+
useEffect14(() => {
|
|
766
782
|
const resolved = resolveResource(client, resource);
|
|
767
783
|
if (!resolved) {
|
|
768
784
|
setError(new Error(`Invalid resource path: ${resource}. Expected format: 'tickets.list'`));
|
|
@@ -849,14 +865,14 @@ function useCStarMutation(resource) {
|
|
|
849
865
|
}
|
|
850
866
|
|
|
851
867
|
// src/dashboard/useCStarEvents.ts
|
|
852
|
-
import { useState as useState15, useEffect as
|
|
868
|
+
import { useState as useState15, useEffect as useEffect15 } from "react";
|
|
853
869
|
var MAX_EVENTS = 100;
|
|
854
870
|
function useCStarEvents(types) {
|
|
855
871
|
const client = useDashboardClient();
|
|
856
872
|
const [events, setEvents] = useState15([]);
|
|
857
873
|
const [connected, setConnected] = useState15(false);
|
|
858
874
|
const typesKey = types ? types.join(",") : "";
|
|
859
|
-
|
|
875
|
+
useEffect15(() => {
|
|
860
876
|
const realtime = client.realtime;
|
|
861
877
|
const handler = (event) => {
|
|
862
878
|
if (types && types.length > 0) {
|
|
@@ -888,14 +904,14 @@ function useCStarEvents(types) {
|
|
|
888
904
|
}
|
|
889
905
|
|
|
890
906
|
// src/dashboard/useBossBattle.ts
|
|
891
|
-
import { useState as useState16, useEffect as
|
|
907
|
+
import { useState as useState16, useEffect as useEffect16, useRef as useRef17, useCallback as useCallback14 } from "react";
|
|
892
908
|
function useBossBattle() {
|
|
893
909
|
const client = useDashboardClient();
|
|
894
910
|
const [boss, setBoss] = useState16(null);
|
|
895
911
|
const [loading, setLoading] = useState16(true);
|
|
896
912
|
const [error, setError] = useState16(null);
|
|
897
|
-
const subRef =
|
|
898
|
-
|
|
913
|
+
const subRef = useRef17(null);
|
|
914
|
+
useEffect16(() => {
|
|
899
915
|
const sub = client.game.subscribeBoss(client.realtime);
|
|
900
916
|
subRef.current = sub;
|
|
901
917
|
sub.on("change", (data) => {
|
|
@@ -919,14 +935,14 @@ function useBossBattle() {
|
|
|
919
935
|
}
|
|
920
936
|
|
|
921
937
|
// src/dashboard/usePlayerStats.ts
|
|
922
|
-
import { useState as useState17, useEffect as
|
|
938
|
+
import { useState as useState17, useEffect as useEffect17, useRef as useRef18, useCallback as useCallback15 } from "react";
|
|
923
939
|
function usePlayerStats(memberId) {
|
|
924
940
|
const client = useDashboardClient();
|
|
925
941
|
const [player, setPlayer] = useState17(null);
|
|
926
942
|
const [loading, setLoading] = useState17(true);
|
|
927
943
|
const [error, setError] = useState17(null);
|
|
928
|
-
const subRef =
|
|
929
|
-
|
|
944
|
+
const subRef = useRef18(null);
|
|
945
|
+
useEffect17(() => {
|
|
930
946
|
const sub = client.game.subscribePlayer(client.realtime, memberId);
|
|
931
947
|
subRef.current = sub;
|
|
932
948
|
sub.on("change", (data) => {
|
|
@@ -950,14 +966,14 @@ function usePlayerStats(memberId) {
|
|
|
950
966
|
}
|
|
951
967
|
|
|
952
968
|
// src/dashboard/useLeaderboard.ts
|
|
953
|
-
import { useState as useState18, useEffect as
|
|
969
|
+
import { useState as useState18, useEffect as useEffect18, useRef as useRef19, useCallback as useCallback16 } from "react";
|
|
954
970
|
function useLeaderboard(period) {
|
|
955
971
|
const client = useDashboardClient();
|
|
956
972
|
const [entries, setEntries] = useState18([]);
|
|
957
973
|
const [loading, setLoading] = useState18(true);
|
|
958
974
|
const [error, setError] = useState18(null);
|
|
959
|
-
const subRef =
|
|
960
|
-
|
|
975
|
+
const subRef = useRef19(null);
|
|
976
|
+
useEffect18(() => {
|
|
961
977
|
const sub = client.game.subscribeLeaderboard(client.realtime, period ? { period } : void 0);
|
|
962
978
|
subRef.current = sub;
|
|
963
979
|
sub.on("change", (data) => {
|
|
@@ -981,14 +997,14 @@ function useLeaderboard(period) {
|
|
|
981
997
|
}
|
|
982
998
|
|
|
983
999
|
// src/dashboard/useGameActivity.ts
|
|
984
|
-
import { useState as useState19, useEffect as
|
|
1000
|
+
import { useState as useState19, useEffect as useEffect19, useRef as useRef20, useCallback as useCallback17 } from "react";
|
|
985
1001
|
function useGameActivity() {
|
|
986
1002
|
const client = useDashboardClient();
|
|
987
1003
|
const [events, setEvents] = useState19([]);
|
|
988
1004
|
const [loading, setLoading] = useState19(true);
|
|
989
1005
|
const [error, setError] = useState19(null);
|
|
990
|
-
const subRef =
|
|
991
|
-
|
|
1006
|
+
const subRef = useRef20(null);
|
|
1007
|
+
useEffect19(() => {
|
|
992
1008
|
const sub = client.game.subscribeActivity(client.realtime);
|
|
993
1009
|
subRef.current = sub;
|
|
994
1010
|
sub.on("change", (data) => {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cstar.help/react",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.3",
|
|
4
4
|
"description": "React hooks for the cStar customer support platform",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.cjs",
|
|
@@ -30,12 +30,12 @@
|
|
|
30
30
|
},
|
|
31
31
|
"peerDependencies": {
|
|
32
32
|
"react": ">=18.0.0",
|
|
33
|
-
"@cstar.help/js": "
|
|
33
|
+
"@cstar.help/js": "^0.18.2"
|
|
34
34
|
},
|
|
35
35
|
"devDependencies": {
|
|
36
36
|
"react": "^18.3.1",
|
|
37
37
|
"react-dom": "^18.3.1",
|
|
38
|
-
"@cstar.help/js": "^0.
|
|
38
|
+
"@cstar.help/js": "^0.18.2",
|
|
39
39
|
"@testing-library/react": "^16.1.0",
|
|
40
40
|
"@types/react": "^18.3.0",
|
|
41
41
|
"@types/react-dom": "^18.3.0",
|