@adventurelabs/scout-core 1.4.51 → 1.4.53

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.
@@ -1,6 +1,6 @@
1
1
  import { ISessionSummary } from "../types/db";
2
2
  import { IWebResponseCompatible } from "../types/requests";
3
3
  import { SupabaseClient } from "@supabase/supabase-js";
4
- export declare function server_get_session_summaries_by_herd(herd_id: number, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionSummary>>;
5
- export declare function server_get_session_summaries_by_device(device_id: number, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionSummary>>;
6
- export declare function server_get_session_summaries_with_filters(herd_id?: number, device_id?: number, start_date?: string, end_date?: string, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionSummary>>;
4
+ export declare function server_get_session_summaries_by_herd(herd_id: number, client?: SupabaseClient, min_duration_minutes_caller?: number, min_distance_meters_caller?: number): Promise<IWebResponseCompatible<ISessionSummary>>;
5
+ export declare function server_get_session_summaries_by_device(device_id: number, client?: SupabaseClient, min_duration_minutes_caller?: number, min_distance_meters_caller?: number): Promise<IWebResponseCompatible<ISessionSummary>>;
6
+ export declare function server_get_session_summaries_with_filters(herd_id?: number, device_id?: number, start_date?: string, end_date?: string, client?: SupabaseClient, min_duration_minutes_caller?: number, min_distance_meters_caller?: number): Promise<IWebResponseCompatible<ISessionSummary>>;
@@ -1,13 +1,15 @@
1
1
  "use server";
2
2
  import { newServerClient } from "../supabase/server";
3
3
  import { IWebResponse, } from "../types/requests";
4
- export async function server_get_session_summaries_by_herd(herd_id, client) {
4
+ export async function server_get_session_summaries_by_herd(herd_id, client, min_duration_minutes_caller, min_distance_meters_caller) {
5
5
  const supabase = client || (await newServerClient());
6
6
  const { data, error } = await supabase.rpc("get_session_summaries", {
7
7
  start_date_caller: undefined,
8
8
  end_date_caller: undefined,
9
9
  device_id_caller: undefined,
10
10
  herd_id_caller: herd_id,
11
+ min_duration_minutes_caller,
12
+ min_distance_meters_caller,
11
13
  });
12
14
  if (error) {
13
15
  return IWebResponse.error(error.message).to_compatible();
@@ -17,13 +19,15 @@ export async function server_get_session_summaries_by_herd(herd_id, client) {
17
19
  }
18
20
  return IWebResponse.success(data).to_compatible();
19
21
  }
20
- export async function server_get_session_summaries_by_device(device_id, client) {
22
+ export async function server_get_session_summaries_by_device(device_id, client, min_duration_minutes_caller, min_distance_meters_caller) {
21
23
  const supabase = client || (await newServerClient());
22
24
  const { data, error } = await supabase.rpc("get_session_summaries", {
23
25
  start_date_caller: undefined,
24
26
  end_date_caller: undefined,
25
27
  device_id_caller: device_id,
26
28
  herd_id_caller: undefined,
29
+ min_duration_minutes_caller,
30
+ min_distance_meters_caller,
27
31
  });
28
32
  if (error) {
29
33
  return IWebResponse.error(error.message).to_compatible();
@@ -33,13 +37,15 @@ export async function server_get_session_summaries_by_device(device_id, client)
33
37
  }
34
38
  return IWebResponse.success(data).to_compatible();
35
39
  }
36
- export async function server_get_session_summaries_with_filters(herd_id, device_id, start_date, end_date, client) {
40
+ export async function server_get_session_summaries_with_filters(herd_id, device_id, start_date, end_date, client, min_duration_minutes_caller, min_distance_meters_caller) {
37
41
  const supabase = client || (await newServerClient());
38
42
  const { data, error } = await supabase.rpc("get_session_summaries", {
39
43
  start_date_caller: start_date || undefined,
40
44
  end_date_caller: end_date || undefined,
41
45
  device_id_caller: device_id || undefined,
42
46
  herd_id_caller: herd_id || undefined,
47
+ min_duration_minutes_caller,
48
+ min_distance_meters_caller,
43
49
  });
44
50
  if (error) {
45
51
  return IWebResponse.error(error.message).to_compatible();
@@ -2,8 +2,8 @@ import { ISessionWithCoordinates, ISessionUsageOverTime, IEventAndTagsPrettyLoca
2
2
  import { IWebResponseCompatible } from "../types/requests";
3
3
  import { SupabaseClient } from "@supabase/supabase-js";
4
4
  export declare function server_get_session_by_id(sessionId: number, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionWithCoordinates | null>>;
5
- export declare function server_get_session_usage_over_time_by_herd(herd_id: number, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionUsageOverTime>>;
6
- export declare function server_get_session_usage_over_time_by_device(device_id: number, client?: SupabaseClient): Promise<IWebResponseCompatible<ISessionUsageOverTime>>;
5
+ export declare function server_get_session_usage_over_time_by_herd(herd_id: number, client?: SupabaseClient, min_duration_minutes_caller?: number, min_distance_meters_caller?: number): Promise<IWebResponseCompatible<ISessionUsageOverTime>>;
6
+ export declare function server_get_session_usage_over_time_by_device(device_id: number, client?: SupabaseClient, min_duration_minutes_caller?: number, min_distance_meters_caller?: number): Promise<IWebResponseCompatible<ISessionUsageOverTime>>;
7
7
  export declare function server_get_events_and_tags_by_session_id(sessionId: number, limit?: number, offset?: number): Promise<IWebResponseCompatible<IEventAndTagsPrettyLocation[]>>;
8
8
  export declare function server_insert_session(sessions: SessionInsert | SessionInsert[], client?: SupabaseClient): Promise<IWebResponseCompatible<ISession[]>>;
9
9
  export declare function server_update_session(sessions: (SessionUpdate & {
@@ -21,13 +21,15 @@ export async function server_get_session_by_id(sessionId, client) {
21
21
  return IWebResponse.success(session).to_compatible();
22
22
  }
23
23
  // Get session usage over time by herd
24
- export async function server_get_session_usage_over_time_by_herd(herd_id, client) {
24
+ export async function server_get_session_usage_over_time_by_herd(herd_id, client, min_duration_minutes_caller, min_distance_meters_caller) {
25
25
  const supabase = client || (await newServerClient());
26
26
  const { data, error } = await supabase.rpc("get_session_usage_over_time", {
27
27
  start_date_caller: undefined,
28
28
  end_date_caller: undefined,
29
29
  device_id_caller: undefined,
30
30
  herd_id_caller: herd_id,
31
+ min_duration_minutes_caller,
32
+ min_distance_meters_caller,
31
33
  });
32
34
  if (error) {
33
35
  return IWebResponse.error(error.message).to_compatible();
@@ -38,13 +40,15 @@ export async function server_get_session_usage_over_time_by_herd(herd_id, client
38
40
  return IWebResponse.success(data).to_compatible();
39
41
  }
40
42
  // Get session usage over time by device
41
- export async function server_get_session_usage_over_time_by_device(device_id, client) {
43
+ export async function server_get_session_usage_over_time_by_device(device_id, client, min_duration_minutes_caller, min_distance_meters_caller) {
42
44
  const supabase = client || (await newServerClient());
43
45
  const { data, error } = await supabase.rpc("get_session_usage_over_time", {
44
46
  start_date_caller: undefined,
45
47
  end_date_caller: undefined,
46
48
  device_id_caller: device_id,
47
49
  herd_id_caller: undefined,
50
+ min_duration_minutes_caller,
51
+ min_distance_meters_caller,
48
52
  });
49
53
  if (error) {
50
54
  return IWebResponse.error(error.message).to_compatible();
@@ -13,7 +13,7 @@ export interface UseScoutRefreshOptions {
13
13
  * @param options.onRefreshComplete - Callback function called when refresh completes
14
14
  * @param options.cacheFirst - Whether to load from cache first, then refresh (default: true)
15
15
  * @param options.cacheTtlMs - Cache time-to-live in milliseconds (default: 24 hours)
16
- * @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 60s)
16
+ * @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 15s)
17
17
  *
18
18
  * @returns Object containing:
19
19
  * - handleRefresh: Function to manually trigger a refresh
@@ -15,7 +15,7 @@ import { createBrowserClient } from "@supabase/ssr";
15
15
  * @param options.onRefreshComplete - Callback function called when refresh completes
16
16
  * @param options.cacheFirst - Whether to load from cache first, then refresh (default: true)
17
17
  * @param options.cacheTtlMs - Cache time-to-live in milliseconds (default: 24 hours)
18
- * @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 60s)
18
+ * @param options.onlineRefetchMinIntervalMs - Min ms since last refresh before refetch on "online" (default: 15s)
19
19
  *
20
20
  * @returns Object containing:
21
21
  * - handleRefresh: Function to manually trigger a refresh
@@ -33,7 +33,7 @@ import { createBrowserClient } from "@supabase/ssr";
33
33
  */
34
34
  export function useScoutRefresh(options = {}) {
35
35
  const { autoRefresh = true, onRefreshComplete, cacheFirst = true, cacheTtlMs = 24 * 60 * 60 * 1000, // 24 hours default (1 day)
36
- onlineRefetchMinIntervalMs = 60 * 1000, // 1 minute
36
+ onlineRefetchMinIntervalMs = 15 * 1000, // 15 seconds
37
37
  } = options;
38
38
  const dispatch = useAppDispatch();
39
39
  const store = useStore();
@@ -83,6 +83,49 @@ export function useScoutRefresh(options = {}) {
83
83
  const startTime = Date.now();
84
84
  timingRefs.current.startTime = startTime;
85
85
  const isOffline = typeof navigator === "undefined" || !navigator.onLine;
86
+ const fetchUserWithOneRetry = async () => {
87
+ const startTotal = Date.now();
88
+ let lastError;
89
+ for (let attempt = 0; attempt < 2; attempt++) {
90
+ try {
91
+ const { data } = await supabase.auth.getUser();
92
+ if (!data.user) {
93
+ throw new Error("Invalid user response");
94
+ }
95
+ const totalMs = Date.now() - startTotal;
96
+ timingRefs.current.userApiDuration = totalMs;
97
+ dispatch(setUserApiDuration(totalMs));
98
+ dispatch(setUser(data.user));
99
+ return data.user;
100
+ }
101
+ catch (e) {
102
+ lastError = e;
103
+ }
104
+ }
105
+ throw lastError;
106
+ };
107
+ const fetchUserWithOneRetryBackground = async () => {
108
+ const startTotal = Date.now();
109
+ for (let attempt = 0; attempt < 2; attempt++) {
110
+ try {
111
+ const { data } = await supabase.auth.getUser();
112
+ if (data.user) {
113
+ const totalMs = Date.now() - startTotal;
114
+ timingRefs.current.userApiDuration = totalMs;
115
+ dispatch(setUserApiDuration(totalMs));
116
+ dispatch(setUser(data.user));
117
+ return data.user;
118
+ }
119
+ }
120
+ catch {
121
+ // retry once
122
+ }
123
+ }
124
+ const totalMs = Date.now() - startTotal;
125
+ timingRefs.current.userApiDuration = totalMs;
126
+ dispatch(setUserApiDuration(totalMs));
127
+ return null;
128
+ };
86
129
  try {
87
130
  dispatch(setStatus(EnumScoutStateStatus.LOADING));
88
131
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.LOADING));
@@ -117,17 +160,7 @@ export function useScoutRefresh(options = {}) {
117
160
  // Background fetch fresh data without blocking
118
161
  (async () => {
119
162
  try {
120
- const userPromise = (async () => {
121
- const start = Date.now();
122
- const { data } = await supabase.auth.getUser();
123
- const duration = Date.now() - start;
124
- timingRefs.current.userApiDuration = duration;
125
- dispatch(setUserApiDuration(duration));
126
- if (data.user) {
127
- dispatch(setUser(data.user));
128
- }
129
- return data.user ?? null;
130
- })();
163
+ const userPromise = fetchUserWithOneRetryBackground();
131
164
  let backgroundHerdModulesResult;
132
165
  try {
133
166
  const start = Date.now();
@@ -228,18 +261,7 @@ export function useScoutRefresh(options = {}) {
228
261
  }
229
262
  // Step 2: Load fresh data from API (user resolves independently; Redux gets user as soon as getUser returns)
230
263
  const parallelStartTime = Date.now();
231
- const userPromise = (async () => {
232
- const start = Date.now();
233
- const { data } = await supabase.auth.getUser();
234
- const duration = Date.now() - start;
235
- timingRefs.current.userApiDuration = duration;
236
- dispatch(setUserApiDuration(duration));
237
- if (!data.user) {
238
- throw new Error("Invalid user response");
239
- }
240
- dispatch(setUser(data.user));
241
- return data.user;
242
- })();
264
+ const userPromise = fetchUserWithOneRetry();
243
265
  let herdModulesResult;
244
266
  try {
245
267
  herdModulesResult = await (async () => {
@@ -2461,6 +2461,8 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
2461
2461
  device_id_caller?: number;
2462
2462
  end_date_caller?: string;
2463
2463
  herd_id_caller?: number;
2464
+ min_distance_meters_caller?: number;
2465
+ min_duration_minutes_caller?: number;
2464
2466
  start_date_caller?: string;
2465
2467
  };
2466
2468
  Returns: import("../types/supabase").Json;
@@ -2470,6 +2472,8 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
2470
2472
  device_id_caller?: number;
2471
2473
  end_date_caller?: string;
2472
2474
  herd_id_caller?: number;
2475
+ min_distance_meters_caller?: number;
2476
+ min_duration_minutes_caller?: number;
2473
2477
  start_date_caller?: string;
2474
2478
  };
2475
2479
  Returns: import("../types/supabase").Json;
@@ -62,6 +62,8 @@ export interface ISessionSummary {
62
62
  end_date: string | null;
63
63
  device_id: number | null;
64
64
  herd_id: number | null;
65
+ min_duration_minutes: number | null;
66
+ min_distance_meters: number | null;
65
67
  };
66
68
  }
67
69
  export type ISessionUsageOverTime = Database["public"]["Functions"]["get_session_usage_over_time"]["Returns"];
@@ -2546,6 +2546,8 @@ export type Database = {
2546
2546
  device_id_caller?: number;
2547
2547
  end_date_caller?: string;
2548
2548
  herd_id_caller?: number;
2549
+ min_distance_meters_caller?: number;
2550
+ min_duration_minutes_caller?: number;
2549
2551
  start_date_caller?: string;
2550
2552
  };
2551
2553
  Returns: Json;
@@ -2555,6 +2557,8 @@ export type Database = {
2555
2557
  device_id_caller?: number;
2556
2558
  end_date_caller?: string;
2557
2559
  herd_id_caller?: number;
2560
+ min_distance_meters_caller?: number;
2561
+ min_duration_minutes_caller?: number;
2558
2562
  start_date_caller?: string;
2559
2563
  };
2560
2564
  Returns: Json;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.4.51",
3
+ "version": "1.4.53",
4
4
  "description": "Core utilities and helpers for Adventure Labs Scout applications",
5
5
  "main": "dist/index.js",
6
6
  "types": "dist/index.d.ts",