@adventurelabs/scout-core 1.0.97 → 1.0.99

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.
@@ -40,38 +40,60 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
40
40
  switch (data.operation) {
41
41
  case "INSERT":
42
42
  if (!updatedConnectivity[deviceId]) {
43
- updatedConnectivity[deviceId] = [];
43
+ updatedConnectivity[deviceId] = {
44
+ most_recent: connectivityData,
45
+ history: [connectivityData],
46
+ };
44
47
  }
45
48
  else {
46
- // Create a copy of the existing array to avoid mutating immutable state
47
- updatedConnectivity[deviceId] = [...updatedConnectivity[deviceId]];
48
- }
49
- updatedConnectivity[deviceId].push(connectivityData);
50
- // Keep only recent 100 entries
51
- if (updatedConnectivity[deviceId].length > 100) {
52
- updatedConnectivity[deviceId] = updatedConnectivity[deviceId]
49
+ // Create a copy of the existing historical data
50
+ const newHistory = [
51
+ ...updatedConnectivity[deviceId].history,
52
+ connectivityData,
53
+ ];
54
+ // Keep only recent 100 entries
55
+ const sortedHistory = newHistory
53
56
  .sort((a, b) => new Date(b.timestamp_start || 0).getTime() -
54
57
  new Date(a.timestamp_start || 0).getTime())
55
58
  .slice(0, 100);
59
+ updatedConnectivity[deviceId] = {
60
+ most_recent: sortedHistory[0],
61
+ history: sortedHistory,
62
+ };
56
63
  }
57
64
  break;
58
65
  case "UPDATE":
59
66
  if (updatedConnectivity[deviceId]) {
60
- // Create a copy of the array before modifying
61
- updatedConnectivity[deviceId] = [...updatedConnectivity[deviceId]];
62
- const index = updatedConnectivity[deviceId].findIndex((c) => c.id === connectivityData.id);
67
+ // Create a copy of the history array before modifying
68
+ const newHistory = [...updatedConnectivity[deviceId].history];
69
+ const index = newHistory.findIndex((c) => c.id === connectivityData.id);
63
70
  if (index >= 0) {
64
- updatedConnectivity[deviceId][index] = connectivityData;
71
+ newHistory[index] = connectivityData;
72
+ // Update most_recent if this was the most recent item
73
+ const sortedHistory = newHistory.sort((a, b) => new Date(b.timestamp_start || 0).getTime() -
74
+ new Date(a.timestamp_start || 0).getTime());
75
+ updatedConnectivity[deviceId] = {
76
+ most_recent: sortedHistory[0],
77
+ history: sortedHistory,
78
+ };
65
79
  }
66
80
  }
67
81
  break;
68
82
  case "DELETE":
69
83
  if (updatedConnectivity[deviceId]) {
70
84
  // Filter creates a new array, so this is safe
71
- updatedConnectivity[deviceId] = updatedConnectivity[deviceId].filter((c) => c.id !== connectivityData.id);
72
- if (updatedConnectivity[deviceId].length === 0) {
85
+ const newHistory = updatedConnectivity[deviceId].history.filter((c) => c.id !== connectivityData.id);
86
+ if (newHistory.length === 0) {
73
87
  delete updatedConnectivity[deviceId];
74
88
  }
89
+ else {
90
+ const sortedHistory = newHistory.sort((a, b) => new Date(b.timestamp_start || 0).getTime() -
91
+ new Date(a.timestamp_start || 0).getTime());
92
+ updatedConnectivity[deviceId] = {
93
+ most_recent: sortedHistory[0],
94
+ history: sortedHistory,
95
+ };
96
+ }
75
97
  }
76
98
  break;
77
99
  }
@@ -80,7 +102,7 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
80
102
  }, [connectivity, dispatch]);
81
103
  // Fetch initial connectivity data
