@adventurelabs/scout-core 1.4.76 → 1.4.78

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.
@@ -0,0 +1,2 @@
1
+ import { IHerdModule } from "../types/herd_module";
2
+ export declare function herdModulesSemanticallyEqual(current: IHerdModule[], incoming: IHerdModule[]): boolean;
@@ -0,0 +1,28 @@
1
+ import { dequal } from "dequal";
2
+ function withoutFetchTimestamp({ timestamp_last_refreshed: _timestamp, ...module }) {
3
+ return module;
4
+ }
5
+ export function herdModulesSemanticallyEqual(current, incoming) {
6
+ if (current === incoming) {
7
+ return true;
8
+ }
9
+ if (current.length !== incoming.length) {
10
+ return false;
11
+ }
12
+ if (current.length === 0) {
13
+ return true;
14
+ }
15
+ const currentByHerdId = new Map(current.map((module) => [
16
+ String(module.herd.id),
17
+ withoutFetchTimestamp(module),
18
+ ]));
19
+ for (const incomingModule of incoming) {
20
+ const herdId = String(incomingModule.herd.id);
21
+ const existing = currentByHerdId.get(herdId);
22
+ if (!existing ||
23
+ !dequal(existing, withoutFetchTimestamp(incomingModule))) {
24
+ return false;
25
+ }
26
+ }
27
+ return true;
28
+ }
@@ -7,4 +7,3 @@ export declare function get_versions_software_by_system(client: SupabaseClient<D
7
7
  export declare function create_version_software(client: SupabaseClient<Database>, newVersionSoftware: VersionsSoftwareInsert): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
8
8
  export declare function update_version_software(client: SupabaseClient<Database>, version_id: number, updatedVersionSoftware: Partial<VersionsSoftwareInsert>): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
9
9
  export declare function delete_version_software(client: SupabaseClient<Database>, version_id: number): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
10
- export declare function get_versions_software_by_created_by(client: SupabaseClient<Database>, user_id: string): Promise<IWebResponseCompatible<IVersionsSoftware[]>>;
@@ -75,17 +75,3 @@ export async function delete_version_software(client, version_id) {
75
75
  }
76
76
  return IWebResponse.success(data).to_compatible();
77
77
  }
78
- export async function get_versions_software_by_created_by(client, user_id) {
79
- const { data, error } = await client
80
- .from("versions_software")
81
- .select("*")
82
- .eq("created_by", user_id)
83
- .order("created_at", { ascending: false });
84
- if (error) {
85
- return IWebResponse.error(error.message).to_compatible();
86
- }
87
- if (!data) {
88
- return IWebResponse.error("No software versions found for user").to_compatible();
89
- }
90
- return IWebResponse.success(data).to_compatible();
91
- }
@@ -3,4 +3,3 @@ import { IWebResponseCompatible } from "../types/requests";
3
3
  import { SupabaseClient } from "@supabase/supabase-js";
4
4
  export declare function server_get_versions_software(client?: SupabaseClient): Promise<IWebResponseCompatible<IVersionsSoftwareWithBuildUrl[]>>;
5
5
  export declare function server_get_versions_software_by_system(system: string, client?: SupabaseClient): Promise<IWebResponseCompatible<IVersionsSoftwareWithBuildUrl[]>>;
6
- export declare function server_get_versions_software_by_created_by(user_id: string, client?: SupabaseClient): Promise<IWebResponseCompatible<IVersionsSoftwareWithBuildUrl[]>>;
@@ -53,19 +53,3 @@ export async function server_get_versions_software_by_system(system, client) {
53
53
  const withUrls = await attachBuildArtifactUrls(data, client);
54
54
  return IWebResponse.success(withUrls).to_compatible();
55
55
  }
56
- export async function server_get_versions_software_by_created_by(user_id, client) {
57
- const supabase = client || (await newServerClient());
58
- const { data, error } = await supabase
59
- .from("versions_software")
60
- .select("*")
61
- .eq("created_by", user_id)
62
- .order("created_at", { ascending: false });
63
- if (error) {
64
- return IWebResponse.error(error.message).to_compatible();
65
- }
66
- if (!data) {
67
- return IWebResponse.error("No software versions found for user").to_compatible();
68
- }
69
- const withUrls = await attachBuildArtifactUrls(data, client);
70
- return IWebResponse.success(withUrls).to_compatible();
71
- }
@@ -1,6 +1,5 @@
1
- import { useEffect, useCallback, useRef, useMemo } from "react";
1
+ import { useEffect, useCallback, useRef, useMemo, startTransition } from "react";
2
2
  import { useAppDispatch } from "../store/hooks";
3
- import { useStore } from "react-redux";
4
3
  import { EnumScoutStateStatus, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setUser, setDataSource, setDataSourceInfo, } from "../store/scout";
