@adventurelabs/scout-core 1.3.4 → 1.3.6

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 = 4; // Increment to invalidate old cache versions
2
+ const DB_VERSION = 5; // Increment to invalidate old cache versions
3
3
  const HERD_MODULES_STORE = "herd_modules";
4
4
  const CACHE_METADATA_STORE = "cache_metadata";
5
5
  // Default TTL: 24 hours (1 day)
@@ -1,36 +1,7 @@
1
- import { ISession, IConnectivity, IEvent, ISessionWithCoordinates, IConnectivityWithCoordinates, IEventAndTagsPrettyLocation } from "../types/db";
1
+ import { ISessionWithCoordinates, ISessionUsageOverTime, IEventAndTagsPrettyLocation } from "../types/db";
2
2
  import { IWebResponseCompatible } from "../types/requests";
3
- export type SessionInput = Omit<ISession, "id" | "inserted_at">;
4
- export type SessionUpdateInput = Partial<SessionInput> & {
5
- id: number;
6
- };
7
- export type SessionUpsertInput = SessionInput | SessionUpdateInput;
8
- export type ConnectivityInput = Omit<IConnectivity, "id" | "inserted_at">;
9
- export type ConnectivityUpdateInput = Partial<ConnectivityInput> & {
10
- id: number;
11
- };
12
- export type ConnectivityUpsertInput = ConnectivityInput | ConnectivityUpdateInput;
13
- export declare function server_get_sessions_by_herd_id(herdId: number): Promise<IWebResponseCompatible<ISessionWithCoordinates[]>>;
14
- export declare function server_get_events_by_session_id(sessionId: number): Promise<IWebResponseCompatible<IEvent[]>>;
3
+ import { SupabaseClient } from "@supabase/supabase-js";
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>>;
15
7
  export declare function server_get_events_and_tags_by_session_id(sessionId: number, limit?: number, offset?: number): Promise<IWebResponseCompatible<IEventAndTagsPrettyLocation[]>>;
16
- export declare function server_get_total_events_for_session(sessionId: number): Promise<IWebResponseCompatible<number>>;
17
- export declare function server_upsert_session(sessionData: SessionUpsertInput): Promise<IWebResponseCompatible<ISession>>;
18
- export declare function server_upsert_sessions(sessionsData: SessionUpsertInput[]): Promise<IWebResponseCompatible<ISession[]>>;
19
- export declare function server_upsert_connectivity(connectivityData: ConnectivityUpsertInput): Promise<IWebResponseCompatible<IConnectivity>>;
20
- export declare function server_upsert_connectivity_batch(connectivityDataArray: ConnectivityUpsertInput[]): Promise<IWebResponseCompatible<IConnectivity[]>>;
21
- export declare function server_get_session_with_connectivity_and_events(sessionId: number, herdId?: number): Promise<IWebResponseCompatible<{
22
- session: ISessionWithCoordinates | null;
23
- connectivity: IConnectivityWithCoordinates[];
24
- events: IEvent[];
25
- }>>;
26
- export declare function server_get_session_with_connectivity_and_events_with_tags(sessionId: number, limit?: number, offset?: number, herdId?: number): Promise<IWebResponseCompatible<{
27
- session: ISessionWithCoordinates | null;
28
- connectivity: IConnectivityWithCoordinates[];
29
- eventsWithTags: IEventAndTagsPrettyLocation[];
30
- totalEvents: number;
31
- }>>;
32
- export declare function server_get_sessions_by_device_id(deviceId: number): Promise<IWebResponseCompatible<ISessionWithCoordinates[]>>;
33
- export declare function server_delete_session(sessionId: number): Promise<IWebResponseCompatible<boolean>>;
34
- export declare function server_delete_sessions(sessionIds: number[]): Promise<IWebResponseCompatible<boolean>>;
35
- export declare function server_delete_connectivity(connectivityId: number): Promise<IWebResponseCompatible<boolean>>;
36
- export declare function server_delete_connectivity_batch(connectivityIds: number[]): Promise<IWebResponseCompatible<boolean>>;
@@ -1,47 +1,57 @@
1
1
  "use server";
2
2
  import { newServerClient } from "../supabase/server";
3
3
  import { EnumWebResponse, IWebResponse, } from "../types/requests";
