@adventurelabs/scout-core 1.5.4 → 2.0.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 +47 -0
- package/dist/api_keys/actions.d.ts +0 -1
- package/dist/api_keys/actions.js +0 -14
- package/dist/client/index.d.ts +75 -0
- package/dist/client/index.js +82 -0
- package/dist/constants/index.d.ts +1 -0
- package/dist/constants/index.js +1 -0
- package/dist/helpers/analysis_usage/jobs_server.d.ts +25 -0
- package/dist/helpers/analysis_usage/jobs_server.js +10 -0
- package/dist/helpers/analysis_usage/tasks_server.d.ts +63 -0
- package/dist/helpers/analysis_usage/tasks_server.js +14 -0
- package/dist/helpers/artifacts.d.ts +0 -1
- package/dist/helpers/artifacts.js +10 -147
- package/dist/helpers/artifacts.queries.d.ts +26 -0
- package/dist/helpers/{artifacts.internal.js → artifacts.queries.js} +24 -41
- package/dist/helpers/auth.d.ts +1 -1
- package/dist/helpers/auth.js +2 -3
- package/dist/helpers/auth_server.d.ts +2 -0
- package/dist/helpers/auth_server.js +10 -0
- package/dist/helpers/certificates_server.d.ts +101 -0
- package/dist/helpers/certificates_server.js +42 -0
- package/dist/helpers/chat.d.ts +1 -2
- package/dist/helpers/chat.js +3 -38
- package/dist/helpers/chat.queries.d.ts +13 -0
- package/dist/helpers/chat.queries.js +39 -0
- package/dist/helpers/client_abilities_jwt_keys.js +0 -1
- package/dist/helpers/client_abilities_token_server.d.ts +1 -0
- package/dist/helpers/client_abilities_token_server.js +5 -2
- package/dist/helpers/connectivity.d.ts +1 -5
- package/dist/helpers/connectivity.js +7 -140
- package/dist/helpers/connectivity.queries.d.ts +18 -0
- package/dist/helpers/connectivity.queries.js +121 -0
- package/dist/helpers/contacts_server.d.ts +63 -0
- package/dist/helpers/contacts_server.js +18 -0
- package/dist/helpers/deviceTransfer.js +2 -11
- package/dist/helpers/deviceTransfer.queries.d.ts +4 -0
- package/dist/helpers/deviceTransfer.queries.js +11 -0
- package/dist/helpers/devices.js +4 -61
- package/dist/helpers/devices.queries.d.ts +4 -1
- package/dist/helpers/devices.queries.js +52 -0
- package/dist/helpers/document_templates.js +6 -52
- package/dist/helpers/document_templates.queries.d.ts +9 -0
- package/dist/helpers/document_templates.queries.js +56 -0
- package/dist/helpers/documents_server.d.ts +226 -0
- package/dist/helpers/documents_server.js +38 -0
- package/dist/helpers/email.d.ts +0 -6
- package/dist/helpers/email.js +1 -19
- package/dist/helpers/embeddings.d.ts +0 -5
- package/dist/helpers/embeddings.js +2 -19
- package/dist/helpers/embeddings.queries.d.ts +7 -0
- package/dist/helpers/{embeddings.internal.js → embeddings.queries.js} +2 -2
- package/dist/helpers/eventUtils.d.ts +3 -12
- package/dist/helpers/eventUtils.js +0 -10
- package/dist/helpers/events.d.ts +0 -1
- package/dist/helpers/events.js +7 -107
- package/dist/helpers/events.queries.d.ts +17 -0
- package/dist/helpers/{events.internal.js → events.queries.js} +24 -15
- package/dist/helpers/health_metrics.js +3 -38
- package/dist/helpers/health_metrics.queries.d.ts +12 -0
- package/dist/helpers/health_metrics.queries.js +39 -0
- package/dist/helpers/heartbeats.js +4 -83
- package/dist/helpers/heartbeats.queries.d.ts +11 -0
- package/dist/helpers/heartbeats.queries.js +76 -0
- package/dist/helpers/herd_allowed_domains.js +2 -12
- package/dist/helpers/{herd_allowed_domains_internal.d.ts → herd_allowed_domains.queries.d.ts} +1 -1
- package/dist/helpers/{herd_allowed_domains_internal.js → herd_allowed_domains.queries.js} +2 -2
- package/dist/helpers/herd_credentials_server.d.ts +76 -0
- package/dist/helpers/herd_credentials_server.js +22 -0
- package/dist/helpers/herd_modules.queries.js +10 -7
- package/dist/helpers/herd_roles.js +13 -148
- package/dist/helpers/herd_roles.queries.d.ts +18 -0
- package/dist/helpers/{herd_roles_internal.js → herd_roles.queries.js} +28 -28
- package/dist/helpers/herds.js +5 -47
- package/dist/helpers/herds.queries.d.ts +8 -1
- package/dist/helpers/herds.queries.js +48 -0
- package/dist/helpers/invitations.js +7 -58
- package/dist/helpers/invitations.queries.d.ts +10 -0
- package/dist/helpers/{invitations_internal.js → invitations.queries.js} +12 -12
- package/dist/helpers/issuers.js +6 -52
- package/dist/helpers/issuers.queries.d.ts +9 -0
- package/dist/helpers/issuers.queries.js +53 -0
- package/dist/helpers/layers.js +2 -20
- package/dist/helpers/layers.queries.d.ts +2 -1
- package/dist/helpers/layers.queries.js +9 -13
- package/dist/helpers/lifecycle_server.d.ts +175 -0
- package/dist/helpers/lifecycle_server.js +38 -0
- package/dist/helpers/localizations.js +5 -42
- package/dist/helpers/localizations.queries.d.ts +8 -0
- package/dist/helpers/localizations.queries.js +45 -0
- package/dist/helpers/maintenance_requests_server.d.ts +124 -0
- package/dist/helpers/maintenance_requests_server.js +34 -0
- package/dist/helpers/manufacturers.js +5 -43
- package/dist/helpers/manufacturers.queries.d.ts +10 -0
- package/dist/helpers/manufacturers.queries.js +46 -0
- package/dist/helpers/media_urls.d.ts +13 -0
- package/dist/helpers/media_urls.js +21 -0
- package/dist/helpers/models.js +8 -80
- package/dist/helpers/models.queries.d.ts +13 -0
- package/dist/helpers/models.queries.js +79 -0
- package/dist/helpers/observations_server.d.ts +51 -0
- package/dist/helpers/observations_server.js +22 -0
- package/dist/helpers/operating_contexts.js +39 -154
- package/dist/helpers/operating_contexts.queries.d.ts +48 -0
- package/dist/helpers/operating_contexts.queries.js +223 -0
- package/dist/helpers/operators.js +4 -57
- package/dist/helpers/operators.queries.d.ts +7 -0
- package/dist/helpers/operators.queries.js +55 -0
- package/dist/helpers/parts.d.ts +0 -87
- package/dist/helpers/parts.js +4 -90
- package/dist/helpers/parts_server.d.ts +260 -0
- package/dist/helpers/parts_server.js +71 -0
- package/dist/helpers/pins_server.d.ts +118 -0
- package/dist/helpers/pins_server.js +38 -0
- package/dist/helpers/plans.js +4 -56
- package/dist/helpers/plans.queries.d.ts +4 -1
- package/dist/helpers/plans.queries.js +39 -12
- package/dist/helpers/points_for_user_server.d.ts +9 -0
- package/dist/helpers/points_for_user_server.js +14 -0
- package/dist/helpers/product_compatibilities.js +6 -78
- package/dist/helpers/product_compatibilities.queries.d.ts +9 -0
- package/dist/helpers/product_compatibilities.queries.js +83 -0
- package/dist/helpers/product_numbers.js +6 -55
- package/dist/helpers/product_numbers.queries.d.ts +9 -0
- package/dist/helpers/product_numbers.queries.js +58 -0
- package/dist/helpers/products.js +6 -54
- package/dist/helpers/products.queries.d.ts +11 -0
- package/dist/helpers/products.queries.js +58 -0
- package/dist/helpers/providers.js +5 -71
- package/dist/helpers/providers.queries.d.ts +5 -1
- package/dist/helpers/providers.queries.js +52 -11
- package/dist/helpers/pubsub_token_server.d.ts +1 -0
- package/dist/helpers/pubsub_token_server.js +5 -2
- package/dist/helpers/segmentations_sam3.js +5 -78
- package/dist/helpers/segmentations_sam3.queries.d.ts +16 -0
- package/dist/helpers/segmentations_sam3.queries.js +81 -0
- package/dist/helpers/sensor_poses_server.d.ts +98 -0
- package/dist/helpers/sensor_poses_server.js +26 -0
- package/dist/helpers/session_incidents_server.d.ts +106 -0
- package/dist/helpers/session_incidents_server.js +22 -0
- package/dist/helpers/session_summaries.d.ts +2 -0
- package/dist/helpers/session_summaries.js +7 -23
- package/dist/helpers/session_summaries.queries.d.ts +6 -3
- package/dist/helpers/session_summaries.queries.js +27 -0
- package/dist/helpers/sessions.js +8 -122
- package/dist/helpers/sessions.queries.d.ts +14 -2
- package/dist/helpers/sessions.queries.js +88 -1
- package/dist/helpers/storage.js +0 -1
- package/dist/helpers/supabase_auth.d.ts +6 -0
- package/dist/helpers/supabase_auth.js +37 -0
- package/dist/helpers/tags.d.ts +0 -1
- package/dist/helpers/tags.js +13 -559
- package/dist/helpers/tags.queries.d.ts +33 -0
- package/dist/helpers/tags.queries.js +454 -0
- package/dist/helpers/user_credentials_server.d.ts +76 -0
- package/dist/helpers/user_credentials_server.js +22 -0
- package/dist/helpers/users.d.ts +2 -2
- package/dist/helpers/users.js +8 -107
- package/dist/helpers/users.queries.d.ts +9 -1
- package/dist/helpers/users.queries.js +107 -0
- package/dist/helpers/versions_software.d.ts +3 -1
- package/dist/helpers/versions_software.js +24 -0
- package/dist/helpers/versions_software_server.d.ts +83 -4
- package/dist/helpers/versions_software_server.js +23 -50
- package/dist/helpers/zones.d.ts +1 -16
- package/dist/helpers/zones.js +4 -104
- package/dist/helpers/zones.queries.d.ts +6 -0
- package/dist/helpers/zones.queries.js +78 -0
- package/dist/hooks/useAuthorizedRealtimeTopics.js +8 -2
- package/dist/hooks/useInfiniteQuery.js +18 -14
- package/dist/hooks/useScoutRealtimeBroadcast.js +8 -6
- package/dist/hooks/useScoutRealtimeDocuments.js +3 -2
- package/dist/hooks/useScoutRefresh.d.ts +9 -25
- package/dist/hooks/useScoutRefresh.js +33 -213
- package/dist/providers/ScoutRefreshProvider.d.ts +1 -1
- package/dist/providers/ScoutRefreshProvider.js +56 -13
- package/dist/server/index.d.ts +77 -0
- package/dist/server/index.js +79 -0
- package/dist/server/middleware.d.ts +2 -0
- package/dist/server/middleware.js +2 -0
- package/dist/server/supabase.d.ts +2 -0
- package/dist/server/supabase.js +2 -0
- package/dist/store/api.d.ts +40 -40
- package/dist/store/api.js +38 -109
- package/dist/store/configureStore.d.ts +0 -55
- package/dist/store/configureStore.js +1 -8
- package/dist/store/hooks.js +1 -0
- package/dist/supabase/client.d.ts +3 -0
- package/dist/supabase/client.js +10 -0
- package/dist/supabase/middleware.d.ts +1 -0
- package/dist/supabase/middleware.js +6 -20
- package/dist/supabase/server.d.ts +7 -2
- package/dist/supabase/server.js +13 -1
- package/dist/types/db.d.ts +2 -2
- package/dist/types/index.d.ts +5 -0
- package/dist/types/index.js +5 -0
- package/package.json +53 -4
- package/dist/api_keys/index.d.ts +0 -1
- package/dist/api_keys/index.js +0 -1
- package/dist/helpers/artifacts.internal.d.ts +0 -22
- package/dist/helpers/client_abilities_jwt_keys_internal.d.ts +0 -9
- package/dist/helpers/client_abilities_jwt_keys_internal.js +0 -20
- package/dist/helpers/connectivity.internal.d.ts +0 -10
- package/dist/helpers/connectivity.internal.js +0 -47
- package/dist/helpers/credentials.d.ts +0 -9
- package/dist/helpers/credentials.js +0 -92
- package/dist/helpers/embeddings.internal.d.ts +0 -5
- package/dist/helpers/events.internal.d.ts +0 -13
- package/dist/helpers/herd_roles_internal.d.ts +0 -18
- package/dist/helpers/index.d.ts +0 -56
- package/dist/helpers/index.js +0 -56
- package/dist/helpers/invitations_internal.d.ts +0 -10
- package/dist/helpers/versions_software_internal.d.ts +0 -6
- package/dist/helpers/versions_software_internal.js +0 -53
- package/dist/hooks/useDeviceDisplayName.d.ts +0 -8
- package/dist/hooks/useDeviceDisplayName.js +0 -49
- package/dist/index.d.ts +0 -108
- package/dist/index.js +0 -114
- package/dist/supabase/index.d.ts +0 -2
- package/dist/supabase/index.js +0 -2
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useCallback, useEffect, useState } from "react";
|
|
2
|
+
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
3
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
4
|
+
import { refreshRealtimeAuth, subscribeToSupabaseAuth, } from "../helpers/supabase_auth";
|
|
4
5
|
import { useAuthorizedRealtimeTopics } from "./useAuthorizedRealtimeTopics";
|
|
5
6
|
const OPERATIONS = {
|
|
6
7
|
INSERT: EnumRealtimeOperation.INSERT,
|
|
@@ -19,6 +20,8 @@ function backoffDelayMs(attempt, initialMs, maxMs) {
|
|
|
19
20
|
export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, rowFilter) {
|
|
20
21
|
const { authErrorRetry = "stop", backoffInitialMs = DEFAULT_BACKOFF_INITIAL_MS, backoffMaxMs = DEFAULT_BACKOFF_MAX_MS, backoffMaxAttempts = Number.POSITIVE_INFINITY, } = options;
|
|
21
22
|
const [latestUpdate, setLatestUpdate] = useState(null);
|
|
23
|
+
const rowFilterRef = useRef(rowFilter);
|
|
24
|
+
rowFilterRef.current = rowFilter;
|
|
22
25
|
const subscribedTopics = useAuthorizedRealtimeTopics(topics);
|
|
23
26
|
const clearLatestUpdate = useCallback(() => setLatestUpdate(null), []);
|
|
24
27
|
useEffect(() => {
|
|
@@ -63,7 +66,7 @@ export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, r
|
|
|
63
66
|
const row = change.record ?? change.old_record;
|
|
64
67
|
if (operation === undefined || !row)
|
|
65
68
|
return;
|
|
66
|
-
if (
|
|
69
|
+
if (rowFilterRef.current && !rowFilterRef.current(row))
|
|
67
70
|
return;
|
|
68
71
|
setLatestUpdate({ data: row, operation, table: change.table });
|
|
69
72
|
});
|
|
@@ -86,7 +89,7 @@ export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, r
|
|
|
86
89
|
};
|
|
87
90
|
async function authenticateAndJoin(topicsToJoin) {
|
|
88
91
|
try {
|
|
89
|
-
await scoutSupabase
|
|
92
|
+
await refreshRealtimeAuth(scoutSupabase);
|
|
90
93
|
}
|
|
91
94
|
catch (error) {
|
|
92
95
|
console.warn("[scout-core realtime] failed to refresh auth", error);
|
|
@@ -106,7 +109,7 @@ export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, r
|
|
|
106
109
|
if (topicsToRetry.length > 0)
|
|
107
110
|
void authenticateAndJoin(topicsToRetry);
|
|
108
111
|
};
|
|
109
|
-
const
|
|
112
|
+
const unsubscribeAuth = subscribeToSupabaseAuth(scoutSupabase, (event) => {
|
|
110
113
|
if (event === "INITIAL_SESSION" ||
|
|
111
114
|
event === "SIGNED_IN" ||
|
|
112
115
|
event === "TOKEN_REFRESHED") {
|
|
@@ -116,7 +119,7 @@ export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, r
|
|
|
116
119
|
void authenticateAndJoin(subscribedTopics);
|
|
117
120
|
return () => {
|
|
118
121
|
cancelled = true;
|
|
119
|
-
|
|
122
|
+
unsubscribeAuth();
|
|
120
123
|
retryTimers.forEach((timer) => clearTimeout(timer));
|
|
121
124
|
retryTimers.clear();
|
|
122
125
|
channels.forEach((channel) => {
|
|
@@ -131,7 +134,6 @@ export function useScoutRealtimeBroadcast(scoutSupabase, topics, options = {}, r
|
|
|
131
134
|
backoffInitialMs,
|
|
132
135
|
backoffMaxMs,
|
|
133
136
|
backoffMaxAttempts,
|
|
134
|
-
rowFilter,
|
|
135
137
|
]);
|
|
136
138
|
return [latestUpdate, clearLatestUpdate];
|
|
137
139
|
}
|
|
@@ -13,12 +13,13 @@ const ALL_DOCUMENT_CHANNELS = [
|
|
|
13
13
|
export function useScoutRealtimeDocuments(scoutSupabase, channels = ALL_DOCUMENT_CHANNELS, options) {
|
|
14
14
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
15
15
|
const userId = useSelector((state) => state.scout.user?.id ?? null);
|
|
16
|
-
const
|
|
16
|
+
const channelsKey = channels.join("|");
|
|
17
|
+
const topics = useMemo(() => channelsKey.split("|").flatMap((channel) => {
|
|
17
18
|
if (channel === "product")
|
|
18
19
|
return ["product_documents_changes"];
|
|
19
20
|
if (channel === "own")
|
|
20
21
|
return userId ? [`user_${userId}-documents`] : [];
|
|
21
22
|
return activeHerdId ? [`${activeHerdId}-${channel}_documents`] : [];
|
|
22
|
-
}), [
|
|
23
|
+
}), [channelsKey, activeHerdId, userId]);
|
|
23
24
|
return useScoutRealtimeBroadcast(scoutSupabase, topics, options);
|
|
24
25
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
-
import { Database } from "../types/supabase";
|
|
1
|
+
import type { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import type { Database } from "../types/supabase";
|
|
3
3
|
export interface UseScoutRefreshOptions {
|
|
4
4
|
supabase?: SupabaseClient<Database>;
|
|
5
5
|
autoRefresh?: boolean;
|
|
@@ -8,32 +8,16 @@ export interface UseScoutRefreshOptions {
|
|
|
8
8
|
cacheTtlMs?: number;
|
|
9
9
|
onlineRefetchMinIntervalMs?: number;
|
|
10
10
|
}
|
|
11
|
+
export interface ScoutRefreshRequest {
|
|
12
|
+
force?: boolean;
|
|
13
|
+
}
|
|
11
14
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
* @param options - Configuration options for the refresh behavior
|
|
15
|
-
* @param options.autoRefresh - Whether to automatically refresh on mount (default: true)
|
|
16
|
-
* @param options.onRefreshComplete - Callback function called when refresh completes
|
|
17
|
-
* @param options.cacheFirst - Whether to load from cache first, then refresh (default: true)
|
|
18
|
-
* @param options.cacheTtlMs - Cache time-to-live in milliseconds (default: 24 hours)
|
|
19
|
-
* @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 15s)
|
|
20
|
-
* @param options.supabase - Optional shared browser client; when omitted, the hook creates its own via `createBrowserClient`
|
|
21
|
-
*
|
|
22
|
-
* @returns Object containing:
|
|
23
|
-
* - handleRefresh: Function to manually trigger a refresh
|
|
24
|
-
* - clearCache: Function to clear the cache
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
* ```tsx
|
|
28
|
-
* const { handleRefresh, clearCache } = useScoutRefresh({
|
|
29
|
-
* cacheFirst: true,
|
|
30
|
-
* cacheTtlMs: 10 * 60 * 1000 // 10 minutes
|
|
31
|
-
* });
|
|
15
|
+
* Refreshes Scout state from cache and the API.
|
|
32
16
|
*
|
|
33
|
-
*
|
|
34
|
-
*
|
|
17
|
+
* Manual refreshes force an API request by default. Automatic mount refreshes
|
|
18
|
+
* finish from a fresh cache without requesting the API.
|
|
35
19
|
*/
|
|
36
20
|
export declare function useScoutRefresh(options?: UseScoutRefreshOptions): {
|
|
37
|
-
handleRefresh: () => Promise<void>;
|
|
21
|
+
handleRefresh: ({ force }?: ScoutRefreshRequest) => Promise<void>;
|
|
38
22
|
clearCache: () => Promise<void>;
|
|
39
23
|
};
|
|
@@ -1,93 +1,60 @@
|
|
|
1
|
-
|
|
1
|
+
"use client";
|
|
2
|
+
import { useEffect, useCallback, useRef, useMemo, startTransition, } from "react";
|
|
2
3
|
import { useAppDispatch } from "../store/hooks";
|
|
3
4
|
import { EnumScoutStateStatus, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setUser, setDataSource, setDataSourceInfo, } from "../store/scout";
|
|
4
|
-
import { EnumHerdModulesLoadingState } from "../types/herd_module";
|
|
5
|
-
import {
|
|
5
|
+
import { EnumHerdModulesLoadingState, } from "../types/herd_module";
|
|
6
|
+
import { load_herd_modules_query } from "../helpers/herd_modules.queries";
|
|
6
7
|
import { scoutCache } from "../helpers/cache";
|
|
7
8
|
import { EnumDataSource } from "../types/data_source";
|
|
8
9
|
import { EnumWebResponse } from "../types/requests";
|
|
9
|
-
import {
|
|
10
|
+
import { createScoutBrowserClient } from "../supabase/client";
|
|
10
11
|
function dispatchInTransition(dispatch, action) {
|
|
11
12
|
startTransition(() => {
|
|
12
13
|
dispatch(action);
|
|
13
14
|
});
|
|
14
15
|
}
|
|
15
16
|
/**
|
|
16
|
-
*
|
|
17
|
+
* Refreshes Scout state from cache and the API.
|
|
17
18
|
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
20
|
-
* @param options.onRefreshComplete - Callback function called when refresh completes
|
|
21
|
-
* @param options.cacheFirst - Whether to load from cache first, then refresh (default: true)
|
|
22
|
-
* @param options.cacheTtlMs - Cache time-to-live in milliseconds (default: 24 hours)
|
|
23
|
-
* @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 15s)
|
|
24
|
-
* @param options.supabase - Optional shared browser client; when omitted, the hook creates its own via `createBrowserClient`
|
|
25
|
-
*
|
|
26
|
-
* @returns Object containing:
|
|
27
|
-
* - handleRefresh: Function to manually trigger a refresh
|
|
28
|
-
* - clearCache: Function to clear the cache
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
* ```tsx
|
|
32
|
-
* const { handleRefresh, clearCache } = useScoutRefresh({
|
|
33
|
-
* cacheFirst: true,
|
|
34
|
-
* cacheTtlMs: 10 * 60 * 1000 // 10 minutes
|
|
35
|
-
* });
|
|
36
|
-
*
|
|
37
|
-
* // Timing stats are available in Redux store via selectors
|
|
38
|
-
* ```
|
|
19
|
+
* Manual refreshes force an API request by default. Automatic mount refreshes
|
|
20
|
+
* finish from a fresh cache without requesting the API.
|
|
39
21
|
*/
|
|
40
22
|
export function useScoutRefresh(options = {}) {
|
|
41
|
-
const { supabase: supabaseOption, autoRefresh = true, onRefreshComplete, cacheFirst = true, cacheTtlMs = 24 * 60 * 60 * 1000,
|
|
42
|
-
onlineRefetchMinIntervalMs = 15 * 1000, // 15 seconds
|
|
43
|
-
} = options;
|
|
23
|
+
const { supabase: supabaseOption, autoRefresh = true, onRefreshComplete, cacheFirst = true, cacheTtlMs = 24 * 60 * 60 * 1000, onlineRefetchMinIntervalMs = 15 * 1000, } = options;
|
|
44
24
|
const dispatch = useAppDispatch();
|
|
45
25
|
const refreshInProgressRef = useRef(false);
|
|
46
26
|
const lastQueryAtRef = useRef(0);
|
|
27
|
+
const onRefreshCompleteRef = useRef(onRefreshComplete);
|
|
28
|
+
useEffect(() => {
|
|
29
|
+
onRefreshCompleteRef.current = onRefreshComplete;
|
|
30
|
+
}, [onRefreshComplete]);
|
|
47
31
|
const supabase = useMemo(() => {
|
|
48
32
|
if (supabaseOption) {
|
|
49
33
|
return supabaseOption;
|
|
50
34
|
}
|
|
51
|
-
return
|
|
35
|
+
return createScoutBrowserClient();
|
|
52
36
|
}, [supabaseOption]);
|
|
53
|
-
// Refs to store timing measurements
|
|
54
|
-
const timingRefs = useRef({
|
|
55
|
-
startTime: 0,
|
|
56
|
-
herdModulesDuration: 0,
|
|
57
|
-
userApiDuration: 0,
|
|
58
|
-
dataProcessingDuration: 0,
|
|
59
|
-
cacheLoadDuration: 0,
|
|
60
|
-
cacheSaveDuration: 0,
|
|
61
|
-
});
|
|
62
|
-
// Helper function for deep comparison of objects
|
|
63
|
-
// Helper function to handle IndexedDB errors - memoized for stability
|
|
64
37
|
const handleIndexedDbError = useCallback(async (error, operation, retryFn) => {
|
|
65
38
|
if (error instanceof Error &&
|
|
66
39
|
(error.message.includes("object store") ||
|
|
67
40
|
error.message.includes("NotFoundError"))) {
|
|
68
|
-
console.log(`[useScoutRefresh] Attempting database reset due to ${operation} error...`);
|
|
69
41
|
try {
|
|
70
42
|
await scoutCache.resetDatabase();
|
|
71
|
-
console.log("[useScoutRefresh] Database reset successful");
|
|
72
43
|
if (retryFn) {
|
|
73
44
|
await retryFn();
|
|
74
|
-
console.log(`[useScoutRefresh] ${operation} successful after database reset`);
|
|
75
45
|
}
|
|
76
46
|
}
|
|
77
47
|
catch (resetError) {
|
|
78
|
-
console.error(`[useScoutRefresh]
|
|
48
|
+
console.error(`[useScoutRefresh] ${operation} reset and retry failed:`, resetError);
|
|
79
49
|
}
|
|
80
50
|
}
|
|
81
51
|
}, []);
|
|
82
|
-
const handleRefresh = useCallback(async () => {
|
|
83
|
-
// Prevent concurrent refresh calls
|
|
52
|
+
const handleRefresh = useCallback(async ({ force = true } = {}) => {
|
|
84
53
|
if (refreshInProgressRef.current) {
|
|
85
|
-
console.warn("[useScoutRefresh] Refresh already in progress, skipping");
|
|
86
54
|
return;
|
|
87
55
|
}
|
|
88
56
|
refreshInProgressRef.current = true;
|
|
89
57
|
const startTime = Date.now();
|
|
90
|
-
timingRefs.current.startTime = startTime;
|
|
91
58
|
const isOffline = typeof navigator === "undefined" || !navigator.onLine;
|
|
92
59
|
const fetchUserWithOneRetry = async () => {
|
|
93
60
|
const startTotal = Date.now();
|
|
@@ -99,7 +66,6 @@ export function useScoutRefresh(options = {}) {
|
|
|
99
66
|
throw new Error("Invalid user response");
|
|
100
67
|
}
|
|
101
68
|
const totalMs = Date.now() - startTotal;
|
|
102
|
-
timingRefs.current.userApiDuration = totalMs;
|
|
103
69
|
dispatch(setUserApiDuration(totalMs));
|
|
104
70
|
dispatchInTransition(dispatch, setUser(data.user));
|
|
105
71
|
return data.user;
|
|
@@ -110,47 +76,20 @@ export function useScoutRefresh(options = {}) {
|
|
|
110
76
|
}
|
|
111
77
|
throw lastError;
|
|
112
78
|
};
|
|
113
|
-
const fetchUserWithOneRetryBackground = async () => {
|
|
114
|
-
const startTotal = Date.now();
|
|
115
|
-
for (let attempt = 0; attempt < 2; attempt++) {
|
|
116
|
-
try {
|
|
117
|
-
const { data } = await supabase.auth.getUser();
|
|
118
|
-
if (data.user) {
|
|
119
|
-
const totalMs = Date.now() - startTotal;
|
|
120
|
-
timingRefs.current.userApiDuration = totalMs;
|
|
121
|
-
dispatch(setUserApiDuration(totalMs));
|
|
122
|
-
dispatchInTransition(dispatch, setUser(data.user));
|
|
123
|
-
return data.user;
|
|
124
|
-
}
|
|
125
|
-
}
|
|
126
|
-
catch {
|
|
127
|
-
// retry once
|
|
128
|
-
}
|
|
129
|
-
}
|
|
130
|
-
const totalMs = Date.now() - startTotal;
|
|
131
|
-
timingRefs.current.userApiDuration = totalMs;
|
|
132
|
-
dispatch(setUserApiDuration(totalMs));
|
|
133
|
-
return null;
|
|
134
|
-
};
|
|
135
79
|
try {
|
|
136
80
|
dispatch(setStatus(EnumScoutStateStatus.LOADING));
|
|
137
81
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.LOADING));
|
|
138
82
|
let cachedHerdModules = null;
|
|
139
83
|
let cachedContentHash;
|
|
140
|
-
let cacheLoadDuration = 0;
|
|
141
|
-
// Step 1: Load from cache first if enabled
|
|
142
84
|
if (cacheFirst) {
|
|
143
85
|
const cacheStartTime = Date.now();
|
|
144
86
|
try {
|
|
145
87
|
const cacheResult = await scoutCache.getHerdModules();
|
|
146
|
-
cacheLoadDuration = Date.now() - cacheStartTime;
|
|
147
|
-
timingRefs.current.cacheLoadDuration = cacheLoadDuration;
|
|
88
|
+
const cacheLoadDuration = Date.now() - cacheStartTime;
|
|
148
89
|
dispatch(setCacheLoadDuration(cacheLoadDuration));
|
|
149
90
|
if (cacheResult.data && cacheResult.data.length > 0) {
|
|
150
91
|
cachedHerdModules = cacheResult.data;
|
|
151
92
|
cachedContentHash = cacheResult.metadata?.etag;
|
|
152
|
-
console.log(`[useScoutRefresh] Loaded ${cachedHerdModules.length} herd modules from cache in ${cacheLoadDuration}ms (age: ${Math.round(cacheResult.age / 1000)}s, stale: ${cacheResult.isStale})`);
|
|
153
|
-
// Set data source to CACHE initially
|
|
154
93
|
dispatch(setDataSource(EnumDataSource.CACHE));
|
|
155
94
|
dispatch(setDataSourceInfo({
|
|
156
95
|
source: EnumDataSource.CACHE,
|
|
@@ -158,98 +97,25 @@ export function useScoutRefresh(options = {}) {
|
|
|
158
97
|
cacheAge: cacheResult.age,
|
|
159
98
|
isStale: cacheResult.isStale,
|
|
160
99
|
}));
|
|
161
|
-
// Update the store with cached data
|
|
162
|
-
console.log(`[useScoutRefresh] Updating store with cached herd modules`);
|
|
163
100
|
dispatchInTransition(dispatch, setHerdModules({
|
|
164
101
|
modules: cachedHerdModules,
|
|
165
102
|
contentHash: cachedContentHash,
|
|
166
103
|
}));
|
|
167
104
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
168
|
-
|
|
169
|
-
if (!cacheResult.isStale) {
|
|
170
|
-
if (!isOffline) {
|
|
171
|
-
// Background fetch fresh data without blocking
|
|
172
|
-
(async () => {
|
|
173
|
-
try {
|
|
174
|
-
const userPromise = fetchUserWithOneRetryBackground();
|
|
175
|
-
let backgroundHerdModulesResult;
|
|
176
|
-
try {
|
|
177
|
-
const start = Date.now();
|
|
178
|
-
const result = await server_load_herd_modules();
|
|
179
|
-
const totalDuration = Date.now() - start;
|
|
180
|
-
const serverDuration = result.server_processing_time_ms || totalDuration;
|
|
181
|
-
const clientOverhead = totalDuration - serverDuration;
|
|
182
|
-
console.log(`[useScoutRefresh] Background API timing breakdown:`);
|
|
183
|
-
console.log(` - Server processing: ${serverDuration}ms`);
|
|
184
|
-
console.log(` - Client overhead: ${clientOverhead}ms`);
|
|
185
|
-
console.log(` - Total request: ${totalDuration}ms`);
|
|
186
|
-
timingRefs.current.herdModulesDuration = serverDuration;
|
|
187
|
-
dispatch(setHerdModulesApiServerProcessingDuration(serverDuration));
|
|
188
|
-
dispatch(setHerdModulesApiTotalRequestDuration(totalDuration));
|
|
189
|
-
backgroundHerdModulesResult = result;
|
|
190
|
-
}
|
|
191
|
-
catch (e) {
|
|
192
|
-
await userPromise.catch(() => { });
|
|
193
|
-
throw e;
|
|
194
|
-
}
|
|
195
|
-
const backgroundUserResult = await userPromise;
|
|
196
|
-
// Validate background responses
|
|
197
|
-
if (backgroundHerdModulesResult.status ===
|
|
198
|
-
EnumWebResponse.SUCCESS &&
|
|
199
|
-
Array.isArray(backgroundHerdModulesResult.data) &&
|
|
200
|
-
backgroundUserResult) {
|
|
201
|
-
const backgroundContentHash = backgroundHerdModulesResult.content_hash;
|
|
202
|
-
// Update cache with fresh data
|
|
203
|
-
try {
|
|
204
|
-
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs, backgroundContentHash);
|
|
205
|
-
}
|
|
206
|
-
catch (cacheError) {
|
|
207
|
-
console.warn("[useScoutRefresh] Background cache save failed:", cacheError);
|
|
208
|
-
await handleIndexedDbError(cacheError, "background cache save", async () => {
|
|
209
|
-
if (backgroundHerdModulesResult.data) {
|
|
210
|
-
await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs, backgroundContentHash);
|
|
211
|
-
}
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
// Update store with fresh data from background request
|
|
215
|
-
console.log(`[useScoutRefresh] Updating store with background herd modules`);
|
|
216
|
-
dispatchInTransition(dispatch, setHerdModules({
|
|
217
|
-
modules: backgroundHerdModulesResult.data,
|
|
218
|
-
contentHash: backgroundContentHash,
|
|
219
|
-
}));
|
|
220
|
-
// Update data source to DATABASE
|
|
221
|
-
dispatch(setDataSource(EnumDataSource.DATABASE));
|
|
222
|
-
dispatch(setDataSourceInfo({
|
|
223
|
-
source: EnumDataSource.DATABASE,
|
|
224
|
-
timestamp: Date.now(),
|
|
225
|
-
}));
|
|
226
|
-
}
|
|
227
|
-
else {
|
|
228
|
-
console.warn("[useScoutRefresh] Background fetch returned invalid data");
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
catch (backgroundError) {
|
|
232
|
-
console.warn("[useScoutRefresh] Background fetch failed:", backgroundError);
|
|
233
|
-
}
|
|
234
|
-
})();
|
|
235
|
-
}
|
|
105
|
+
if (!cacheResult.isStale && !force) {
|
|
236
106
|
const totalDuration = Date.now() - startTime;
|
|
237
107
|
dispatch(setHerdModulesLoadedInMs(totalDuration));
|
|
238
108
|
dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
|
|
239
|
-
|
|
109
|
+
onRefreshCompleteRef.current?.();
|
|
240
110
|
return;
|
|
241
111
|
}
|
|
242
112
|
}
|
|
243
|
-
else {
|
|
244
|
-
}
|
|
245
113
|
}
|
|
246
114
|
catch (cacheError) {
|
|
247
115
|
console.warn("[useScoutRefresh] Cache load failed:", cacheError);
|
|
248
116
|
await handleIndexedDbError(cacheError, "cache load");
|
|
249
|
-
// Continue with API call
|
|
250
117
|
}
|
|
251
118
|
}
|
|
252
|
-
// When offline, skip network/auth; use cache if available
|
|
253
119
|
if (isOffline) {
|
|
254
120
|
if (cachedHerdModules && cachedHerdModules.length > 0) {
|
|
255
121
|
dispatch(setDataSource(EnumDataSource.CACHE));
|
|
@@ -273,22 +139,18 @@ export function useScoutRefresh(options = {}) {
|
|
|
273
139
|
}
|
|
274
140
|
dispatch(setHerdModulesLoadedInMs(Date.now() - startTime));
|
|
275
141
|
dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
|
|
276
|
-
|
|
277
|
-
refreshInProgressRef.current = false;
|
|
278
|
-
lastQueryAtRef.current = Date.now();
|
|
142
|
+
onRefreshCompleteRef.current?.();
|
|
279
143
|
return;
|
|
280
144
|
}
|
|
281
|
-
// Step 2: Load fresh data from API (user resolves independently; Redux gets user as soon as getUser returns)
|
|
282
|
-
const parallelStartTime = Date.now();
|
|
283
145
|
const userPromise = fetchUserWithOneRetry();
|
|
284
146
|
let herdModulesResult;
|
|
285
147
|
try {
|
|
286
148
|
herdModulesResult = await (async () => {
|
|
287
149
|
const start = Date.now();
|
|
288
|
-
const result = await
|
|
150
|
+
const result = await load_herd_modules_query(supabase);
|
|
289
151
|
const totalDuration = Date.now() - start;
|
|
290
152
|
const serverDuration = result.server_processing_time_ms || totalDuration;
|
|
291
|
-
return { result, totalDuration, serverDuration
|
|
153
|
+
return { result, totalDuration, serverDuration };
|
|
292
154
|
})();
|
|
293
155
|
}
|
|
294
156
|
catch (e) {
|
|
@@ -296,121 +158,79 @@ export function useScoutRefresh(options = {}) {
|
|
|
296
158
|
throw e;
|
|
297
159
|
}
|
|
298
160
|
await userPromise;
|
|
299
|
-
const parallelDuration = Date.now() - parallelStartTime;
|
|
300
|
-
console.log(`[useScoutRefresh] API requests completed in ${parallelDuration}ms`);
|
|
301
|
-
// Extract results and timing
|
|
302
161
|
const herdModulesResponse = herdModulesResult.result;
|
|
303
162
|
const herdModulesServerDuration = herdModulesResult.serverDuration;
|
|
304
163
|
const herdModulesTotalDuration = herdModulesResult.totalDuration;
|
|
305
|
-
const clientOverhead = herdModulesTotalDuration - herdModulesServerDuration;
|
|
306
|
-
console.log(`[useScoutRefresh] Fresh API timing breakdown:`);
|
|
307
|
-
console.log(` - Server processing: ${herdModulesServerDuration}ms`);
|
|
308
|
-
console.log(` - Client overhead: ${clientOverhead}ms`);
|
|
309
|
-
console.log(` - Total request: ${herdModulesTotalDuration}ms`);
|
|
310
|
-
// Store timing values
|
|
311
|
-
timingRefs.current.herdModulesDuration = herdModulesServerDuration;
|
|
312
|
-
// Dispatch timing actions
|
|
313
164
|
dispatch(setHerdModulesApiServerProcessingDuration(herdModulesServerDuration));
|
|
314
165
|
dispatch(setHerdModulesApiTotalRequestDuration(herdModulesTotalDuration));
|
|
315
|
-
// Validate API responses
|
|
316
|
-
const validationStartTime = Date.now();
|
|
317
166
|
if (herdModulesResponse.status !== EnumWebResponse.SUCCESS ||
|
|
318
167
|
!Array.isArray(herdModulesResponse.data)) {
|
|
319
168
|
throw new Error("Invalid herd modules response");
|
|
320
169
|
}
|
|
321
|
-
const
|
|
322
|
-
console.log(`[useScoutRefresh] Data validation took: ${validationDuration}ms`);
|
|
323
|
-
// Use the validated data
|
|
324
|
-
const compatible_new_herd_modules = herdModulesResponse.data;
|
|
170
|
+
const freshHerdModules = herdModulesResponse.data;
|
|
325
171
|
const freshContentHash = herdModulesResponse.content_hash;
|
|
326
|
-
// Set data source to DATABASE
|
|
327
172
|
dispatch(setDataSource(EnumDataSource.DATABASE));
|
|
328
173
|
dispatch(setDataSourceInfo({
|
|
329
174
|
source: EnumDataSource.DATABASE,
|
|
330
175
|
timestamp: Date.now(),
|
|
331
176
|
}));
|
|
332
|
-
// Step 3: Update cache with fresh data
|
|
333
|
-
const cacheSaveStartTime = Date.now();
|
|
334
177
|
try {
|
|
335
|
-
await scoutCache.setHerdModules(
|
|
336
|
-
const cacheSaveDuration = Date.now() - cacheSaveStartTime;
|
|
337
|
-
timingRefs.current.cacheSaveDuration = cacheSaveDuration;
|
|
338
|
-
console.log(`[useScoutRefresh] Cache updated in ${cacheSaveDuration}ms with TTL: ${Math.round(cacheTtlMs / 1000)}s`);
|
|
178
|
+
await scoutCache.setHerdModules(freshHerdModules, cacheTtlMs, freshContentHash);
|
|
339
179
|
}
|
|
340
180
|
catch (cacheError) {
|
|
341
181
|
console.warn("[useScoutRefresh] Cache save failed:", cacheError);
|
|
342
182
|
await handleIndexedDbError(cacheError, "cache save", async () => {
|
|
343
|
-
await scoutCache.setHerdModules(
|
|
183
|
+
await scoutCache.setHerdModules(freshHerdModules, cacheTtlMs, freshContentHash);
|
|
344
184
|
});
|
|
345
185
|
}
|
|
346
|
-
// Step 4: Update store with fresh data (reducer skips no-op updates)
|
|
347
186
|
const dataProcessingStartTime = Date.now();
|
|
348
|
-
// Update store with new data
|
|
349
|
-
console.log(`[useScoutRefresh] Updating store with fresh herd modules`);
|
|
350
187
|
dispatchInTransition(dispatch, setHerdModules({
|
|
351
|
-
modules:
|
|
188
|
+
modules: freshHerdModules,
|
|
352
189
|
contentHash: freshContentHash,
|
|
353
190
|
}));
|
|
354
191
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
|
|
355
192
|
const dataProcessingDuration = Date.now() - dataProcessingStartTime;
|
|
356
|
-
timingRefs.current.dataProcessingDuration = dataProcessingDuration;
|
|
357
193
|
dispatch(setDataProcessingDuration(dataProcessingDuration));
|
|
358
194
|
const loadingDuration = Date.now() - startTime;
|
|
359
195
|
dispatch(setHerdModulesLoadedInMs(loadingDuration));
|
|
360
196
|
dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
|
|
361
|
-
|
|
362
|
-
console.log(`[useScoutRefresh] Refresh completed in ${loadingDuration}ms (Server: ${herdModulesServerDuration}ms, Total API: ${herdModulesTotalDuration}ms)`);
|
|
363
|
-
onRefreshComplete?.();
|
|
197
|
+
onRefreshCompleteRef.current?.();
|
|
364
198
|
}
|
|
365
199
|
catch (error) {
|
|
366
200
|
const loadingDuration = Date.now() - startTime;
|
|
367
201
|
console.error("Error refreshing scout data:", error);
|
|
368
|
-
// Set data source to UNKNOWN on error
|
|
369
202
|
dispatch(setDataSource(EnumDataSource.UNKNOWN));
|
|
370
203
|
dispatch(setDataSourceInfo({
|
|
371
204
|
source: EnumDataSource.UNKNOWN,
|
|
372
205
|
timestamp: Date.now(),
|
|
373
206
|
}));
|
|
374
|
-
// Ensure consistent state updates on error
|
|
375
207
|
dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.UNSUCCESSFULLY_LOADED));
|
|
376
208
|
dispatch(setHerdModulesLoadedInMs(loadingDuration));
|
|
377
209
|
dispatch(setStatus(EnumScoutStateStatus.DONE_LOADING));
|
|
378
|
-
|
|
379
|
-
console.log(`[useScoutRefresh] Refresh failed after ${loadingDuration}ms`);
|
|
380
|
-
// Call completion callback even on error for consistency
|
|
381
|
-
onRefreshComplete?.();
|
|
210
|
+
onRefreshCompleteRef.current?.();
|
|
382
211
|
}
|
|
383
212
|
finally {
|
|
384
213
|
refreshInProgressRef.current = false;
|
|
385
214
|
lastQueryAtRef.current = Date.now();
|
|
386
215
|
}
|
|
387
|
-
}, [
|
|
388
|
-
dispatch,
|
|
389
|
-
supabase,
|
|
390
|
-
onRefreshComplete,
|
|
391
|
-
cacheFirst,
|
|
392
|
-
cacheTtlMs,
|
|
393
|
-
handleIndexedDbError,
|
|
394
|
-
]);
|
|
216
|
+
}, [dispatch, supabase, cacheFirst, cacheTtlMs, handleIndexedDbError]);
|
|
395
217
|
useEffect(() => {
|
|
396
218
|
if (autoRefresh) {
|
|
397
|
-
handleRefresh();
|
|
219
|
+
void handleRefresh({ force: false });
|
|
398
220
|
}
|
|
399
221
|
}, [autoRefresh, handleRefresh]);
|
|
400
|
-
// Full refetch when nav goes online, only if min interval since last query has passed
|
|
401
222
|
useEffect(() => {
|
|
402
|
-
if (typeof window === "undefined")
|
|
223
|
+
if (!autoRefresh || typeof window === "undefined")
|
|
403
224
|
return;
|
|
404
225
|
const handleOnline = () => {
|
|
405
226
|
const now = Date.now();
|
|
406
227
|
if (now - lastQueryAtRef.current >= onlineRefetchMinIntervalMs) {
|
|
407
|
-
handleRefresh();
|
|
228
|
+
void handleRefresh({ force: true });
|
|
408
229
|
}
|
|
409
230
|
};
|
|
410
231
|
window.addEventListener("online", handleOnline);
|
|
411
232
|
return () => window.removeEventListener("online", handleOnline);
|
|
412
|
-
}, [handleRefresh, onlineRefetchMinIntervalMs]);
|
|
413
|
-
// Utility function to clear cache
|
|
233
|
+
}, [autoRefresh, handleRefresh, onlineRefetchMinIntervalMs]);
|
|
414
234
|
const clearCache = useCallback(async () => {
|
|
415
235
|
try {
|
|
416
236
|
await scoutCache.clearHerdModules();
|
|
@@ -33,4 +33,4 @@ export interface ScoutRefreshProviderProps extends UseScoutRefreshOptions {
|
|
|
33
33
|
children: ReactNode;
|
|
34
34
|
abilityParams?: ScoutRefreshAbilityParams;
|
|
35
35
|
}
|
|
36
|
-
export declare function ScoutRefreshProvider({ children, abilityParams, ...refreshOptions }: ScoutRefreshProviderProps): import("react/jsx-runtime").JSX.Element;
|
|
36
|
+
export declare function ScoutRefreshProvider({ children, abilityParams, supabase: supabaseOption, ...refreshOptions }: ScoutRefreshProviderProps): import("react/jsx-runtime").JSX.Element;
|