@adventurelabs/scout-core 1.0.32 → 1.0.33

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 { SupabaseClient } from "@supabase/supabase-js";
2
2
  import { Database } from "../types/supabase";
3
- import { ISession, IConnectivity, IEvent, ISessionWithCoordinates, IConnectivityWithCoordinates } from "../types/db";
3
+ import { ISession, IConnectivity, IEvent, ISessionWithCoordinates, IConnectivityWithCoordinates, IEventAndTagsPrettyLocation } from "../types/db";
4
4
  export type SessionInput = Omit<ISession, "id" | "inserted_at">;
5
5
  export type SessionUpdateInput = Partial<SessionInput> & {
6
6
  id: number;
@@ -14,15 +14,23 @@ export type ConnectivityUpsertInput = ConnectivityInput | ConnectivityUpdateInpu
14
14
  export declare function getSessionsByHerdId(supabase: SupabaseClient<Database>, herdId: number): Promise<ISessionWithCoordinates[]>;
15
15
  export declare function getConnectivityBySessionId(supabase: SupabaseClient<Database>, sessionId: number): Promise<IConnectivityWithCoordinates[]>;
16
16
  export declare function getEventsBySessionId(supabase: SupabaseClient<Database>, sessionId: number): Promise<IEvent[]>;
17
+ export declare function getEventsAndTagsBySessionId(supabase: SupabaseClient<Database>, sessionId: number, limit?: number, offset?: number): Promise<IEventAndTagsPrettyLocation[]>;
18
+ export declare function getTotalEventsForSession(supabase: SupabaseClient<Database>, sessionId: number): Promise<number>;
17
19
  export declare function upsertSession(supabase: SupabaseClient<Database>, sessionData: SessionUpsertInput): Promise<ISession>;
18
20
  export declare function upsertSessions(supabase: SupabaseClient<Database>, sessionsData: SessionUpsertInput[]): Promise<ISession[]>;
19
21
  export declare function upsertConnectivity(supabase: SupabaseClient<Database>, connectivityData: ConnectivityUpsertInput): Promise<IConnectivity>;
20
22
  export declare function upsertConnectivityBatch(supabase: SupabaseClient<Database>, connectivityDataArray: ConnectivityUpsertInput[]): Promise<IConnectivity[]>;
21
- export declare function getSessionWithConnectivityAndEvents(supabase: SupabaseClient<Database>, sessionId: number): Promise<{
23
+ export declare function getSessionWithConnectivityAndEvents(supabase: SupabaseClient<Database>, sessionId: number, herdId?: number): Promise<{
22
24
  session: ISessionWithCoordinates | null;
23
25
  connectivity: IConnectivityWithCoordinates[];
24
26
  events: IEvent[];
25
27
  }>;
28
+ export declare function getSessionWithConnectivityAndEventsWithTags(supabase: SupabaseClient<Database>, sessionId: number, limit?: number, offset?: number, herdId?: number): Promise<{
29
+ session: ISessionWithCoordinates | null;
30
+ connectivity: IConnectivityWithCoordinates[];
31
+ eventsWithTags: IEventAndTagsPrettyLocation[];
32
+ totalEvents: number;
33
+ }>;
26
34
  export declare function getSessionsByDeviceId(supabase: SupabaseClient<Database>, deviceId: number): Promise<ISessionWithCoordinates[]>;
27
35
  export declare function deleteSession(supabase: SupabaseClient<Database>, sessionId: number): Promise<void>;
28
36
  export declare function deleteSessions(supabase: SupabaseClient<Database>, sessionIds: number[]): Promise<void>;
@@ -42,6 +42,28 @@ export async function getEventsBySessionId(supabase, sessionId) {
42
42
  }
43
43
  return data || [];
44
44
  }
45
+ // Get events with tags by session id using RPC function
46
+ export async function getEventsAndTagsBySessionId(supabase, sessionId, limit = 50, offset = 0) {
47
+ const { data, error } = await supabase.rpc("get_events_and_tags_for_session", {
48
+ session_id_caller: sessionId,
49
+ limit_caller: limit,
50
+ offset_caller: offset,
51
+ });
52
+ if (error) {
53
+ throw new Error(`Failed to get events and tags by session id: ${error.message}`);
54
+ }
55
+ return data || [];
56
+ }
57
+ // Get total count of events for a session
58
+ export async function getTotalEventsForSession(supabase, sessionId) {
59
+ const { data, error } = await supabase.rpc("get_total_events_for_session", {
60
+ session_id_caller: sessionId,
61
+ });
62
+ if (error) {
63
+ throw new Error(`Failed to get total events for session: ${error.message}`);
64
+ }
65
+ return data || 0;
66
+ }
45
67
  // Create or update session
46
68
  export async function upsertSession(supabase, sessionData) {
47
69
  const isUpdate = "id" in sessionData;
@@ -171,34 +193,51 @@ export async function upsertConnectivityBatch(supabase, connectivityDataArray) {
171
193
  return results;
172
194
  }
173
195
  // Get session with connectivity and events using RPC functions
174
- export async function getSessionWithConnectivityAndEvents(supabase, sessionId) {
175
- // Get the session from the sessions table first to get the device_id
176
- const { data: sessionData, error: sessionError } = await supabase
177
- .from("sessions")
178
- .select("*")
179
- .eq("id", sessionId)
180
- .single();
181
- if (sessionError) {
182
- throw new Error(`Failed to get session: ${sessionError.message}`);
183
- }
184
- // Get the device to find its herd_id
185
- const { data: device, error: deviceError } = await supabase
186
- .from("devices")
187
- .select("herd_id")
188
- .eq("id", sessionData.device_id)
189
- .single();
190
- if (deviceError) {
191
- throw new Error(`Failed to get device: ${deviceError.message}`);
196
+ export async function getSessionWithConnectivityAndEvents(supabase, sessionId, herdId) {
197
+ let sessionWithCoords = null;
198
+ if (herdId) {
199
+ // Use provided herd ID directly
200
+ // Get sessions with coordinates for the herd and find our specific session
201
+ const { data: allSessionsWithCoords, error: sessionsError } = await supabase.rpc("get_sessions_with_coordinates", {
202
+ herd_id_caller: herdId,
203
+ });
204
+ if (sessionsError) {
205
+ throw new Error(`Failed to get session with coordinates: ${sessionsError.message}`);
206
+ }
207
+ // Find the specific session in the results
208
+ sessionWithCoords =
209
+ allSessionsWithCoords?.find((s) => s.id === sessionId) || null;
192
210
  }
193
- // Get sessions with coordinates for the herd and find our specific session
194
- const { data: allSessionsWithCoords, error: sessionsError } = await supabase.rpc("get_sessions_with_coordinates", {
195
- herd_id_caller: device.herd_id,
196
- });
197
- if (sessionsError) {
198
- throw new Error(`Failed to get session with coordinates: ${sessionsError.message}`);
211
+ else {
212
+ // Get the session from the sessions table first to get the device_id
213
+ const { data: sessionData, error: sessionError } = await supabase
214
+ .from("sessions")
215
+ .select("*")
216
+ .eq("id", sessionId)
217
+ .single();
218
+ if (sessionError) {
219
+ throw new Error(`Failed to get session: ${sessionError.message}`);
220
+ }
221
+ // Get the device to find its herd_id
222
+ const { data: device, error: deviceError } = await supabase
223
+ .from("devices")
224
+ .select("herd_id")
225
+ .eq("id", sessionData.device_id)
226
+ .single();
227
+ if (deviceError) {
228
+ throw new Error(`Failed to get device: ${deviceError.message}`);
229
+ }
230
+ // Get sessions with coordinates for the herd and find our specific session
231
+ const { data: allSessionsWithCoords, error: sessionsError } = await supabase.rpc("get_sessions_with_coordinates", {
232
+ herd_id_caller: device.herd_id,
233
+ });
234
+ if (sessionsError) {
235
+ throw new Error(`Failed to get session with coordinates: ${sessionsError.message}`);
236
+ }
237
+ // Find the specific session in the results
238
+ sessionWithCoords =
239
+ allSessionsWithCoords?.find((s) => s.id === sessionId) || null;
199
240
  }
200
- // Find the specific session in the results
201
- const sessionWithCoords = allSessionsWithCoords?.find((s) => s.id === sessionId) || null;
202
241
  const [connectivityResult, eventsResult] = await Promise.all([
203
242
  getConnectivityBySessionId(supabase, sessionId),
204
243
  getEventsBySessionId(supabase, sessionId),
@@ -209,6 +248,67 @@ export async function getSessionWithConnectivityAndEvents(supabase, sessionId) {
209
248
  events: eventsResult,
210
249
  };
211
250
  }
251
+ // Get session with connectivity and events with tags using RPC functions
252
+ export async function getSessionWithConnectivityAndEventsWithTags(supabase, sessionId, limit = 50, offset = 0, herdId) {
253
+ let sessionWithCoords = null;
254
+ let actualHerdId;
255
+ if (herdId) {
256
+ // Use provided herd ID directly
257
+ actualHerdId = herdId;
258
+ // Get sessions with coordinates for the herd and find our specific session
259
+ const { data: allSessionsWithCoords, error: sessionsError } = await supabase.rpc("get_sessions_with_coordinates", {
260
+ herd_id_caller: actualHerdId,
261
+ });
262
+ if (sessionsError) {
263
+ throw new Error(`Failed to get session with coordinates: ${sessionsError.message}`);
264
+ }
265
+ // Find the specific session in the results
266
+ sessionWithCoords =
267
+ allSessionsWithCoords?.find((s) => s.id === sessionId) || null;
268
+ }
269
+ else {
270
+ // Get the session from the sessions table first to get the device_id
271
+ const { data: sessionData, error: sessionError } = await supabase
272
+ .from("sessions")
273
+ .select("*")
274
+ .eq("id", sessionId)
275
+ .single();
276
+ if (sessionError) {
277
+ throw new Error(`Failed to get session: ${sessionError.message}`);
278
+ }
279
+ // Get the device to find its herd_id
280
+ const { data: device, error: deviceError } = await supabase
281
+ .from("devices")
282
+ .select("herd_id")
283
+ .eq("id", sessionData.device_id)
284
+ .single();
285
+ if (deviceError) {
286
+ throw new Error(`Failed to get device: ${deviceError.message}`);
287
+ }
288
+ actualHerdId = device.herd_id;
289
+ // Get sessions with coordinates for the herd and find our specific session
290
+ const { data: allSessionsWithCoords, error: sessionsError } = await supabase.rpc("get_sessions_with_coordinates", {
291
+ herd_id_caller: actualHerdId,
292
+ });
293
+ if (sessionsError) {
294
+ throw new Error(`Failed to get session with coordinates: ${sessionsError.message}`);
295
+ }
296
+ // Find the specific session in the results
297
+ sessionWithCoords =
298
+ allSessionsWithCoords?.find((s) => s.id === sessionId) || null;
299
+ }
300
+ const [connectivityResult, eventsWithTagsResult, totalEventsResult] = await Promise.all([
301
+ getConnectivityBySessionId(supabase, sessionId),
302
+ getEventsAndTagsBySessionId(supabase, sessionId, limit, offset),
303
+ getTotalEventsForSession(supabase, sessionId),
304
+ ]);
305
+ return {
306
+ session: sessionWithCoords,
307
+ connectivity: connectivityResult,
308
+ eventsWithTags: eventsWithTagsResult,
309
+ totalEvents: totalEventsResult,
310
+ };
311
+ }
212
312
  // Get sessions for a device using RPC function
213
313
  export async function getSessionsByDeviceId(supabase, deviceId) {
214
314
  const { data, error } = await supabase.rpc("get_sessions_with_coordinates_by_device", {
@@ -403,6 +403,12 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
403
403
  isOneToOne: false;
404
404
  referencedRelation: "events_with_tags";
405
405
  referencedColumns: ["id"];
406
+ }, {
407
+ foreignKeyName: "tags_event_id_fkey";
408
+ columns: ["event_id"];
409
+ isOneToOne: false;
410
+ referencedRelation: "events_with_tags_by_session";
411
+ referencedColumns: ["id"];
406
412
  }];
407
413
  };
408
414
  users: {
@@ -500,6 +506,46 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
500
506
  media_type: Database["public"]["Enums"]["media_type"] | null;
501
507
  media_url: string | null;
502
508
  message: string | null;
509
+ session_id: number | null;
510
+ tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
511
+ timestamp_observation: string | null;
512
+ };
513
+ Relationships: [{
514
+ foreignKeyName: "devices_herd_id_fkey";
515
+ columns: ["herd_id"];
516
+ isOneToOne: false;
517
+ referencedRelation: "herds";
518
+ referencedColumns: ["id"];
519
+ }, {
520
+ foreignKeyName: "events_device_id_fkey";
521
+ columns: ["device_id"];
522
+ isOneToOne: false;
523
+ referencedRelation: "devices";
524
+ referencedColumns: ["id"];
525
+ }, {
526
+ foreignKeyName: "events_session_id_fkey";
527
+ columns: ["session_id"];
528
+ isOneToOne: false;
529
+ referencedRelation: "sessions";
530
+ referencedColumns: ["id"];
531
+ }];
532
+ };
533
+ events_with_tags_by_session: {
534
+ Row: {
535
+ altitude: number | null;
536
+ device_id: number | null;
537
+ earthranger_url: string | null;
538
+ file_path: string | null;
539
+ heading: number | null;
540
+ herd_id: number | null;
541
+ id: number | null;
542
+ inserted_at: string | null;
543
+ is_public: boolean | null;
544
+ location: unknown | null;
545
+ media_type: Database["public"]["Enums"]["media_type"] | null;
546
+ media_url: string | null;
547
+ message: string | null;
548
+ session_id: number | null;
503
549
  tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
504
550
  timestamp_observation: string | null;
505
551
  };
@@ -515,6 +561,12 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
515
561
  isOneToOne: false;
516
562
  referencedRelation: "devices";
517
563
  referencedColumns: ["id"];
564
+ }, {
565
+ foreignKeyName: "events_session_id_fkey";
566
+ columns: ["session_id"];
567
+ isOneToOne: false;
568
+ referencedRelation: "sessions";
569
+ referencedColumns: ["id"];
518
570
  }];
519
571
  };
520
572
  zones_and_actions: {
@@ -618,6 +670,14 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
618
670
  };
619
671
  Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
620
672
  };
673
+ get_events_and_tags_for_session: {
674
+ Args: {
675
+ session_id_caller: number;
676
+ limit_caller: number;
677
+ offset_caller: number;
678
+ };
679
+ Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
680
+ };
621
681
  get_events_for_herd: {
622
682
  Args: {
623
683
  herd_id_in: number;
@@ -671,6 +731,12 @@ export declare function useSupabase(): SupabaseClient<Database, "public", {
671
731
  };
672
732
  Returns: number;
673
733
  };
734
+ get_total_events_for_session: {
735
+ Args: {
736
+ session_id_caller: number;
737
+ };
738
+ Returns: number;
739
+ };
674
740
  get_zones_and_actions_for_herd: {
675
741
  Args: {
676
742
  herd_id_caller: number;
@@ -401,6 +401,12 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
401
401
  isOneToOne: false;
402
402
  referencedRelation: "events_with_tags";
403
403
  referencedColumns: ["id"];
404
+ }, {
405
+ foreignKeyName: "tags_event_id_fkey";
406
+ columns: ["event_id"];
407
+ isOneToOne: false;
408
+ referencedRelation: "events_with_tags_by_session";
409
+ referencedColumns: ["id"];
404
410
  }];
405
411
  };
406
412
  users: {
@@ -498,6 +504,46 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
498
504
  media_type: Database["public"]["Enums"]["media_type"] | null;
499
505
  media_url: string | null;
500
506
  message: string | null;
507
+ session_id: number | null;
508
+ tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
509
+ timestamp_observation: string | null;
510
+ };
511
+ Relationships: [{
512
+ foreignKeyName: "devices_herd_id_fkey";
513
+ columns: ["herd_id"];
514
+ isOneToOne: false;
515
+ referencedRelation: "herds";
516
+ referencedColumns: ["id"];
517
+ }, {
518
+ foreignKeyName: "events_device_id_fkey";
519
+ columns: ["device_id"];
520
+ isOneToOne: false;
521
+ referencedRelation: "devices";
522
+ referencedColumns: ["id"];
523
+ }, {
524
+ foreignKeyName: "events_session_id_fkey";
525
+ columns: ["session_id"];
526
+ isOneToOne: false;
527
+ referencedRelation: "sessions";
528
+ referencedColumns: ["id"];
529
+ }];
530
+ };
531
+ events_with_tags_by_session: {
532
+ Row: {
533
+ altitude: number | null;
534
+ device_id: number | null;
535
+ earthranger_url: string | null;
536
+ file_path: string | null;
537
+ heading: number | null;
538
+ herd_id: number | null;
539
+ id: number | null;
540
+ inserted_at: string | null;
541
+ is_public: boolean | null;
542
+ location: unknown | null;
543
+ media_type: Database["public"]["Enums"]["media_type"] | null;
544
+ media_url: string | null;
545
+ message: string | null;
546
+ session_id: number | null;
501
547
  tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
502
548
  timestamp_observation: string | null;
503
549
  };
@@ -513,6 +559,12 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
513
559
  isOneToOne: false;
514
560
  referencedRelation: "devices";
515
561
  referencedColumns: ["id"];
562
+ }, {
563
+ foreignKeyName: "events_session_id_fkey";
564
+ columns: ["session_id"];
565
+ isOneToOne: false;
566
+ referencedRelation: "sessions";
567
+ referencedColumns: ["id"];
516
568
  }];
517
569
  };