4
- import { server_get_connectivity_by_session_id } from "./connectivity";
5
- // Get sessions by herd id using RPC function with coordinates
6
- export async function server_get_sessions_by_herd_id(herdId) {
7
- const supabase = await newServerClient();
8
- const { data, error } = await supabase.rpc("get_sessions_with_coordinates", {
9
- herd_id_caller: herdId,
4
+ // Get session by ID with coordinates
5
+ export async function server_get_session_by_id(sessionId, client) {
6
+ const supabase = client || (await newServerClient());
7
+ const { data, error } = await supabase.rpc("get_session_by_id", {
8
+ session_id_caller: sessionId,
10
9
  });
11
10
  if (error) {
12
- console.warn("Error fetching sessions by herd id:", error.message);
11
+ console.warn("Error fetching session by id:", error.message);
13
12
  return {
14
13
  status: EnumWebResponse.ERROR,
15
14
  msg: error.message,
16
- data: [],
15
+ data: null,
17
16
  };
18
17
  }
19
- // Sort by timestamp_start in descending order
20
- const sortedSessions = (data || []).sort((a, b) => {
21
- if (!a.timestamp_start || !b.timestamp_start)
22
- return 0;
23
- return (new Date(b.timestamp_start).getTime() -
24
- new Date(a.timestamp_start).getTime());
18
+ // The RPC returns an array, but we want a single session or null
19
+ const session = data && data.length > 0 ? data[0] : null;
20
+ return IWebResponse.success(session).to_compatible();
21
+ }
22
+ // Get session usage over time by herd
23
+ export async function server_get_session_usage_over_time_by_herd(herd_id, client) {
24
+ const supabase = client || (await newServerClient());
25
+ const { data, error } = await supabase.rpc("get_session_usage_over_time", {
26
+ start_date_caller: undefined,
27
+ end_date_caller: undefined,
28
+ device_id_caller: undefined,
29
+ herd_id_caller: herd_id,
25
30
  });
26
- return IWebResponse.success(sortedSessions).to_compatible();
31
+ if (error) {
32
+ return IWebResponse.error(error.message).to_compatible();
33
+ }
34
+ if (!data) {
35
+ return IWebResponse.error("No session usage data returned").to_compatible();
36
+ }
37
+ return IWebResponse.success(data).to_compatible();
27
38
  }
28
- // Get events by session id
29
- export async function server_get_events_by_session_id(sessionId) {
30
- const supabase = await newServerClient();
31
- const { data, error } = await supabase
32
- .from("events")
33
- .select("*")
34
- .eq("session_id", sessionId)
35
- .order("timestamp_observation", { ascending: true });
39
+ // Get session usage over time by device
40
+ export async function server_get_session_usage_over_time_by_device(device_id, client) {
41
+ const supabase = client || (await newServerClient());
42
+ const { data, error } = await supabase.rpc("get_session_usage_over_time", {
43
+ start_date_caller: undefined,
44
+ end_date_caller: undefined,
45
+ device_id_caller: device_id,
46
+ herd_id_caller: undefined,
47
+ });
36
48
  if (error) {
37
- console.warn("Error fetching events by session id:", error.message);
38
- return {
39
- status: EnumWebResponse.ERROR,
40
- msg: error.message,
41
- data: [],
42
- };
49
+ return IWebResponse.error(error.message).to_compatible();
43
50
  }
44
- return IWebResponse.success(data || []).to_compatible();
51
+ if (!data) {
52
+ return IWebResponse.error("No session usage data returned").to_compatible();
53
+ }
54
+ return IWebResponse.success(data).to_compatible();
45
55
  }
46
56
  // Get events with tags by session id using RPC function
47
57
  export async function server_get_events_and_tags_by_session_id(sessionId, limit = 50, offset = 0) {
@@ -61,429 +71,3 @@ export async function server_get_events_and_tags_by_session_id(sessionId, limit
61
71
  }
62
72
  return IWebResponse.success(data || []).to_compatible();
63
73
  }
64
- // Get total count of events for a session
65
- export async function server_get_total_events_for_session(sessionId) {
66
- const supabase = await newServerClient();
67
- const { data, error } = await supabase.rpc("get_total_events_for_session", {
68
- session_id_caller: sessionId,
69
- });
70
- if (error) {
71
- console.warn("Error fetching total events for session:", error.message);
72
- return {
73
- status: EnumWebResponse.ERROR,
74
- msg: error.message,
75
- data: 0,
76
- };
77
- }
78
- return IWebResponse.success(data || 0).to_compatible();
79
- }
80
- // Create or update session
81
- export async function server_upsert_session(sessionData) {
82
- const supabase = await newServerClient();
83
- const isUpdate = "id" in sessionData;
84
- if (isUpdate) {
85
- // Update existing session
86
- const { id, ...updateData } = sessionData;
87
- const { data, error } = await supabase
88
- .from("sessions")
89
- .update(updateData)
90
- .eq("id", id)
91
- .select()
92
- .single();
93
- if (error) {
94
- console.warn("Error updating session:", error.message);
95
- return {
96
- status: EnumWebResponse.ERROR,
97
- msg: error.message,
98
- data: null,
99
- };
100
- }
101
- return IWebResponse.success(data).to_compatible();
102
- }
103
- else {
104
- // Create new session
105
- const { data, error } = await supabase
106
- .from("sessions")
107
- .insert(sessionData)
108
- .select()
109
- .single();
110
- if (error) {
111
- console.warn("Error creating session:", error.message);
112
- return {
113
- status: EnumWebResponse.ERROR,
114
- msg: error.message,
115
- data: null,
116
- };
117
- }
118
- return IWebResponse.success(data).to_compatible();
119
- }
120
- }
121
- // Batch upsert sessions
122
- export async function server_upsert_sessions(sessionsData) {
123
- const supabase = await newServerClient();
124
- if (sessionsData.length === 0) {
125
- return IWebResponse.success([]).to_compatible();
126
- }
127
- // Separate updates and inserts
128
- const updates = sessionsData.filter((s) => "id" in s);
129
- const inserts = sessionsData.filter((s) => !("id" in s));
130
- const results = [];
131
- // Handle updates
132
- if (updates.length > 0) {
133
- for (const sessionData of updates) {
134
- const updateResult = await server_upsert_session(sessionData);
135
- if (updateResult.status === EnumWebResponse.SUCCESS &&
136
- updateResult.data) {
137
- results.push(updateResult.data);
138
- }
139
- else {
140
- console.warn(`Failed to update session ${sessionData.id}:`, updateResult.msg);
141
- }
142
- }
143
- }
144
- // Handle inserts
145
- if (inserts.length > 0) {
146
- const { data, error } = await supabase
147
- .from("sessions")
148
- .insert(inserts)
149
- .select();
150
- if (error) {
151
- console.warn("Error creating sessions:", error.message);
152
- return {
153
- status: EnumWebResponse.ERROR,
154
- msg: error.message,
155
- data: results,
156
- };
157
- }
158
- results.push(...(data || []));
159
- }
160
- return IWebResponse.success(results).to_compatible();
161
- }
162
- // Create or update connectivity
163
- export async function server_upsert_connectivity(connectivityData) {
164
- const supabase = await newServerClient();
165
- const isUpdate = "id" in connectivityData;
166
- if (isUpdate) {
167
- // Update existing connectivity
168
- const { id, ...updateData } = connectivityData;
169
- const { data, error } = await supabase
170
- .from("connectivity")
171
- .update(updateData)
172
- .eq("id", id)
173
- .select()
174
- .single();
175
- if (error) {
176
- console.warn("Error updating connectivity:", error.message);
177
- return {
178
- status: EnumWebResponse.ERROR,
179
- msg: error.message,
180
- data: null,
181
- };
182
- }
183
- return IWebResponse.success(data).to_compatible();
184
- }
185
- else {
186
- // Create new connectivity
187
- const { data, error } = await supabase
188
- .from("connectivity")
189
- .insert(connectivityData)
190
- .select()
191
- .single();
192
- if (error) {
193
- console.warn("Error creating connectivity:", error.message);
194
- return {
195
- status: EnumWebResponse.ERROR,
196
- msg: error.message,
197
- data: null,
198
- };
199
- }
200
- return IWebResponse.success(data).to_compatible();
201
- }
202
- }
203
- // Batch upsert connectivity
204
- export async function server_upsert_connectivity_batch(connectivityDataArray) {
205
- const supabase = await newServerClient();
206
- if (connectivityDataArray.length === 0) {
207
- return IWebResponse.success([]).to_compatible();
208
- }
209
- // Separate updates and inserts
210
- const updates = connectivityDataArray.filter((c) => "id" in c);
211
- const inserts = connectivityDataArray.filter((c) => !("id" in c));
212
- const results = [];
213
- // Handle updates
214
- if (updates.length > 0) {
215
- for (const connectivityData of updates) {
216
- const updateResult = await server_upsert_connectivity(connectivityData);
217
- if (updateResult.status === EnumWebResponse.SUCCESS &&
218
- updateResult.data) {
219
- results.push(updateResult.data);
220
- }
221
- else {
222
- console.warn(`Failed to update connectivity ${connectivityData.id}:`, updateResult.msg);
223
- }
224
- }
225
- }
226
- // Handle inserts
227
- if (inserts.length > 0) {
228
- const { data, error } = await supabase
229
- .from("connectivity")
230
- .insert(inserts)
231
- .select();
232
- if (error) {
233
- console.warn("Error creating connectivity entries:", error.message);
234
- return {
235
- status: EnumWebResponse.ERROR,
236
- msg: error.message,
237
- data: results,
238
- };
239
- }
240
- results.push(...(data || []));
241
- }
242
- return IWebResponse.success(results).to_compatible();
243
- }
244
- // Get session with connectivity and events using RPC functions
245
- export async function server_get_session_with_connectivity_and_events(sessionId, herdId) {
246
- const supabase = await newServerClient();
247
- let sessionWithCoords = null;
248
- if (herdId) {
249
- // Use provided herd ID directly
250
- const sessionsResult = await server_get_sessions_by_herd_id(herdId);
251
- if (sessionsResult.status === EnumWebResponse.SUCCESS &&
252
- sessionsResult.data) {
253
- sessionWithCoords =
254
- sessionsResult.data.find((s) => s.id === sessionId) || null;
255
- }
256
- }
257
- else {
258
- // Get the session from the sessions table first to get the device_id
259
- const { data: sessionData, error: sessionError } = await supabase
260
- .from("sessions")
261
- .select("*")
262
- .eq("id", sessionId)
263
- .single();
264
- if (sessionError) {
265
- console.warn("Error getting session:", sessionError.message);
266
- return {
267
- status: EnumWebResponse.ERROR,
268
- msg: sessionError.message,
269
- data: {
270
- session: null,
271
- connectivity: [],
272
- events: [],
273
- },
274
- };
275
- }
276
- // Get the device to find its herd_id
277
- const { data: device, error: deviceError } = await supabase
278
- .from("devices")
279
- .select("herd_id")
280
- .eq("id", sessionData.device_id)
281
- .single();
282
- if (deviceError) {
283
- console.warn("Error getting device:", deviceError.message);
284
- return {
285
- status: EnumWebResponse.ERROR,
286
- msg: deviceError.message,
287
- data: {
288
- session: null,
289
- connectivity: [],
290
- events: [],
291
- },
292
- };
293
- }
294
- const sessionsResult = await server_get_sessions_by_herd_id(device.herd_id);
295
- if (sessionsResult.status === EnumWebResponse.SUCCESS &&
296
- sessionsResult.data) {
297
- sessionWithCoords =
298
- sessionsResult.data.find((s) => s.id === sessionId) || null;
299
- }
300
- }
301
- const [connectivityResult, eventsResult] = await Promise.all([
302
- server_get_connectivity_by_session_id(sessionId),
303
- server_get_events_by_session_id(sessionId),
304
- ]);
305
- const connectivity = connectivityResult.status === EnumWebResponse.SUCCESS
306
- ? connectivityResult.data || []
307
- : [];
308
- const events = eventsResult.status === EnumWebResponse.SUCCESS
309
- ? eventsResult.data || []
310
- : [];
311
- return IWebResponse.success({
312
- session: sessionWithCoords,
313
- connectivity,
314
- events,
315
- }).to_compatible();
316
- }
317
- // Get session with connectivity and events with tags using RPC functions
318
- export async function server_get_session_with_connectivity_and_events_with_tags(sessionId, limit = 50, offset = 0, herdId) {
319
- const supabase = await newServerClient();
320
- let sessionWithCoords = null;
321
- let actualHerdId;
322
- if (herdId) {
323
- // Use provided herd ID directly
324
- actualHerdId = herdId;
325
- const sessionsResult = await server_get_sessions_by_herd_id(herdId);
326
- if (sessionsResult.status === EnumWebResponse.SUCCESS &&
327
- sessionsResult.data) {
328
- sessionWithCoords =
329
- sessionsResult.data.find((s) => s.id === sessionId) || null;
330
- }
331
- }
332
- else {
333
- // Get the session from the sessions table first to get the device_id
334
- const { data: sessionData, error: sessionError } = await supabase
335
- .from("sessions")
336
- .select("*")
337
- .eq("id", sessionId)
338
- .single();
339
- if (sessionError) {
340
- console.warn("Error getting session:", sessionError.message);
341
- return {
342
- status: EnumWebResponse.ERROR,
343
- msg: sessionError.message,
344
- data: {
345
- session: null,
346
- connectivity: [],
347
- eventsWithTags: [],
348
- totalEvents: 0,
349
- },
350
- };
351
- }
352
- // Get the device to find its herd_id
353
- const { data: device, error: deviceError } = await supabase
354
- .from("devices")
355
- .select("herd_id")
356
- .eq("id", sessionData.device_id)
357
- .single();
358
- if (deviceError) {
359
- console.warn("Error getting device:", deviceError.message);
360
- return {
361
- status: EnumWebResponse.ERROR,
362
- msg: deviceError.message,
363
- data: {
364
- session: null,
365
- connectivity: [],
366
- eventsWithTags: [],
367
- totalEvents: 0,
368
- },
369
- };
370
- }
371
- actualHerdId = device.herd_id;
372
- const sessionsResult = await server_get_sessions_by_herd_id(device.herd_id);
373
- if (sessionsResult.status === EnumWebResponse.SUCCESS &&
374
- sessionsResult.data) {
375
- sessionWithCoords =
376
- sessionsResult.data.find((s) => s.id === sessionId) || null;
377
- }
378
- }
379
- const [connectivityResult, eventsWithTagsResult, totalEventsResult] = await Promise.all([
380
- server_get_connectivity_by_session_id(sessionId),
381
- server_get_events_and_tags_by_session_id(sessionId, limit, offset),
382
- server_get_total_events_for_session(sessionId),
383
- ]);
384
- const connectivity = connectivityResult.status === EnumWebResponse.SUCCESS
385
- ? connectivityResult.data || []
386
- : [];
387
- const eventsWithTags = eventsWithTagsResult.status === EnumWebResponse.SUCCESS
388
- ? eventsWithTagsResult.data || []
389
- : [];
390
- const totalEvents = totalEventsResult.status === EnumWebResponse.SUCCESS
391
- ? totalEventsResult.data || 0
392
- : 0;
393
- return IWebResponse.success({
394
- session: sessionWithCoords,
395
- connectivity,
396
- eventsWithTags,
397
- totalEvents,
398
- }).to_compatible();
399
- }
400
- // Get sessions for a device using RPC function
401
- export async function server_get_sessions_by_device_id(deviceId) {
402
- const supabase = await newServerClient();
403
- const { data, error } = await supabase.rpc("get_sessions_with_coordinates_by_device", {
404
- device_id_caller: deviceId,
405
- });
406
- if (error) {
407
- console.warn("Error fetching sessions by device id:", error.message);
408
- return {
409
- status: EnumWebResponse.ERROR,
410
- msg: error.message,
411
- data: [],
412
- };
413
- }
414
- return IWebResponse.success(data || []).to_compatible();
415
- }
416
- // Delete session and all related data
417
- export async function server_delete_session(sessionId) {
418
- const supabase = await newServerClient();
419
- const { error } = await supabase
420
- .from("sessions")
421
- .delete()
422
- .eq("id", sessionId);
423
- if (error) {
424
- console.warn("Error deleting session:", error.message);
425
- return {
426
- status: EnumWebResponse.ERROR,
427
- msg: error.message,
428
- data: false,
429
- };
430
- }
431
- return IWebResponse.success(true).to_compatible();
432
- }
433
- // Batch delete sessions
434
- export async function server_delete_sessions(sessionIds) {
435
- const supabase = await newServerClient();
436
- if (sessionIds.length === 0) {
437
- return IWebResponse.success(true).to_compatible();
438
- }
439
- const { error } = await supabase
440
- .from("sessions")
441
- .delete()
442
- .in("id", sessionIds);
443
- if (error) {
444
- console.warn("Error deleting sessions:", error.message);
445
- return {
446
- status: EnumWebResponse.ERROR,
447
- msg: error.message,
448
- data: false,
449
- };
450
- }
451
- return IWebResponse.success(true).to_compatible();
452
- }
453
- // Delete connectivity entry
454
- export async function server_delete_connectivity(connectivityId) {
455
- const supabase = await newServerClient();
456
- const { error } = await supabase
457
- .from("connectivity")
458
- .delete()
459
- .eq("id", connectivityId);
460
- if (error) {
461
- console.warn("Error deleting connectivity:", error.message);
462
- return {
463
- status: EnumWebResponse.ERROR,
464
- msg: error.message,
465
- data: false,
466
- };
467
- }
468
- return IWebResponse.success(true).to_compatible();
469
- }
470
- // Batch delete connectivity entries
471
- export async function server_delete_connectivity_batch(connectivityIds) {
472
- const supabase = await newServerClient();
473
- if (connectivityIds.length === 0) {
474
- return IWebResponse.success(true).to_compatible();
475
- }
476
- const { error } = await supabase
477
- .from("connectivity")
478
- .delete()
479
- .in("id", connectivityIds);
480
- if (error) {
481
- console.warn("Error deleting connectivity entries:", error.message);
482
- return {
483
- status: EnumWebResponse.ERROR,
484
- msg: error.message,
485
- data: false,
486
- };
487
- }
488
- return IWebResponse.success(true).to_compatible();
489
- }
@@ -1405,6 +1405,18 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1405
1405
  isSetofReturn: true;
1406
1406
  };
1407
1407
  };
1408
+ get_session_by_id: {
1409
+ Args: {
1410
+ session_id_caller: number;
1411
+ };
1412
+ Returns: Database["public"]["CompositeTypes"]["session_with_coordinates"][];
1413
+ SetofOptions: {
1414
+ from: "*";
1415
+ to: "session_with_coordinates";
1416
+ isOneToOne: false;
1417
+ isSetofReturn: true;
1418
+ };
1419
+ };
1408
1420
  get_session_summaries: {
1409
1421
  Args: {
1410
1422
  device_id_caller?: number;
@@ -1414,6 +1426,15 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1414
1426
  };
1415
1427
  Returns: import("../types/supabase").Json;
1416
1428
  };
1429
+ get_session_usage_over_time: {
1430
+ Args: {
1431
+ device_id_caller?: number;
1432
+ end_date_caller?: string;
1433
+ herd_id_caller?: number;
1434
+ start_date_caller?: string;
1435
+ };
1436
+ Returns: import("../types/supabase").Json;
1437
+ };
1417
1438
  get_sessions_infinite_by_device: {
1418
1439
  Args: {
1419
1440
  cursor_id?: number;
@@ -48,6 +48,7 @@ export interface ISessionSummary {
48
48
  herd_id: number | null;
49
49
  };
50
50
  }
51
+ export type ISessionUsageOverTime = Database["public"]["Functions"]["get_session_usage_over_time"]["Returns"];
51
52
  export type ComponentInsert = Database["public"]["Tables"]["components"]["Insert"];
52
53
  export type VersionsSoftwareInsert = Database["public"]["Tables"]["versions_software"]["Insert"];
53
54
  export type ArtifactInsert = Database["public"]["Tables"]["artifacts"]["Insert"];
@@ -1,5 +1,5 @@
1
1
  import { SupabaseClient } from "@supabase/supabase-js";
2
- import { IDevice, IHerd, IPlan, ILayer, IProvider, IUserAndRole, IZoneWithActions, ISessionSummary } from "../types/db";
2
+ import { IDevice, IHerd, 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",
@@ -18,7 +18,8 @@ export declare class HerdModule {
18
18
  layers: ILayer[];
19
19
  providers: IProvider[];
20
20
  session_summaries: ISessionSummary | null;
21
- 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);
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
23
  to_serializable(): IHerdModule;
23
24
  static from_herd(herd: IHerd, client: SupabaseClient): Promise<HerdModule>;
24
25
  }
@@ -33,6 +34,7 @@ export interface IHerdModule {
33
34
  layers: ILayer[];
34
35
  providers: IProvider[];
35
36
  session_summaries: ISessionSummary | null;
37
+ session_usage: ISessionUsageOverTime | null;
36
38
  }
37
39
  export interface IHerdModulesResponse {
38
40
  data: IHerdModule[];
@@ -1,7 +1,5 @@
1
1
  import { LABELS } from "../constants/annotator";
2
2
  import { get_devices_by_herd } from "../helpers/devices";
3
- import { server_get_total_events_by_herd } from "../helpers/events";
4
- import { EnumSessionsVisibility } from "./events";
5
3
  import { server_get_plans_by_herd } from "../helpers/plans";
6
4
  import { server_get_layers_by_herd } from "../helpers/layers";
7
5
  import { server_get_providers_by_herd } from "../helpers/providers";
@@ -9,9 +7,8 @@ import { server_get_users_with_herd_access } from "../helpers/users";
9
7
  import { EnumWebResponse } from "./requests";
10
8
  import { server_get_more_zones_and_actions_for_herd } from "../helpers/zones";
11
9
  import { server_list_api_keys_batch } from "../api_keys/actions";
12
- import { server_get_sessions_by_herd_id } from "../helpers/sessions";
13
- import { server_get_artifacts_by_herd, server_get_total_artifacts_by_herd, } from "../helpers/artifacts";
14
10
  import { server_get_session_summaries_by_herd } from "../helpers/session_summaries";
11
+ import { server_get_session_usage_over_time_by_herd } from "../helpers/sessions";
15
12
  export var EnumHerdModulesLoadingState;
16
13
  (function (EnumHerdModulesLoadingState) {
17
14
  EnumHerdModulesLoadingState["NOT_LOADING"] = "NOT_LOADING";
@@ -20,13 +17,14 @@ export var EnumHerdModulesLoadingState;
20
17
  EnumHerdModulesLoadingState["UNSUCCESSFULLY_LOADED"] = "UNSUCCESSFULLY_LOADED";
21
18
  })(EnumHerdModulesLoadingState || (EnumHerdModulesLoadingState = {}));
22
19
  export class HerdModule {
23
- constructor(herd, devices, timestamp_last_refreshed, user_roles = null, labels = [], plans = [], zones = [], layers = [], providers = [], session_summaries = null) {
20
+ constructor(herd, devices, timestamp_last_refreshed, user_roles = null, labels = [], plans = [], zones = [], layers = [], providers = [], session_summaries = null, session_usage = null) {
24
21
  this.user_roles = null;
25
22
  this.labels = [];
26
23
  this.plans = [];
27
24
  this.layers = [];
28
25
  this.providers = [];
29
26
  this.session_summaries = null;
27
+ this.session_usage = null;
30
28
  this.herd = herd;
31
29
  this.devices = devices;
32
30
  this.timestamp_last_refreshed = timestamp_last_refreshed;
@@ -37,6 +35,7 @@ export class HerdModule {
37
35
  this.layers = layers;
38
36
  this.providers = providers;
39
37
  this.session_summaries = session_summaries;
38
+ this.session_usage = session_usage;
40
39
  }
41
40
  to_serializable() {
42
41
  return {
@@ -50,6 +49,7 @@ export class HerdModule {
50
49
  layers: this.layers,
51
50
  providers: this.providers,
52
51
  session_summaries: this.session_summaries,
52
+ session_usage: this.session_usage,
53
53
  };
54
54
  }
55
55
  static async from_herd(herd, client) {
@@ -65,22 +65,10 @@ export class HerdModule {
65
65
  console.warn(`[HerdModule] Failed to get user roles:`, error);
66
66
  return { status: EnumWebResponse.ERROR, data: null };
67
67
  }),
68
- server_get_total_events_by_herd(herd.id, EnumSessionsVisibility.Exclude).catch((error) => {
69
- console.warn(`[HerdModule] Failed to get total events count:`, error);
70
- return { status: EnumWebResponse.ERROR, data: null };
71
- }),
72
68
  server_get_plans_by_herd(herd.id).catch((error) => {
73
69
  console.warn(`[HerdModule] Failed to get plans:`, error);
74
70
  return { status: EnumWebResponse.ERROR, data: null };
75
71
  }),
76
- server_get_sessions_by_herd_id(herd.id).catch((error) => {
77
- console.warn(`[HerdModule] Failed to get sessions:`, error);
78
- return {
79
- status: EnumWebResponse.ERROR,
80
- data: [],
81
- msg: error.message,
82
- };
83
- }),
84
72
  server_get_layers_by_herd(herd.id).catch((error) => {
85
73
  console.warn(`[HerdModule] Failed to get layers:`, error);
86
74
  return { status: EnumWebResponse.ERROR, data: null };
@@ -89,18 +77,14 @@ export class HerdModule {
89
77
  console.warn(`[HerdModule] Failed to get providers:`, error);
90
78
  return { status: EnumWebResponse.ERROR, data: null };
91
79
  }),
92
- server_get_artifacts_by_herd(herd.id, 50, 0).catch((error) => {
93
- console.warn(`[HerdModule] Failed to get artifacts:`, error);
94
- return { status: EnumWebResponse.ERROR, data: null };
95
- }),
96
- server_get_total_artifacts_by_herd(herd.id).catch((error) => {
97
- console.warn(`[HerdModule] Failed to get total artifacts count:`, error);
98
- return { status: EnumWebResponse.ERROR, data: null };
99
- }),
100
80
  server_get_session_summaries_by_herd(herd.id, client).catch((error) => {
101
81
  console.warn(`[HerdModule] Failed to get session summaries:`, error);
102
82
  return { status: EnumWebResponse.ERROR, data: null };
103
83
  }),
84
+ server_get_session_usage_over_time_by_herd(herd.id, client).catch((error) => {
85
+ console.warn(`[HerdModule] Failed to get session usage:`, error);
86
+ return { status: EnumWebResponse.ERROR, data: null };
87
+ }),
104
88
  ]);
105
89
  // Load devices
106
90
  const devicesPromise = get_devices_by_herd(herd.id, client);
@@ -133,53 +117,43 @@ export class HerdModule {
133
117
  }
134
118
  }
135
119
  // Extract herd-level data with safe fallbacks
136
- const [res_zones, res_user_roles, total_event_count, res_plans, res_sessions, res_layers, res_providers, res_artifacts, total_artifact_count, session_summaries_result,] = herdLevelResults;
120
+ const [res_zones, res_user_roles, res_plans, res_layers, res_providers, session_summaries_result, session_usage_result,] = herdLevelResults;
137
121
  const zones = res_zones.status === "fulfilled" && res_zones.value?.data
138
122
  ? res_zones.value.data
139
123
  : [];
140
124
  const user_roles = res_user_roles.status === "fulfilled" && res_user_roles.value?.data
141
125
  ? res_user_roles.value.data
142
126
  : null;
143
- const total_events = total_event_count.status === "fulfilled" &&
144
- total_event_count.value?.data
145
- ? total_event_count.value.data
146
- : 0;
147
127
  const plans = res_plans.status === "fulfilled" && res_plans.value?.data
148
128
  ? res_plans.value.data
149
129
  : [];
150
- const sessions = res_sessions.status === "fulfilled" && res_sessions.value?.data
151
- ? res_sessions.value.data
152
- : [];
153
130
  const layers = res_layers.status === "fulfilled" && res_layers.value?.data
154
131
  ? res_layers.value.data
155
132
  : [];
156
133
  const providers = res_providers.status === "fulfilled" && res_providers.value?.data
157
134
  ? res_providers.value.data
158
135
  : [];
159
- const artifacts = res_artifacts.status === "fulfilled" && res_artifacts.value?.data
160
- ? res_artifacts.value.data
161
- : [];
162
- const total_artifacts = total_artifact_count.status === "fulfilled" &&
163
- total_artifact_count.value?.data
164
- ? total_artifact_count.value.data
165
- : 0;
166
136
  const session_summaries = session_summaries_result.status === "fulfilled" &&
167
137
  session_summaries_result.value?.data
168
138
  ? session_summaries_result.value.data
169
139
  : null;
140
+ const session_usage = session_usage_result.status === "fulfilled" &&
141
+ session_usage_result.value?.data
142
+ ? session_usage_result.value.data
143
+ : null;
170
144
  // TODO: store in DB and retrieve on load?
171
145
  const newLabels = LABELS;
172
146
  const endTime = Date.now();
173
147
  const loadTime = endTime - startTime;
174
148
  console.log(`[HerdModule] Loaded herd ${herd.slug} in ${loadTime}ms (${new_devices.length} devices)`);
175
- return new HerdModule(herd, new_devices, Date.now(), user_roles, newLabels, plans, zones, layers, providers, session_summaries);
149
+ return new HerdModule(herd, new_devices, Date.now(), user_roles, newLabels, plans, zones, layers, providers, session_summaries, session_usage);
176
150
  }
177
151
  catch (error) {
178
152
  const endTime = Date.now();
179
153
  const loadTime = endTime - startTime;
180
154
  console.error(`[HerdModule] Critical error in HerdModule.from_herd (${loadTime}ms):`, error);
181
155
  // Return a minimal but valid HerdModule instance to prevent complete failure
182
- return new HerdModule(herd, [], Date.now(), null, [], [], [], [], [], null);
156
+ return new HerdModule(herd, [], Date.now(), null, [], [], [], [], [], null, null);
183
157
  }
184
158
  }
185
159
  }
@@ -1460,6 +1460,18 @@ export type Database = {
1460
1460
  isSetofReturn: true;
1461
1461
  };
1462
1462
  };
1463
+ get_session_by_id: {
1464
+ Args: {
1465
+ session_id_caller: number;
1466
+ };
1467
+ Returns: Database["public"]["CompositeTypes"]["session_with_coordinates"][];
1468
+ SetofOptions: {
1469
+ from: "*";
1470
+ to: "session_with_coordinates";
1471
+ isOneToOne: false;
1472
+ isSetofReturn: true;
1473
+ };
1474
+ };
1463
1475
  get_session_summaries: {
1464
1476
  Args: {
1465
1477
  device_id_caller?: number;
@@ -1469,6 +1481,15 @@ export type Database = {
1469
1481
  };
1470
1482
  Returns: Json;
1471
1483
  };
1484
+ get_session_usage_over_time: {
1485
+ Args: {
1486
+ device_id_caller?: number;
1487
+ end_date_caller?: string;
1488
+ herd_id_caller?: number;
1489
+ start_date_caller?: string;
1490
+ };
1491
+ Returns: Json;
1492
+ };
1472
1493
  get_sessions_infinite_by_device: {
1473
1494
  Args: {
1474
1495
  cursor_id?: number;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.3.4",
3
+ "version": "1.3.6",
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",