@adventurelabs/scout-core 2.0.10 → 2.0.12
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
|
@@ -44,6 +44,9 @@ remain available when expired; pass `false` as the fourth argument to
|
|
|
44
44
|
not synthesize a Supabase `User` when no validated user is available.
|
|
45
45
|
Use `createScoutBrowserClient()` when the application needs the same configured
|
|
46
46
|
client outside the provider.
|
|
47
|
+
Provider descendants should call `useScoutRefreshActions()` for
|
|
48
|
+
`handleRefresh` and `clearCache` instead of creating another
|
|
49
|
+
`useScoutRefresh()` instance.
|
|
47
50
|
Create Redux state explicitly with `configureScoutStore()` and keep that
|
|
48
51
|
instance stable in the application provider.
|
|
49
52
|
|
package/dist/hooks/index.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export { useScoutRefresh, type UseScoutRefreshOptions, } from "./useScoutRefresh";
|
|
1
|
+
export { useScoutRefresh, type ScoutRefreshRequest, type UseScoutRefreshOptions, } from "./useScoutRefresh";
|
|
2
2
|
export { useScoutRealtimeBroadcast, type ScoutRealtimeBroadcastOptions, type ScoutRealtimeAuthErrorMode, } from "./useScoutRealtimeBroadcast";
|
|
3
3
|
export { useScoutRealtimeConnectivity } from "./useScoutRealtimeConnectivity";
|
|
4
4
|
export { useScoutRealtimeDevices } from "./useScoutRealtimeDevices";
|
|
@@ -62,6 +62,7 @@ export function useScoutRefresh(options = {}, identityOptions = {}) {
|
|
|
62
62
|
const refreshIdRef = useRef(0);
|
|
63
63
|
const refreshInProgressIdRef = useRef(null);
|
|
64
64
|
const activeUserIdRef = useRef(null);
|
|
65
|
+
const signedOutRef = useRef(false);
|
|
65
66
|
const validatedUserIdRef = useRef(null);
|
|
66
67
|
const providedValidatedUserIdRef = useRef(validatedUserId);
|
|
67
68
|
providedValidatedUserIdRef.current = validatedUserId;
|
|
@@ -334,6 +335,7 @@ export function useScoutRefresh(options = {}, identityOptions = {}) {
|
|
|
334
335
|
useEffect(() => {
|
|
335
336
|
return subscribeToSupabaseAuth(supabase, (event, session) => {
|
|
336
337
|
if (event === "SIGNED_OUT") {
|
|
338
|
+
signedOutRef.current = true;
|
|
337
339
|
const previousUserId = activeUserIdRef.current ?? scoutCache.getScopeUserId();
|
|
338
340
|
refreshIdRef.current++;
|
|
339
341
|
activeUserIdRef.current = null;
|
|
@@ -347,14 +349,22 @@ export function useScoutRefresh(options = {}, identityOptions = {}) {
|
|
|
347
349
|
}
|
|
348
350
|
const nextUserId = session?.user?.id;
|
|
349
351
|
if (event === "SIGNED_IN" && nextUserId) {
|
|
352
|
+
const wasSignedOut = signedOutRef.current;
|
|
353
|
+
signedOutRef.current = false;
|
|
350
354
|
validatedUserIdRef.current = nextUserId;
|
|
351
355
|
notifyUserValidated(nextUserId);
|
|
352
|
-
|
|
356
|
+
const knownUserId = activeUserIdRef.current;
|
|
357
|
+
activeUserIdRef.current = nextUserId;
|
|
358
|
+
if (knownUserId === nextUserId) {
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
if (knownUserId === null && !wasSignedOut) {
|
|
353
362
|
return;
|
|
354
363
|
}
|
|
355
364
|
refreshIdRef.current++;
|
|
356
|
-
|
|
357
|
-
|
|
365
|
+
if (knownUserId !== null) {
|
|
366
|
+
resetClientState();
|
|
367
|
+
}
|
|
358
368
|
void handleRefresh({ force: true });
|
|
359
369
|
}
|
|
360
370
|
});
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type UseScoutRefreshOptions } from "../hooks/useScoutRefresh";
|
|
1
|
+
import { type ScoutRefreshRequest, type UseScoutRefreshOptions } from "../hooks/useScoutRefresh";
|
|
2
2
|
import { type ReactNode } from "react";
|
|
3
3
|
import { SupabaseClient } from "@supabase/supabase-js";
|
|
4
4
|
import { Database } from "../types/supabase";
|
|
@@ -25,7 +25,12 @@ export interface PubsubTokenMintState {
|
|
|
25
25
|
error: string | null;
|
|
26
26
|
refreshMint: () => Promise<void>;
|
|
27
27
|
}
|
|
28
|
+
export interface ScoutRefreshActions {
|
|
29
|
+
handleRefresh: (request?: ScoutRefreshRequest) => Promise<void>;
|
|
30
|
+
clearCache: () => Promise<void>;
|
|
31
|
+
}
|
|
28
32
|
export declare function useSupabase(): SupabaseClient<Database>;
|
|
33
|
+
export declare function useScoutRefreshActions(): ScoutRefreshActions;
|
|
29
34
|
export declare function useClientAbilitiesMint(): ClientAbilitiesMintState;
|
|
30
35
|
export declare function useOptionalClientAbilitiesMint(): ClientAbilitiesMintState | null;
|
|
31
36
|
export declare function usePubsubTokenMint(): PubsubTokenMintState;
|
|
@@ -37,6 +37,10 @@ function useScoutRefreshContext() {
|
|
|
37
37
|
export function useSupabase() {
|
|
38
38
|
return useScoutRefreshContext().supabase;
|
|
39
39
|
}
|
|
40
|
+
export function useScoutRefreshActions() {
|
|
41
|
+
const { handleRefresh, clearCache } = useScoutRefreshContext();
|
|
42
|
+
return useMemo(() => ({ handleRefresh, clearCache }), [handleRefresh, clearCache]);
|
|
43
|
+
}
|
|
40
44
|
export function useClientAbilitiesMint() {
|
|
41
45
|
return useScoutRefreshContext().abilities;
|
|
42
46
|
}
|
|
@@ -282,7 +286,12 @@ function useJwtMintLifecycle({ enabled, supabase, identity, cacheKey, ttlSec, re
|
|
|
282
286
|
authUserIdRef.current !== userId) {
|
|
283
287
|
return;
|
|
284
288
|
}
|
|
285
|
-
|
|
289
|
+
if (cached.data && !cached.isStale) {
|
|
290
|
+
updateMint(cached.data);
|
|
291
|
+
}
|
|
292
|
+
else if (!mintRef.current) {
|
|
293
|
+
updateMint(cached.data);
|
|
294
|
+
}
|
|
286
295
|
}
|
|
287
296
|
catch (cacheError) {
|
|
288
297
|
console.warn(`[ScoutRefreshProvider] ${cacheKey} cache load failed:`, cacheError);
|
|
@@ -481,9 +490,15 @@ export function ScoutRefreshProvider({ children, abilityParams, supabase: supaba
|
|
|
481
490
|
}
|
|
482
491
|
const abilitiesConfig = useMemo(() => resolveAbilityParams(abilityParams), [abilityParams]);
|
|
483
492
|
const { identity, renderChildren } = useScoutIdentity(supabase, refreshOptions.offlineUserId);
|
|
484
|
-
useScoutRefresh({ ...refreshOptions, supabase }, identity);
|
|
493
|
+
const { handleRefresh, clearCache } = useScoutRefresh({ ...refreshOptions, supabase }, identity);
|
|
485
494
|
const abilities = useClientAbilitiesMintLifecycle(supabase, abilitiesConfig, identity);
|
|
486
495
|
const pubsub = usePubsubTokenMintLifecycle(supabase, abilitiesConfig, identity);
|
|
487
|
-
const value = useMemo(() => ({
|
|
496
|
+
const value = useMemo(() => ({
|
|
497
|
+
supabase,
|
|
498
|
+
abilities,
|
|
499
|
+
pubsub,
|
|
500
|
+
handleRefresh,
|
|
501
|
+
clearCache,
|
|
502
|
+
}), [supabase, abilities, pubsub, handleRefresh, clearCache]);
|
|
488
503
|
return (_jsx(ScoutRefreshContext.Provider, { value: value, children: renderChildren ? children : null }));
|
|
489
504
|
}
|