518
570
  zones_and_actions: {
@@ -616,6 +668,14 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
616
668
  };
617
669
  Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
618
670
  };
671
+ get_events_and_tags_for_session: {
672
+ Args: {
673
+ session_id_caller: number;
674
+ limit_caller: number;
675
+ offset_caller: number;
676
+ };
677
+ Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
678
+ };
619
679
  get_events_for_herd: {
620
680
  Args: {
621
681
  herd_id_in: number;
@@ -669,6 +729,12 @@ export declare function newServerClient(): Promise<import("@supabase/supabase-js
669
729
  };
670
730
  Returns: number;
671
731
  };
732
+ get_total_events_for_session: {
733
+ Args: {
734
+ session_id_caller: number;
735
+ };
736
+ Returns: number;
737
+ };
672
738
  get_zones_and_actions_for_herd: {
673
739
  Args: {
674
740
  herd_id_caller: number;
@@ -451,6 +451,13 @@ export type Database = {
451
451
  isOneToOne: false;
452
452
  referencedRelation: "events_with_tags";
453
453
  referencedColumns: ["id"];
454
+ },
455
+ {
456
+ foreignKeyName: "tags_event_id_fkey";
457
+ columns: ["event_id"];
458
+ isOneToOne: false;
459
+ referencedRelation: "events_with_tags_by_session";
460
+ referencedColumns: ["id"];
454
461
  }
455
462
  ];
456
463
  };
@@ -554,6 +561,50 @@ export type Database = {
554
561
  media_type: Database["public"]["Enums"]["media_type"] | null;
555
562
  media_url: string | null;
556
563
  message: string | null;
564
+ session_id: number | null;
565
+ tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
566
+ timestamp_observation: string | null;
567
+ };
568
+ Relationships: [
569
+ {
570
+ foreignKeyName: "devices_herd_id_fkey";
571
+ columns: ["herd_id"];
572
+ isOneToOne: false;
573
+ referencedRelation: "herds";
574
+ referencedColumns: ["id"];
575
+ },
576
+ {
577
+ foreignKeyName: "events_device_id_fkey";
578
+ columns: ["device_id"];
579
+ isOneToOne: false;
580
+ referencedRelation: "devices";
581
+ referencedColumns: ["id"];
582
+ },
583
+ {
584
+ foreignKeyName: "events_session_id_fkey";
585
+ columns: ["session_id"];
586
+ isOneToOne: false;
587
+ referencedRelation: "sessions";
588
+ referencedColumns: ["id"];
589
+ }
590
+ ];
591
+ };
592
+ events_with_tags_by_session: {
593
+ Row: {
594
+ altitude: number | null;
595
+ device_id: number | null;
596
+ earthranger_url: string | null;
597
+ file_path: string | null;
598
+ heading: number | null;
599
+ herd_id: number | null;
600
+ id: number | null;
601
+ inserted_at: string | null;
602
+ is_public: boolean | null;
603
+ location: unknown | null;
604
+ media_type: Database["public"]["Enums"]["media_type"] | null;
605
+ media_url: string | null;
606
+ message: string | null;
607
+ session_id: number | null;
557
608
  tags: Database["public"]["Tables"]["tags"]["Row"][] | null;
558
609
  timestamp_observation: string | null;
559
610
  };
@@ -571,6 +622,13 @@ export type Database = {
571
622
  isOneToOne: false;
572
623
  referencedRelation: "devices";
573
624
  referencedColumns: ["id"];
625
+ },
626
+ {
627
+ foreignKeyName: "events_session_id_fkey";
628
+ columns: ["session_id"];
629
+ isOneToOne: false;
630
+ referencedRelation: "sessions";
631
+ referencedColumns: ["id"];
574
632
  }
575
633
  ];
576
634
  };
@@ -677,6 +735,14 @@ export type Database = {
677
735
  };
678
736
  Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
679
737
  };
738
+ get_events_and_tags_for_session: {
739
+ Args: {
740
+ session_id_caller: number;
741
+ limit_caller: number;
742
+ offset_caller: number;
743
+ };
744
+ Returns: Database["public"]["CompositeTypes"]["event_and_tags_pretty_location"][];
745
+ };
680
746
  get_events_for_herd: {
681
747
  Args: {
682
748
  herd_id_in: number;
@@ -730,6 +796,12 @@ export type Database = {
730
796
  };
731
797
  Returns: number;
732
798
  };
799
+ get_total_events_for_session: {
800
+ Args: {
801
+ session_id_caller: number;
802
+ };
803
+ Returns: number;
804
+ };
733
805
  get_zones_and_actions_for_herd: {
734
806
  Args: {
735
807
  herd_id_caller: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.0.32",
3
+ "version": "1.0.33",
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",