@adventurelabs/scout-core 1.0.82 → 1.0.84

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,9 @@
1
+ import { IWebResponseCompatible } from "../types/requests";
2
+ import { IHeartbeat } from "../types/db";
3
+ export declare function server_get_last_heartbeat_by_device(device_id: number): Promise<IWebResponseCompatible<IHeartbeat | null>>;
4
+ export declare function server_get_heartbeats_by_device(device_id: number, limit?: number): Promise<IWebResponseCompatible<IHeartbeat[]>>;
5
+ export declare function server_check_device_online_status(device_id: number, offline_threshold_minutes?: number): Promise<IWebResponseCompatible<{
6
+ is_online: boolean;
7
+ last_heartbeat: IHeartbeat | null;
8
+ minutes_since_last_heartbeat: number | null;
9
+ }>>;
@@ -0,0 +1,90 @@
1
+ "use server";
2
+ import { newServerClient } from "../supabase/server";
3
+ import { EnumWebResponse, IWebResponse, } from "../types/requests";
4
+ // Function to get the last heartbeat for a device
5
+ export async function server_get_last_heartbeat_by_device(device_id) {
6
+ const supabase = await newServerClient();
7
+ const { data, error } = await supabase
8
+ .from("heartbeats")
9
+ .select("*")
10
+ .eq("device_id", device_id)
11
+ .order("timestamp", { ascending: false })
12
+ .limit(1)
13
+ .single();
14
+ if (error) {
15
+ // If no heartbeats found, return null data instead of error
16
+ if (error.code === "PGRST116") {
17
+ return {
18
+ status: EnumWebResponse.SUCCESS,
19
+ msg: null,
20
+ data: null,
21
+ };
22
+ }
23
+ return {
24
+ status: EnumWebResponse.ERROR,
25
+ msg: error.message,
26
+ data: null,
27
+ };
28
+ }
29
+ else {
30
+ return IWebResponse.success(data).to_compatible();
31
+ }
32
+ }
33
+ // Function to get all heartbeats for a device
34
+ export async function server_get_heartbeats_by_device(device_id, limit) {
35
+ const supabase = await newServerClient();
36
+ let query = supabase
37
+ .from("heartbeats")
38
+ .select("*")
39
+ .eq("device_id", device_id)
40
+ .order("timestamp", { ascending: false });
41
+ if (limit) {
42
+ query = query.limit(limit);
43
+ }
44
+ const { data, error } = await query;
45
+ if (error) {
46
+ return {
47
+ status: EnumWebResponse.ERROR,
48
+ msg: error.message,
49
+ data: [],
50
+ };
51
+ }
52
+ else {
53
+ return IWebResponse.success(data || []).to_compatible();
54
+ }
55
+ }
56
+ // Function to check if a device is online based on heartbeat recency
57
+ export async function server_check_device_online_status(device_id, offline_threshold_minutes = 5) {
58
+ const supabase = await newServerClient();
59
+ const { data, error } = await supabase
60
+ .from("heartbeats")
61
+ .select("*")
62
+ .eq("device_id", device_id)
63
+ .order("timestamp", { ascending: false })
64
+ .limit(1)
65
+ .single();
66
+ if (error) {
67
+ // If no heartbeats found
68
+ if (error.code === "PGRST116") {
69
+ return IWebResponse.success({
70
+ is_online: false,
71
+ last_heartbeat: null,
72
+ minutes_since_last_heartbeat: null,
73
+ }).to_compatible();
74
+ }
75
+ return {
76
+ status: EnumWebResponse.ERROR,
77
+ msg: error.message,
78
+ data: null,
79
+ };
80
+ }
81
+ const now = new Date();
82
+ const heartbeatTime = new Date(data.timestamp);
83
+ const minutesSinceLastHeartbeat = Math.floor((now.getTime() - heartbeatTime.getTime()) / (1000 * 60));
84
+ const isOnline = minutesSinceLastHeartbeat <= offline_threshold_minutes;
85
+ return IWebResponse.success({
86
+ is_online: isOnline,
87
+ last_heartbeat: data,
88
+ minutes_since_last_heartbeat: minutesSinceLastHeartbeat,
89
+ }).to_compatible();
90
+ }
@@ -6,6 +6,7 @@ export * from "./devices";
6
6
  export * from "./email";
7
7
  export * from "./events";
8
8
  export * from "./gps";