5
4
  import { EnumHerdModulesLoadingState } from "../types/herd_module";
6
5
  import { server_load_herd_modules } from "../helpers/herds";
@@ -8,6 +7,11 @@ import { scoutCache } from "../helpers/cache";
8
7
  import { EnumDataSource } from "../types/data_source";
9
8
  import { EnumWebResponse } from "../types/requests";
10
9
  import { createBrowserClient } from "@supabase/ssr";
10
+ function dispatchInTransition(dispatch, action) {
11
+ startTransition(() => {
12
+ dispatch(action);
13
+ });
14
+ }
11
15
  /**
12
16
  * Hook for refreshing scout data with detailed timing measurements and cache-first loading
13
17
  *
@@ -38,7 +42,6 @@ export function useScoutRefresh(options = {}) {
38
42
  onlineRefetchMinIntervalMs = 15 * 1000, // 15 seconds
39
43
  } = options;
40
44
  const dispatch = useAppDispatch();
41
- const store = useStore();
42
45
  const refreshInProgressRef = useRef(false);
43
46
  const lastQueryAtRef = useRef(0);
44
47
  const supabase = useMemo(() => {
@@ -98,7 +101,7 @@ export function useScoutRefresh(options = {}) {
98
101
  const totalMs = Date.now() - startTotal;
99
102
  timingRefs.current.userApiDuration = totalMs;
100
103
  dispatch(setUserApiDuration(totalMs));
101
- dispatch(setUser(data.user));
104
+ dispatchInTransition(dispatch, setUser(data.user));
102
105
  return data.user;
103
106
  }
104
107
  catch (e) {
@@ -116,7 +119,7 @@ export function useScoutRefresh(options = {}) {
116
119
  const totalMs = Date.now() - startTotal;
117
120
  timingRefs.current.userApiDuration = totalMs;
118
121
  dispatch(setUserApiDuration(totalMs));
119
- dispatch(setUser(data.user));
122
+ dispatchInTransition(dispatch, setUser(data.user));
120
123
  return data.user;
121
124
  }
122
125
  }
@@ -155,7 +158,7 @@ export function useScoutRefresh(options = {}) {
155
158
  }));
156
159
  // Update the store with cached data
157
160
  console.log(`[useScoutRefresh] Updating store with cached herd modules`);
158
- dispatch(setHerdModules(cachedHerdModules));
161
+ dispatchInTransition(dispatch, setHerdModules(cachedHerdModules));
159
162
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
160
163
  // If cache is fresh, we still background fetch but don't wait (only when online)
161
164
  if (!cacheResult.isStale) {
@@ -204,7 +207,7 @@ export function useScoutRefresh(options = {}) {
204
207
  }
205
208
  // Update store with fresh data from background request
206
209
  console.log(`[useScoutRefresh] Updating store with background herd modules`);
207
- dispatch(setHerdModules(backgroundHerdModulesResult.data));
210
+ dispatchInTransition(dispatch, setHerdModules(backgroundHerdModulesResult.data));
208
211
  // Update data source to DATABASE
209
212
  dispatch(setDataSource(EnumDataSource.DATABASE));
210
213
  dispatch(setDataSourceInfo({
@@ -245,7 +248,7 @@ export function useScoutRefresh(options = {}) {
245
248
  source: EnumDataSource.CACHE,
246
249
  timestamp: Date.now(),
247
250
  }));
248
- dispatch(setHerdModules(cachedHerdModules));
251
+ dispatchInTransition(dispatch, setHerdModules(cachedHerdModules));
249
252
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
250
253
  }
251
254
  else {
@@ -327,11 +330,11 @@ export function useScoutRefresh(options = {}) {
327
330
  await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
328
331
  });
329
332
  }
330
- // Step 4: Conditionally update store with fresh data, skip timestamp-only changes
333
+ // Step 4: Update store with fresh data (reducer skips no-op updates)
331
334
  const dataProcessingStartTime = Date.now();
332
335
  // Update store with new data
333
336
  console.log(`[useScoutRefresh] Updating store with fresh herd modules`);
334
- dispatch(setHerdModules(compatible_new_herd_modules));
337
+ dispatchInTransition(dispatch, setHerdModules(compatible_new_herd_modules));
335
338
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
336
339
  const dataProcessingDuration = Date.now() - dataProcessingStartTime;
337
340
  timingRefs.current.dataProcessingDuration = dataProcessingDuration;
@@ -367,7 +370,6 @@ export function useScoutRefresh(options = {}) {
367
370
  }
368
371
  }, [
369
372
  dispatch,
370
- store,
371
373
  supabase,
372
374
  onRefreshComplete,
373
375
  cacheFirst,