82
104
  const fetchInitialData = useCallback(async () => {
83
- if (!activeHerdId || !gpsDeviceIds)
105
+ if (!gpsDeviceIds)
84
106
  return;
85
107
  const deviceIds = gpsDeviceIds.split(",").filter(Boolean).map(Number);
86
108
  if (deviceIds.length === 0) {
@@ -95,10 +117,14 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
95
117
  if (response.status === EnumWebResponse.SUCCESS && response.data) {
96
118
  const trackerData = response.data.filter((conn) => !conn.session_id);
97
119
  if (trackerData.length > 0) {
98
- connectivityData[deviceId] = trackerData
120
+ const sortedData = trackerData
99
121
  .sort((a, b) => new Date(b.timestamp_start || 0).getTime() -
100
122
  new Date(a.timestamp_start || 0).getTime())
101
123
  .slice(0, 100);
124
+ connectivityData[deviceId] = {
125
+ most_recent: sortedData[0],
126
+ history: sortedData,
127
+ };
102
128
  }
103
129
  }
104
130
  else {
@@ -111,10 +137,11 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
111
137
  }));
112
138
  dispatch(setActiveHerdGpsTrackersConnectivity(connectivityData));
113
139
  console.log(`[Connectivity] Loaded data for ${Object.keys(connectivityData).length} devices`);
114
- }, [activeHerdId, gpsDeviceIds, dispatch]);
140
+ }, [gpsDeviceIds, dispatch]);
115
141
  useEffect(() => {
116
- if (!scoutSupabase || !gpsDeviceIds)
142
+ if (!scoutSupabase || gpsDeviceIds === "")
117
143
  return;
144
+ console.log(`[Connectivity Hook] Loading data for ${gpsDeviceIds}`);
118
145
  // Clean up existing channels
119
146
  channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
120
147
  channels.current = [];
@@ -137,5 +164,11 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
137
164
  channels.current.forEach((ch) => scoutSupabase.removeChannel(ch));
138
165
  channels.current = [];
139
166
  };
140
- }, [gpsDeviceIds]);
167
+ }, [
168
+ scoutSupabase,
169
+ gpsDeviceIds,
170
+ activeHerdId,
171
+ handleConnectivityBroadcast,
172
+ fetchInitialData,
173
+ ]);
141
174
  }
@@ -39,7 +39,7 @@ export function useScoutRealtimeDevices(scoutSupabase) {
39
39
  console.log(`[Devices] ✅ Connected to herd ${herdId}`);
40
40
  }
41
41
  else if (status === "CHANNEL_ERROR") {
42
- console.error(`[Devices] Failed to connect to herd ${herdId}`);
42
+ console.warn(`[Devices] 🟡 Failed to connect to herd ${herdId}`);
43
43
  }
44
44
  });
45
45
  };
@@ -1,4 +1,5 @@
1
+ import { HistoricalData } from "./historical";
1
2
  import { IConnectivityWithCoordinates } from "./db";
2
3
  export type MapDeviceIdToConnectivity = {
3
- [deviceId: number]: IConnectivityWithCoordinates[];
4
+ [deviceId: number]: HistoricalData<IConnectivityWithCoordinates>;
4
5
  };
@@ -0,0 +1,4 @@
1
+ export type HistoricalData<T> = {
2
+ most_recent: T;
3
+ history: T[];
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,4 @@
1
+ export type HistoricalData<T> = {
2
+ most_recent: T;
3
+ history: T[];
4
+ };
@@ -0,0 +1 @@
1
+ export {};
@@ -7,3 +7,4 @@ export * from "./supabase";
7
7
  export * from "./events";
8
8
  export * from "./data_source";
9
9
  export * from "./connectivity";
10
+ export * from "./historical";
@@ -7,3 +7,4 @@ export * from "./supabase";
7
7
  export * from "./events";
8
8
  export * from "./data_source";
9
9
  export * from "./connectivity";
10
+ export * from "./historical";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.0.97",
3
+ "version": "1.0.99",
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",