9
+ export * from "./heartbeats";
9
10
  export * from "./herds";
10
11
  export * from "./location";
11
12
  export * from "./plans";
@@ -6,6 +6,7 @@ export * from "./devices";
6
6
  export * from "./email";
7
7
  export * from "./events";
8
8
  export * from "./gps";
9
+ export * from "./heartbeats";
9
10
  export * from "./herds";
10
11
  export * from "./location";
11
12
  export * from "./plans";
@@ -0,0 +1,6 @@
1
+ import { IProvider } from "../types/db";
2
+ import { IWebResponseCompatible } from "../types/requests";
3
+ export declare function server_get_providers_by_herd(herd_id: number): Promise<IWebResponseCompatible<IProvider[]>>;
4
+ export declare function server_create_provider(provider: Omit<IProvider, "id" | "created_at">): Promise<IWebResponseCompatible<IProvider>>;
5
+ export declare function server_update_provider(provider_id: number, updates: Partial<Omit<IProvider, "id" | "created_at">>): Promise<IWebResponseCompatible<IProvider>>;
6
+ export declare function server_delete_providers_by_ids(provider_ids: number[]): Promise<IWebResponseCompatible<boolean>>;
@@ -0,0 +1,78 @@
1
+ "use server";
2
+ import { newServerClient } from "../supabase/server";
3
+ import { EnumWebResponse, IWebResponse, } from "../types/requests";
4
+ // function that fetches the providers from our db given a herd id
5
+ export async function server_get_providers_by_herd(herd_id) {
6
+ const supabase = await newServerClient();
7
+ const { data, error } = await supabase
8
+ .from("providers")
9
+ .select("*")
10
+ .eq("herd_id", herd_id);
11
+ if (error) {
12
+ return {
13
+ status: EnumWebResponse.ERROR,
14
+ msg: error.message,
15
+ data: null,
16
+ };
17
+ }
18
+ else {
19
+ return IWebResponse.success(data).to_compatible();
20
+ }
21
+ }
22
+ // function that creates a new provider in our db
23
+ export async function server_create_provider(provider) {
24
+ const supabase = await newServerClient();
25
+ const { data, error } = await supabase
26
+ .from("providers")
27
+ .insert(provider)
28
+ .select("*")
29
+ .single();
30
+ if (error) {
31
+ return {
32
+ status: EnumWebResponse.ERROR,
33
+ msg: error.message,
34
+ data: null,
35
+ };
36
+ }
37
+ else {
38
+ return IWebResponse.success(data).to_compatible();
39
+ }
40
+ }
41
+ // function that updates a provider in our db
42
+ export async function server_update_provider(provider_id, updates) {
43
+ const supabase = await newServerClient();
44
+ const { data, error } = await supabase
45
+ .from("providers")
46
+ .update(updates)
47
+ .eq("id", provider_id)
48
+ .select("*")
49
+ .single();
50
+ if (error) {
51
+ return {
52
+ status: EnumWebResponse.ERROR,
53
+ msg: error.message,
54
+ data: null,
55
+ };
56
+ }
57
+ else {
58
+ return IWebResponse.success(data).to_compatible();
59
+ }
60
+ }
61
+ // function that deletes providers by ids
62
+ export async function server_delete_providers_by_ids(provider_ids) {
63
+ const supabase = await newServerClient();
64
+ const { error } = await supabase
65
+ .from("providers")
66
+ .delete()
67
+ .in("id", provider_ids);
68
+ if (error) {
69
+ return {
70
+ status: EnumWebResponse.ERROR,
71
+ msg: error.message,
72
+ data: false,
73
+ };
74
+ }
75
+ else {
76
+ return IWebResponse.success(true).to_compatible();
77
+ }
78
+ }
@@ -289,6 +289,33 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
289
289
  referencedColumns: ["id"];
290
290
  }];
291
291
  };
292
+ heartbeats: {
293
+ Row: {
294
+ created_at: string;
295
+ device_id: number;
296
+ id: number;
297
+ timestamp: string;
298
+ };
299
+ Insert: {
300
+ created_at?: string;
301
+ device_id: number;
302
+ id?: number;
303
+ timestamp: string;
304
+ };
305
+ Update: {
306
+ created_at?: string;
307
+ device_id?: number;
308
+ id?: number;
309
+ timestamp?: string;
310
+ };
311
+ Relationships: [{
312
+ foreignKeyName: "heartbeats_device_id_fkey";
313
+ columns: ["device_id"];
314
+ isOneToOne: false;
315
+ referencedRelation: "devices";
316
+ referencedColumns: ["id"];
317
+ }];
318
+ };
292
319
  herds: {
293
320
  Row: {
294
321
  created_by: string;
@@ -397,6 +424,39 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
397
424
  referencedColumns: ["id"];
398
425
  }];
