@adventurelabs/scout-core 1.4.14 → 1.4.16

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,5 +1,5 @@
1
1
  const DB_NAME = "ScoutCache";
2
- const DB_VERSION = 5; // Increment to invalidate old cache versions
2
+ const DB_VERSION = 6;
3
3
  const HERD_MODULES_STORE = "herd_modules";
4
4
  const CACHE_METADATA_STORE = "cache_metadata";
5
5
  // Default TTL: 24 hours (1 day)
@@ -104,6 +104,8 @@ export class ScoutCache {
104
104
  const version = "2.0.0";
105
105
  // Store each herd module (contains all nested data - devices, events, zones, etc.)
106
106
  herdModules.forEach((herdModule) => {
107
+ if (herdModule.herd.id == null)
108
+ return;
107
109
  const cacheEntry = {
108
110
  herdId: herdModule.herd.id.toString(),
109
111
  data: herdModule,
@@ -1,8 +1,10 @@
1
- import { IHerd } from "../types/db";
1
+ import { Database } from "../types/supabase";
2
+ import { IHerd, IHerdPrettyLocation } from "../types/db";
2
3
  import { IWebResponseCompatible } from "../types/requests";
3
4
  import { SupabaseClient } from "@supabase/supabase-js";
4
5
  import { IHerdModulesResponseWithStatus } from "../types/herd_module";
5
- export declare function get_herds(client: SupabaseClient): Promise<IWebResponseCompatible<IHerd[]>>;
6
+ export declare function get_herds(client: SupabaseClient<Database>): Promise<IWebResponseCompatible<IHerd[]>>;
7
+ export declare function get_herds_with_location(client: SupabaseClient<Database>): Promise<IWebResponseCompatible<IHerdPrettyLocation[]>>;
6
8
  export declare function get_herd_by_slug(slug: string): Promise<IWebResponseCompatible<IHerd>>;
7
9
  export declare function deleteHerd(herd_id: number): Promise<IWebResponseCompatible<boolean>>;
8
10
  export declare function createHerd(newHerd: any): Promise<IWebResponseCompatible<boolean>>;
@@ -16,6 +16,24 @@ export async function get_herds(client) {
16
16
  return response.to_compatible();
17
17
  }
18
18
  }
19
+ export async function get_herds_with_location(client) {
20
+ const { data, error } = await client.rpc("get_herds_with_location");
21
+ if (error) {
22
+ return {
23
+ status: EnumWebResponse.ERROR,
24
+ msg: error.message,
25
+ data: null,
26
+ };
27
+ }
28
+ if (!data) {
29
+ return {
30
+ status: EnumWebResponse.ERROR,
31
+ msg: "No herds found",
32
+ data: null,
33
+ };
34
+ }
35
+ return IWebResponse.success(data).to_compatible();
36
+ }
19
37
  export async function get_herd_by_slug(slug) {
20
38
  const supabase = await newServerClient();
21
39
  const { data: herds } = await supabase
@@ -66,28 +84,28 @@ export async function createHerd(newHerd) {
66
84
  }
67
85
  export async function server_load_herd_modules() {
68
86
  const startTime = Date.now();
69
- // load herds
70
87
  const client_supabase = await newServerClient();
71
- let new_herds = await get_herds(client_supabase);
72
- if (new_herds.status != EnumWebResponse.SUCCESS || !new_herds.data) {
88
+ const herdsResult = await get_herds_with_location(client_supabase);
89
+ if (herdsResult.status !== EnumWebResponse.SUCCESS ||
90
+ !herdsResult.data ||
91
+ herdsResult.data.length === 0) {
73
92
  return {
74
93
  status: EnumWebResponse.ERROR,
75
- msg: "No herds found",
94
+ msg: herdsResult.msg ?? "No herds found",
76
95
  data: null,
77
96
  time_finished: Date.now(),
78
97
  time_sent: Date.now(),
79
98
  server_processing_time_ms: Date.now() - startTime,
80
99
  };
81
100
  }
101
+ const herds = herdsResult.data.filter((h) => h.id != null);
82
102
  let new_herd_modules = [];
83
- const herdModulePromises = new_herds.data.map((herd) => HerdModule.from_herd(herd, client_supabase));
103
+ const herdModulePromises = herds.map((herd) => HerdModule.from_herd(herd, client_supabase));
84
104
  new_herd_modules = await Promise.all(herdModulePromises);
85
- // now serialize the herd modules
86
- let serialized_herd_modules = new_herd_modules.map((herd_module) => herd_module.to_serializable());
105
+ const serialized_herd_modules = new_herd_modules.map((herd_module) => herd_module.to_serializable());
87
106
  const endTime = Date.now();
88
107
  const totalLoadTime = endTime - startTime;
89
- console.log(`[server_load_herd_modules] Loaded ${new_herds.data.length} herds in ${totalLoadTime}ms (parallel processing)`);
90
- // Record the time when we're about to send the response
108
+ console.log(`[server_load_herd_modules] Loaded ${herds.length} herds in ${totalLoadTime}ms (parallel processing)`);
91
109
  const timeSent = Date.now();
92
110
  return {
93
111
  status: EnumWebResponse.SUCCESS,
@@ -11,7 +11,7 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
11
11
  const gpsDeviceIds = useMemo(() => {
12
12
  if (!activeHerdId)
13
13
  return "";
14
- const activeHerdModule = herdModules.find((hm) => hm.herd.id.toString() === activeHerdId);
14
+ const activeHerdModule = herdModules.find((hm) => hm.herd.id?.toString() === activeHerdId);
15
15
  if (!activeHerdModule)
16
16
  return "";
17
17
  const gpsDevices = activeHerdModule.devices.filter((device) => device.device_type &&
package/dist/index.d.ts CHANGED
@@ -10,6 +10,7 @@ export * from "./types/supabase";
10
10
  export * from "./types/bounding_boxes";
11
11
  export * from "./types/events";
12
12
  export * from "./types/connectivity";
13
+ export * from "./helpers/artifacts";
13
14
  export * from "./helpers/auth";
14
15
  export * from "./helpers/bounding_boxes";
15
16
  export * from "./helpers/chat";
@@ -60,5 +61,5 @@ export * from "./supabase/middleware";
60
61
  export * from "./supabase/server";
61
62
  export * from "./api_keys/actions";
62
63
  export type { HerdModule, IHerdModule } from "./types/herd_module";
63
- export type { IDevice, IEvent, IUser, IHerd, IEventWithTags, IZoneWithActions, IUserAndRole, IApiKeyScout, ILayer, IHeartbeat, IProvider, IConnectivity, ISession, ISessionWithCoordinates, IConnectivityWithCoordinates, } from "./types/db";
64
+ export type { IDevice, IEvent, IUser, IHerd, IHerdPrettyLocation, IEventWithTags, IZoneWithActions, IUserAndRole, IApiKeyScout, ILayer, IHeartbeat, IProvider, IConnectivity, ISession, ISessionWithCoordinates, IConnectivityWithCoordinates, } from "./types/db";
64
65
  export { EnumSessionsVisibility } from "./types/events";
package/dist/index.js CHANGED
@@ -13,6 +13,7 @@ export * from "./types/bounding_boxes";
13
13
  export * from "./types/events";
14
14
  export * from "./types/connectivity";
15
15
  // Helpers
16
+ export * from "./helpers/artifacts";
16
17
  export * from "./helpers/auth";
17
18
  export * from "./helpers/bounding_boxes";
18
19
  export * from "./helpers/chat";
@@ -449,6 +449,7 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
449
449
  id: number;
450
450
  inserted_at: string;
451
451
  is_public: boolean;
452
+ location: unknown;
452
453
  slug: string;
453
454
  video_publisher_token: string | null;
454
455
  video_server_url: string | null;
@@ -462,6 +463,7 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
462
463
  id?: number;
463
464
  inserted_at?: string;
464
465
  is_public?: boolean;
466
+ location?: unknown;
465
467
  slug: string;
466
468
  video_publisher_token?: string | null;
467
469
  video_server_url?: string | null;
@@ -475,6 +477,7 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
475
477
  id?: number;
476
478
  inserted_at?: string;
477
479
  is_public?: boolean;
480
+ location?: unknown;
478
481
  slug?: string;
479
482
  video_publisher_token?: string | null;
480
483
  video_server_url?: string | null;
@@ -1477,6 +1480,16 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1477
1480
  total_heartbeats: number;
1478
1481
  }[];
1479
1482
  };
1483
+ get_herds_with_location: {
1484
+ Args: never;
1485
+ Returns: Database["public"]["CompositeTypes"]["herds_pretty_location"][];
1486
+ SetofOptions: {
1487
+ from: "*";
1488
+ to: "herds_pretty_location";
1489
+ isOneToOne: false;
1490
+ isSetofReturn: true;
1491
+ };
1492
+ };
1480
1493
  get_pins_for_herd: {
1481
1494
  Args: {
1482
1495
  herd_id_caller: number;
@@ -1700,6 +1713,14 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1700
1713
  Args: never;
1701
1714
  Returns: undefined;
1702
1715
  };
1716
+ set_herd_location: {
1717
+ Args: {
1718
+ p_herd_id: number;
1719
+ p_latitude: number;
1720
+ p_longitude: number;
1721
+ };
1722
+ Returns: undefined;
1723
+ };
1703
1724
  };
1704
1725
  Enums: {
1705
1726
  app_permission: "herds.delete" | "events.delete";
@@ -1827,6 +1848,22 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1827
1848
  is_public: boolean | null;
1828
1849
  tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
1829
1850
  };
1851
+ herds_pretty_location: {
1852
+ id: number | null;
1853
+ inserted_at: string | null;
1854
+ slug: string | null;
1855
+ description: string | null;
1856
+ created_by: string | null;
1857
+ is_public: boolean | null;
1858
+ earthranger_domain: string | null;
1859
+ earthranger_token: string | null;
1860
+ video_publisher_token: string | null;
1861
+ video_subscriber_token: string | null;
1862
+ video_server_url: string | null;
1863
+ location: string | null;
1864
+ latitude: number | null;
1865
+ longitude: number | null;
1866
+ };
1830
1867
  pins_pretty_location: {
1831
1868
  id: number | null;
1832
1869
  created_at: string | null;
@@ -82,21 +82,21 @@ export const scoutSlice = createSlice({
82
82
  },
83
83
  updateSessionSummariesForHerdModule: (state, action) => {
84
84
  const { herd_id, session_summaries } = action.payload;
85
- const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
85
+ const herd_module = state.herd_modules.find((hm) => hm.herd.id?.toString() === herd_id);
86
86
  if (herd_module) {
87
87
  herd_module.session_summaries = session_summaries;
88
88
  }
89
89
  },
90
90
  appendPlansToHerdModule: (state, action) => {
91
91
  const { herd_id, plan } = action.payload;
92
- const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
92
+ const herd_module = state.herd_modules.find((hm) => hm.herd.id?.toString() === herd_id);
93
93
  if (herd_module) {
94
94
  herd_module.plans = [...herd_module.plans, plan];
95
95
  }
96
96
  },
97
97
  updateDeviceForHerdModule: (state, action) => {
98
98
  const { herd_id, device } = action.payload;
99
- const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
99
+ const herd_module = state.herd_modules.find((hm) => hm.herd.id?.toString() === herd_id);
100
100
  if (herd_module) {
101
101
  herd_module.devices = herd_module.devices.map((d) => d.id === device.id ? device : d);
102
102
  }
@@ -104,7 +104,7 @@ export const scoutSlice = createSlice({
104
104
  // append device to herd module
105
105
  addNewDeviceToHerdModule: (state, action) => {
106
106
  const { herd_id, device } = action.payload;
107
- const herd_module = state.herd_modules.find((hm) => hm.herd.id.toString() === herd_id);
107
+ const herd_module = state.herd_modules.find((hm) => hm.herd.id?.toString() === herd_id);
108
108
  if (herd_module) {
109
109
  herd_module.devices = [...herd_module.devices, device];
110
110
  }
@@ -73,6 +73,7 @@ export type IEventWithTags = Database["public"]["CompositeTypes"]["event_with_ta
73
73
  export type IDevicePrettyLocation = Database["public"]["CompositeTypes"]["device_pretty_location"];
74
74
  export type IEventAndTagsPrettyLocation = Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"];
75
75
  export type IZonesAndActionsPrettyLocation = Database["public"]["CompositeTypes"]["zones_and_actions_pretty_location"];
76
+ export type IHerdPrettyLocation = Database["public"]["CompositeTypes"]["herds_pretty_location"];
76
77
  export type ISessionWithCoordinates = Database["public"]["CompositeTypes"]["session_with_coordinates"];
77
78
  export type IConnectivityWithCoordinates = Database["public"]["CompositeTypes"]["connectivity_with_coordinates"];
78
79
  export type IDeviceHeartbeatAnalysis = Database["public"]["CompositeTypes"]["device_heartbeat_analysis"];
@@ -1,5 +1,5 @@
1
1
  import { SupabaseClient } from "@supabase/supabase-js";
2
- import { IDevice, IHerd, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionSummary, ISessionUsageOverTime } from "../types/db";
2
+ import { IDevice, IHerdPrettyLocation, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionSummary, ISessionUsageOverTime } from "../types/db";
3
3
  import { EnumWebResponse } from "./requests";
4
4
  export declare enum EnumHerdModulesLoadingState {
5
5
  NOT_LOADING = "NOT_LOADING",
@@ -8,7 +8,7 @@ export declare enum EnumHerdModulesLoadingState {
8
8
  UNSUCCESSFULLY_LOADED = "UNSUCCESSFULLY_LOADED"
9
9
  }
10
10
  export declare class HerdModule {
11
- herd: IHerd;
11
+ herd: IHerdPrettyLocation;
12
12
  devices: IDevice[];
13
13
  zones: IZoneWithActions[];
14
14
  timestamp_last_refreshed: number;
@@ -19,12 +19,12 @@ export declare class HerdModule {
19
19
  providers: IProvider[];
20
20
  session_summaries: ISessionSummary | null;
21
21
  session_usage: ISessionUsageOverTime | null;
22
- constructor(herd: IHerd, devices: IDevice[], timestamp_last_refreshed: number, user_roles?: IUserAndRole[] | null, labels?: string[], plans?: IPlan[], zones?: IZoneWithActions[], layers?: ILayer[], providers?: IProvider[], session_summaries?: ISessionSummary | null, session_usage?: ISessionUsageOverTime | null);
22
+ constructor(herd: IHerdPrettyLocation, devices: IDevice[], timestamp_last_refreshed: number, user_roles?: IUserAndRole[] | null, labels?: string[], plans?: IPlan[], zones?: IZoneWithActions[], layers?: ILayer[], providers?: IProvider[], session_summaries?: ISessionSummary | null, session_usage?: ISessionUsageOverTime | null);
23
23
  to_serializable(): IHerdModule;
24
- static from_herd(herd: IHerd, client: SupabaseClient): Promise<HerdModule>;
24
+ static from_herd(herd: IHerdPrettyLocation, client: SupabaseClient): Promise<HerdModule>;
25
25
  }
26
26
  export interface IHerdModule {
27
- herd: IHerd;
27
+ herd: IHerdPrettyLocation;
28
28
  devices: IDevice[];
29
29
  timestamp_last_refreshed: number;
30
30
  user_roles: IUserAndRole[] | null;
@@ -467,6 +467,7 @@ export type Database = {
467
467
  id: number;
468
468
  inserted_at: string;
469
469
  is_public: boolean;
470
+ location: unknown;
470
471
  slug: string;
471
472
  video_publisher_token: string | null;
472
473
  video_server_url: string | null;
@@ -480,6 +481,7 @@ export type Database = {
480
481
  id?: number;
481
482
  inserted_at?: string;
482
483
  is_public?: boolean;
484
+ location?: unknown;
483
485
  slug: string;
484
486
  video_publisher_token?: string | null;
485
487
  video_server_url?: string | null;
@@ -493,6 +495,7 @@ export type Database = {
493
495
  id?: number;
494
496
  inserted_at?: string;
495
497
  is_public?: boolean;
498
+ location?: unknown;
496
499
  slug?: string;
497
500
  video_publisher_token?: string | null;
498
501
  video_server_url?: string | null;
@@ -1533,6 +1536,16 @@ export type Database = {
1533
1536
  total_heartbeats: number;
1534
1537
  }[];
1535
1538
  };
1539
+ get_herds_with_location: {
1540
+ Args: never;
1541
+ Returns: Database["public"]["CompositeTypes"]["herds_pretty_location"][];
1542
+ SetofOptions: {
1543
+ from: "*";
1544
+ to: "herds_pretty_location";
1545
+ isOneToOne: false;
1546
+ isSetofReturn: true;
1547
+ };
1548
+ };
1536
1549
  get_pins_for_herd: {
1537
1550
  Args: {
1538
1551
  herd_id_caller: number;
@@ -1756,6 +1769,14 @@ export type Database = {
1756
1769
  Args: never;
1757
1770
  Returns: undefined;
1758
1771
  };
1772
+ set_herd_location: {
1773
+ Args: {
1774
+ p_herd_id: number;
1775
+ p_latitude: number;
1776
+ p_longitude: number;
1777
+ };
1778
+ Returns: undefined;
1779
+ };
1759
1780
  };
1760
1781
  Enums: {
1761
1782
  app_permission: "herds.delete" | "events.delete";
@@ -1883,6 +1904,22 @@ export type Database = {
1883
1904
  is_public: boolean | null;
1884
1905
  tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
1885
1906
  };
1907
+ herds_pretty_location: {
1908
+ id: number | null;
1909
+ inserted_at: string | null;
1910
+ slug: string | null;
1911
+ description: string | null;
1912
+ created_by: string | null;
1913
+ is_public: boolean | null;
1914
+ earthranger_domain: string | null;
1915
+ earthranger_token: string | null;
1916
+ video_publisher_token: string | null;
1917
+ video_subscriber_token: string | null;
1918
+ video_server_url: string | null;
1919
+ location: string | null;
1920
+ latitude: number | null;
1921
+ longitude: number | null;
1922
+ };
1886
1923
  pins_pretty_location: {
1887
1924
  id: number | null;
1888
1925
  created_at: string | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.4.14",
3
+ "version": "1.4.16",
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",