399
426
  };
427
+ providers: {
428
+ Row: {
429
+ created_at: string;
430
+ herd_id: number;
431
+ id: number;
432
+ key: string | null;
433
+ source: string;
434
+ type: string;
435
+ };
436
+ Insert: {
437
+ created_at?: string;
438
+ herd_id: number;
439
+ id?: number;
440
+ key?: string | null;
441
+ source: string;
442
+ type: string;
443
+ };
444
+ Update: {
445
+ created_at?: string;
446
+ herd_id?: number;
447
+ id?: number;
448
+ key?: string | null;
449
+ source?: string;
450
+ type?: string;
451
+ };
452
+ Relationships: [{
453
+ foreignKeyName: "providers_herd_id_fkey";
454
+ columns: ["herd_id"];
455
+ isOneToOne: false;
456
+ referencedRelation: "herds";
457
+ referencedColumns: ["id"];
458
+ }];
459
+ };
400
460
  sessions: {
401
461
  Row: {
402
462
  altitude_average: number;
@@ -21,6 +21,7 @@ export type IUserRolePerHerd = Database["public"]["Tables"]["users_roles_per_her
21
21
  export type IHerd = Database["public"]["Tables"]["herds"]["Row"];
22
22
  export type ISession = Database["public"]["Tables"]["sessions"]["Row"];
23
23
  export type IConnectivity = Database["public"]["Tables"]["connectivity"]["Row"];
24
+ export type IHeartbeat = Database["public"]["Tables"]["heartbeats"]["Row"];
24
25
  export type IEventWithTags = Database["public"]["CompositeTypes"]["event_with_tags"] & {
25
26
  earthranger_url: string | null;
26
27
  file_path: string | null;
@@ -302,6 +302,35 @@ export type Database = {
302
302
  }
303
303
  ];
304
304
  };
305
+ heartbeats: {
306
+ Row: {
307
+ created_at: string;
308
+ device_id: number;
309
+ id: number;
310
+ timestamp: string;
311
+ };
312
+ Insert: {
313
+ created_at?: string;
314
+ device_id: number;
315
+ id?: number;
316
+ timestamp: string;
317
+ };
318
+ Update: {
319
+ created_at?: string;
320
+ device_id?: number;
321
+ id?: number;
322
+ timestamp?: string;
323
+ };
324
+ Relationships: [
325
+ {
326
+ foreignKeyName: "heartbeats_device_id_fkey";
327
+ columns: ["device_id"];
328
+ isOneToOne: false;
329
+ referencedRelation: "devices";
330
+ referencedColumns: ["id"];
331
+ }
332
+ ];
333
+ };
305
334
  herds: {
306
335
  Row: {
307
336
  created_by: string;
@@ -416,6 +445,41 @@ export type Database = {
416
445
  }
417
446
  ];
418
447
  };
448
+ providers: {
449
+ Row: {
450
+ created_at: string;
451
+ herd_id: number;
452
+ id: number;
453
+ key: string | null;
454
+ source: string;
455
+ type: string;
456
+ };
457
+ Insert: {
458
+ created_at?: string;
459
+ herd_id: number;
460
+ id?: number;
461
+ key?: string | null;
462
+ source: string;
463
+ type: string;
464
+ };
465
+ Update: {
466
+ created_at?: string;
467
+ herd_id?: number;
468
+ id?: number;
469
+ key?: string | null;
470
+ source?: string;
471
+ type?: string;
472
+ };
473
+ Relationships: [
474
+ {
475
+ foreignKeyName: "providers_herd_id_fkey";
476
+ columns: ["herd_id"];
477
+ isOneToOne: false;
478
+ referencedRelation: "herds";
479
+ referencedColumns: ["id"];
480
+ }
481
+ ];
482
+ };
419
483
  sessions: {
420
484
  Row: {
421
485
  altitude_average: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.0.82",
3
+ "version": "1.0.84",
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",