@adventurelabs/scout-core 1.1.1 → 1.2.2

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,4 @@
1
1
  import { IHerdModule } from "../types/herd_module";
2
- import { IVersionsSoftware } from "../types/db";
3
2
  export interface CacheMetadata {
4
3
  key: string;
5
4
  timestamp: number;
@@ -46,7 +45,6 @@ export declare class ScoutCache {
46
45
  getHerdModules(): Promise<CacheResult<IHerdModule[]>>;
47
46
  clearHerdModules(): Promise<void>;
48
47
  invalidateHerdModules(): Promise<void>;
49
- invalidateVersionsSoftware(): Promise<void>;
50
48
  getCacheStats(): Promise<CacheStats>;
51
49
  isCacheValid(ttlMs?: number): Promise<boolean>;
52
50
  getCacheAge(): Promise<number>;
@@ -60,8 +58,5 @@ export declare class ScoutCache {
60
58
  isCacheVersionCompatible(): Promise<boolean>;
61
59
  resetDatabase(): Promise<void>;
62
60
  checkDatabaseHealth(): Promise<DatabaseHealth>;
63
- setVersionsSoftware(versionsSoftware: IVersionsSoftware[], ttlMs?: number, etag?: string): Promise<void>;
64
- getVersionsSoftware(): Promise<CacheResult<IVersionsSoftware[]>>;
65
- clearVersionsSoftware(): Promise<void>;
66
61
  }
67
62
  export declare const scoutCache: ScoutCache;
@@ -1,11 +1,9 @@
1
1
  const DB_NAME = "ScoutCache";
2
- const DB_VERSION = 3; // Increment to invalidate old cache versions
3
- const CACHE_VERSION = "3.0.0"; // Cache metadata version string
2
+ const DB_VERSION = 4; // Increment to invalidate old cache versions
4
3
  const HERD_MODULES_STORE = "herd_modules";
5
4
  const CACHE_METADATA_STORE = "cache_metadata";
6
- const VERSIONS_SOFTWARE_STORE = "versions_software";
7
- // Default TTL: 24 hours (2 days)
8
- const DEFAULT_TTL_MS = 2 * 24 * 60 * 60 * 1000;
5
+ // Default TTL: 24 hours (1 day)
6
+ const DEFAULT_TTL_MS = 24 * 60 * 60 * 1000;
9
7
  export class ScoutCache {
10
8
  constructor() {
11
9
  this.db = null;
@@ -63,17 +61,6 @@ export class ScoutCache {
63
61
  keyPath: "key",
64
62
  });
65
63
  console.log("[ScoutCache] Created cache_metadata object store");
66
- // Create versions_software store
67
- const versionsSoftwareStore = db.createObjectStore(VERSIONS_SOFTWARE_STORE, {
68
- keyPath: "id",
69
- });
70
- versionsSoftwareStore.createIndex("system", "system", {
71
- unique: false,
72
- });
73
- versionsSoftwareStore.createIndex("timestamp", "timestamp", {
74
- unique: false,
75
- });
76
- console.log("[ScoutCache] Created versions_software object store");
77
64
  console.log(`[ScoutCache] Database schema upgrade to version ${DB_VERSION} completed`);
78
65
  }
79
66
  catch (error) {
@@ -92,17 +79,13 @@ export class ScoutCache {
92
79
  return false;
93
80
  const hasHerdModulesStore = this.db.objectStoreNames.contains(HERD_MODULES_STORE);
94
81
  const hasMetadataStore = this.db.objectStoreNames.contains(CACHE_METADATA_STORE);
95
- const hasVersionsSoftwareStore = this.db.objectStoreNames.contains(VERSIONS_SOFTWARE_STORE);
96
82
  if (!hasHerdModulesStore) {
97
83
  console.error("[ScoutCache] Missing herd_modules object store");
98
84
  }
99
85
  if (!hasMetadataStore) {
100
86
  console.error("[ScoutCache] Missing cache_metadata object store");
101
87
  }
102
- if (!hasVersionsSoftwareStore) {
103
- console.error("[ScoutCache] Missing versions_software object store");
104
- }
105
- return hasHerdModulesStore && hasMetadataStore && hasVersionsSoftwareStore;
88
+ return hasHerdModulesStore && hasMetadataStore;
106
89
  }
107
90
  async setHerdModules(herdModules, ttlMs = DEFAULT_TTL_MS, etag) {
108
91
  await this.init();
@@ -118,7 +101,7 @@ export class ScoutCache {
118
101
  const herdModulesStore = transaction.objectStore(HERD_MODULES_STORE);
119
102
  const metadataStore = transaction.objectStore(CACHE_METADATA_STORE);
120
103
  const timestamp = Date.now();
121
- const version = CACHE_VERSION;
104
+ const version = "2.0.0";
122
105
  // Store each herd module (contains all nested data - devices, events, zones, etc.)
123
106
  herdModules.forEach((herdModule) => {
124
107
  const cacheEntry = {
@@ -238,21 +221,6 @@ export class ScoutCache {
238
221
  metadataStore.delete("providers");
239
222
  });
240
223
  }
241
- async invalidateVersionsSoftware() {
242
- await this.init();
243
- if (!this.db)
244
- throw new Error("Database not initialized");
245
- if (!this.validateDatabaseSchema()) {
246
- throw new Error("Database schema validation failed - required object stores not found");
247
- }
248
- const transaction = this.db.transaction([CACHE_METADATA_STORE], "readwrite");
249
- return new Promise((resolve, reject) => {
250
- transaction.onerror = () => reject(transaction.error);
251
- transaction.oncomplete = () => resolve();
252
- const metadataStore = transaction.objectStore(CACHE_METADATA_STORE);
253
- metadataStore.delete("versions_software");
254
- });
255
- }
256
224
  async getCacheStats() {
257
225
  const result = await this.getHerdModules();
258
226
  const totalRequests = this.stats.hits + this.stats.misses;
@@ -397,135 +365,6 @@ export class ScoutCache {
397
365
  issues,
398
366
  };
399
367
  }
400
- async setVersionsSoftware(versionsSoftware, ttlMs = DEFAULT_TTL_MS, etag) {
401
- await this.init();
402
- if (!this.db)
403
- throw new Error("Database not initialized");
404
- if (!this.validateDatabaseSchema()) {
405
- throw new Error("Database schema validation failed - required object stores not found");
406
- }
407
- const transaction = this.db.transaction([VERSIONS_SOFTWARE_STORE, CACHE_METADATA_STORE], "readwrite");
408
- return new Promise((resolve, reject) => {
409
- transaction.onerror = () => reject(transaction.error);
410
- transaction.oncomplete = () => resolve();
411
- const versionsSoftwareStore = transaction.objectStore(VERSIONS_SOFTWARE_STORE);
412
- const metadataStore = transaction.objectStore(CACHE_METADATA_STORE);
413
- const timestamp = Date.now();
414
- const version = CACHE_VERSION;
415
- // Clear existing versions_software data first
416
- versionsSoftwareStore.clear();
417
- // Store each software version with timestamp
418
- versionsSoftware.forEach((version) => {
419
- const cacheEntry = {
420
- ...version,
421
- timestamp,
422
- dbVersion: DB_VERSION,
423
- };
424
- versionsSoftwareStore.put(cacheEntry);
425
- });
426
- // Store cache metadata
427
- const metadata = {
428
- key: "versions_software",
429
- timestamp,
430
- ttl: ttlMs,
431
- version,
432
- dbVersion: DB_VERSION,
433
- etag,
434
- lastModified: timestamp,
435
- };
436
- metadataStore.put(metadata);
437
- });
438
- }
439
- async getVersionsSoftware() {
440
- await this.init();
441
- if (!this.db)
442
- throw new Error("Database not initialized");
443
- if (!this.validateDatabaseSchema()) {
444
- throw new Error("Database schema validation failed - required object stores not found");
445
- }
446
- const transaction = this.db.transaction([VERSIONS_SOFTWARE_STORE, CACHE_METADATA_STORE], "readonly");
447
- return new Promise((resolve, reject) => {
448
- transaction.onerror = () => reject(transaction.error);
449
- const versionsSoftwareStore = transaction.objectStore(VERSIONS_SOFTWARE_STORE);
450
- const metadataStore = transaction.objectStore(CACHE_METADATA_STORE);
451
- // Get metadata first
452
- const metadataRequest = metadataStore.get("versions_software");
453
- metadataRequest.onsuccess = () => {
454
- const metadata = metadataRequest.result;
455
- const now = Date.now();
456
- if (!metadata) {
457
- this.stats.misses++;
458
- resolve({ data: null, isStale: true, age: 0, metadata: null });
459
- return;
460
- }
461
- // Check if cache is from an incompatible DB version
462
- if (!metadata.dbVersion || metadata.dbVersion !== DB_VERSION) {
463
- console.log(`[ScoutCache] Versions software cache from incompatible DB version (${metadata.dbVersion || "unknown"} !== ${DB_VERSION}), invalidating`);
464
- this.stats.misses++;
465
- resolve({ data: null, isStale: true, age: 0, metadata });
466
- return;
467
- }
468
- const age = now - metadata.timestamp;
469
- const isStale = age > metadata.ttl;
470
- if (isStale) {
471
- this.stats.misses++;
472
- console.log(`[ScoutCache] Versions software cache is stale (${Math.round(age / 1000)}s old, TTL: ${Math.round(metadata.ttl / 1000)}s)`);
473
- resolve({ data: null, isStale: true, age, metadata });
474
- return;
475
- }
476
- // Get all versions_software
477
- const getAllRequest = versionsSoftwareStore.getAll();
478
- getAllRequest.onsuccess = () => {
479
- const cacheEntries = getAllRequest.result;
480
- if (!cacheEntries || cacheEntries.length === 0) {
481
- this.stats.misses++;
482
- resolve({ data: null, isStale: false, age, metadata });
483
- return;
484
- }
485
- // Extract versions_software data and remove cache metadata
486
- const versionsSoftware = cacheEntries.map((entry) => {
487
- const { timestamp, dbVersion, ...versionData } = entry;
488
- return versionData;
489
- });
490
- this.stats.hits++;
491
- console.log(`[ScoutCache] Found ${versionsSoftware.length} cached software versions (${Math.round(age / 1000)}s old)`);
492
- resolve({
493
- data: versionsSoftware,
494
- isStale: false,
495
- age,
496
- metadata,
497
- });
498
- };
499
- getAllRequest.onerror = () => {
500
- this.stats.misses++;
501
- console.error("[ScoutCache] Failed to get versions software:", getAllRequest.error);
502
- resolve({ data: null, isStale: true, age, metadata });
503
- };
504
- };
505
- metadataRequest.onerror = () => {
506
- this.stats.misses++;
507
- console.error("[ScoutCache] Failed to get versions software metadata:", metadataRequest.error);
508
- resolve({ data: null, isStale: true, age: 0, metadata: null });
509
- };
510
- });
511
- }
512
- async clearVersionsSoftware() {
513
- await this.init();
514
- if (!this.db)
515
- throw new Error("Database not initialized");
516
- if (!this.validateDatabaseSchema()) {
517
- throw new Error("Database schema validation failed - required object stores not found");
518
- }
519
- const transaction = this.db.transaction([VERSIONS_SOFTWARE_STORE, CACHE_METADATA_STORE], "readwrite");
520
- return new Promise((resolve, reject) => {
521
- transaction.onerror = () => reject(transaction.error);
522
- transaction.oncomplete = () => resolve();
523
- const versionsSoftwareStore = transaction.objectStore(VERSIONS_SOFTWARE_STORE);
524
- const metadataStore = transaction.objectStore(CACHE_METADATA_STORE);
525
- versionsSoftwareStore.clear();
526
- metadataStore.delete("versions_software");
527
- });
528
- }
529
368
  }
530
369
  // Singleton instance
531
370
  export const scoutCache = new ScoutCache();
@@ -6,6 +6,5 @@ export declare function get_versions_software(client: SupabaseClient<Database>):
6
6
  export declare function get_versions_software_by_system(client: SupabaseClient<Database>, system: string): Promise<IWebResponseCompatible<IVersionsSoftware[]>>;
7
7
  export declare function create_version_software(client: SupabaseClient<Database>, newVersionSoftware: VersionsSoftwareInsert): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
8
8
  export declare function update_version_software(client: SupabaseClient<Database>, version_id: number, updatedVersionSoftware: Partial<VersionsSoftwareInsert>): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
9
- export declare function server_get_versions_software(): Promise<IWebResponseCompatible<IVersionsSoftware[]>>;
10
9
  export declare function delete_version_software(client: SupabaseClient<Database>, version_id: number): Promise<IWebResponseCompatible<IVersionsSoftware | null>>;
11
10
  export declare function get_versions_software_by_created_by(client: SupabaseClient<Database>, user_id: string): Promise<IWebResponseCompatible<IVersionsSoftware[]>>;
@@ -1,5 +1,4 @@
1
1
  import { IWebResponse } from "../types/requests";
2
- import { scoutCache } from "./cache";
3
2
  export async function get_versions_software(client) {
4
3
  const { data, error } = await client
5
4
  .from("versions_software")
@@ -39,14 +38,6 @@ export async function create_version_software(client, newVersionSoftware) {
39
38
  if (!data) {
40
39
  return IWebResponse.error("Failed to create software version").to_compatible();
41
40
  }
42
- // Invalidate cache after successful creation
43
- try {
44
- await scoutCache.invalidateVersionsSoftware();
45
- console.log("[VersionsSoftware] Cache invalidated after creation");
46
- }
47
- catch (cacheError) {
48
- console.warn("[VersionsSoftware] Failed to invalidate cache:", cacheError);
49
- }
50
41
  return IWebResponse.success(data).to_compatible();
51
42
  }
52
43
  export async function update_version_software(client, version_id, updatedVersionSoftware) {
@@ -67,47 +58,8 @@ export async function update_version_software(client, version_id, updatedVersion
67
58
  if (!data) {
68
59
  return IWebResponse.error("Software version not found or update failed").to_compatible();
69
60
  }
70
- // Invalidate cache after successful update
71
- try {
72
- await scoutCache.invalidateVersionsSoftware();
73
- console.log("[VersionsSoftware] Cache invalidated after update");
74
- }
75
- catch (cacheError) {
76
- console.warn("[VersionsSoftware] Failed to invalidate cache:", cacheError);
77
- }
78
61
  return IWebResponse.success(data).to_compatible();
79
62
  }
80
- export async function server_get_versions_software() {
81
- const { newServerClient } = await import("../supabase/server");
82
- const client = await newServerClient();
83
- try {
84
- // Try to get from cache first
85
- const cacheResult = await scoutCache.getVersionsSoftware();
86
- if (cacheResult.data && !cacheResult.isStale) {
87
- console.log(`[VersionsSoftware] Server using cached data (${Math.round(cacheResult.age / 1000)}s old)`);
88
- return IWebResponse.success(cacheResult.data).to_compatible();
89
- }
90
- // Cache miss or stale data - fetch from API
91
- console.log("[VersionsSoftware] Server cache miss or stale, fetching from API");
92
- const apiResponse = await get_versions_software(client);
93
- // If API request was successful, cache the result
94
- if (apiResponse.status === "success" && apiResponse.data) {
95
- try {
96
- await scoutCache.setVersionsSoftware(apiResponse.data);
97
- console.log(`[VersionsSoftware] Server cached ${apiResponse.data.length} software versions`);
98
- }
99
- catch (cacheError) {
100
- console.warn("[VersionsSoftware] Server failed to cache data:", cacheError);
101
- // Continue anyway, we still have the API data
102
- }
103
- }
104
- return apiResponse;
105
- }
106
- catch (cacheError) {
107
- console.warn("[VersionsSoftware] Server cache error, falling back to API:", cacheError);
108
- return get_versions_software(client);
109
- }
110
- }
111
63
  export async function delete_version_software(client, version_id) {
112
64
  const { data, error } = await client
113
65
  .from("versions_software")
@@ -121,14 +73,6 @@ export async function delete_version_software(client, version_id) {
121
73
  if (!data) {
122
74
  return IWebResponse.error("Software version not found or deletion failed").to_compatible();
123
75
  }
124
- // Invalidate cache after successful deletion
125
- try {
126
- await scoutCache.invalidateVersionsSoftware();
127
- console.log("[VersionsSoftware] Cache invalidated after deletion");
128
- }
129
- catch (cacheError) {
130
- console.warn("[VersionsSoftware] Failed to invalidate cache:", cacheError);
131
- }
132
76
  return IWebResponse.success(data).to_compatible();
133
77
  }
134
78
  export async function get_versions_software_by_created_by(client, user_id) {
@@ -2,3 +2,7 @@ export { useScoutRefresh, type UseScoutRefreshOptions, } from "./useScoutRefresh
2
2
  export { useScoutRealtimeConnectivity } from "./useScoutRealtimeConnectivity";
3
3
  export { useScoutRealtimeDevices } from "./useScoutRealtimeDevices";
4
4
  export { useScoutRealtimeVersionsSoftware } from "./useScoutRealtimeVersionsSoftware";
5
+ export { useScoutRealtimeEvents } from "./useScoutRealtimeEvents";
6
+ export { useScoutRealtimeTags } from "./useScoutRealtimeTags";
7
+ export { useScoutRealtimeSessions } from "./useScoutRealtimeSessions";
8
+ export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
@@ -2,3 +2,7 @@ export { useScoutRefresh, } from "./useScoutRefresh";
2
2
  export { useScoutRealtimeConnectivity } from "./useScoutRealtimeConnectivity";
3
3
  export { useScoutRealtimeDevices } from "./useScoutRealtimeDevices";
4
4
  export { useScoutRealtimeVersionsSoftware } from "./useScoutRealtimeVersionsSoftware";
5
+ export { useScoutRealtimeEvents } from "./useScoutRealtimeEvents";
6
+ export { useScoutRealtimeTags } from "./useScoutRealtimeTags";
7
+ export { useScoutRealtimeSessions } from "./useScoutRealtimeSessions";
8
+ export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
@@ -44,7 +44,7 @@ export function useScoutRealtimeConnectivity(scoutSupabase) {
44
44
  default:
45
45
  return;
46
46
  }
47
- console.log(`[CONNECTIVITY] ${data.operation} received for device ${connectivityData.device_id}:`, JSON.stringify(connectivityData));
47
+ console.log(`[scout-core realtime] CONNECTIVITY ${data.operation} received for device ${connectivityData.device_id}:`, JSON.stringify(connectivityData));
48
48
  const realtimeData = {
49
49
  data: connectivityData,
50
50
  operation,
@@ -28,14 +28,12 @@ export function useScoutRealtimeDevices(scoutSupabase) {
28
28
  case "UPDATE":
29
29
  operation = EnumRealtimeOperation.UPDATE;
30
30
  if (data.record) {
31
- console.log("[Devices] Device updated:", data.record);
32
31
  dispatch(updateDevice(data.record));
33
32
  }
34
33
  break;
35
34
  case "DELETE":
36
35
  operation = EnumRealtimeOperation.DELETE;
37
36
  if (data.old_record) {
38
- console.log("[Devices] Device deleted:", data.old_record);
39
37
  dispatch(deleteDevice(data.old_record));
40
38
  }
41
39
  break;
@@ -46,6 +44,7 @@ export function useScoutRealtimeDevices(scoutSupabase) {
46
44
  data: deviceData,
47
45
  operation,
48
46
  };
47
+ console.log(`[scout-core realtime] DEVICE ${data.operation} received:`, JSON.stringify(realtimeData));
49
48
  setNewDeviceItems((prev) => [realtimeData, ...prev]);
50
49
  }, [dispatch]);
51
50
  // Clear new items when herd changes
@@ -0,0 +1,5 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../types/supabase";
3
+ import { IEventAndTagsPrettyLocation } from "../types/db";
4
+ import { RealtimeData } from "../types/realtime";
5
+ export declare function useScoutRealtimeEvents(scoutSupabase: SupabaseClient<Database>, shouldUpdateGlobalStateOnChanges: boolean): RealtimeData<IEventAndTagsPrettyLocation>[];
@@ -0,0 +1,96 @@
1
+ "use client";
2
+ import { useAppDispatch } from "../store/hooks";
3
+ import { useSelector } from "react-redux";
4
+ import { useEffect, useRef, useCallback, useState } from "react";
5
+ import { updateEventValuesForHerdModule } from "../store/scout";
6
+ import { EnumRealtimeOperation } from "../types/realtime";
7
+ export function useScoutRealtimeEvents(scoutSupabase, shouldUpdateGlobalStateOnChanges) {
8
+ const channels = useRef([]);
9
+ const dispatch = useAppDispatch();
10
+ const [newEventItems, setNewEventItems] = useState([]);
11
+ const activeHerdId = useSelector((state) => state.scout.active_herd_id);
12
+ // Event broadcast handler
13
+ const handleEventBroadcast = useCallback((payload) => {
14
+ console.log("[Events] Broadcast received:", payload.payload.operation);
15
+ const data = payload.payload;
16
+ const eventData = data.record || data.old_record;
17
+ if (!eventData)
18
+ return;
19
+ let operation;
20
+ // TODO: UNCOMMENT GLOBAL STORE OPERATIONS IF OKAY WITH FREQUENT
21
+ switch (data.operation) {
22
+ case "INSERT":
23
+ operation = EnumRealtimeOperation.INSERT;
24
+ if (data.record && activeHerdId && shouldUpdateGlobalStateOnChanges) {
25
+ console.log("[Events] New event received:", data.record);
26
+ // For events, we need to update the event values in the herd module
27
+ dispatch(updateEventValuesForHerdModule({
28
+ herd_id: activeHerdId,
29
+ events: [data.record],
30
+ }));
31
+ }
32
+ break;
33
+ case "UPDATE":
34
+ operation = EnumRealtimeOperation.UPDATE;
35
+ if (data.record && activeHerdId && shouldUpdateGlobalStateOnChanges) {
36
+ console.log("[Events] Event updated:", data.record);
37
+ dispatch(updateEventValuesForHerdModule({
38
+ herd_id: activeHerdId,
39
+ events: [data.record],
40
+ }));
41
+ }
42
+ break;
43
+ case "DELETE":
44
+ operation = EnumRealtimeOperation.DELETE;
45
+ if (data.old_record &&
46
+ activeHerdId &&
47
+ shouldUpdateGlobalStateOnChanges) {
48
+ console.log("[Events] Event deleted:", data.old_record);
49
+ // TODO: WRITE DELETION STORE ACTION
50
+ console.log("[Events] Event deletion detected - manual refresh may be needed");
51
+ }
52
+ break;
53
+ default:
54
+ return;
55
+ }
56
+ const realtimeData = {
57
+ data: eventData,
58
+ operation,
59
+ };
60
+ console.log(`[scout-core realtime] EVENT ${data.operation} received:`, JSON.stringify(realtimeData));
61
+ setNewEventItems((prev) => [realtimeData, ...prev]);
62
+ }, [dispatch, activeHerdId]);
63
+ // Clear new items when herd changes
64
+ const clearNewItems = useCallback(() => {
65
+ setNewEventItems([]);
66
+ }, []);
67
+ const cleanupChannels = () => {
68
+ channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
69
+ channels.current = [];
70
+ };
71
+ const createEventsChannel = (herdId) => {
72
+ return scoutSupabase
73
+ .channel(`${herdId}-events`, { config: { private: true } })
74
+ .on("broadcast", { event: "*" }, handleEventBroadcast)
75
+ .subscribe((status) => {
76
+ if (status === "SUBSCRIBED") {
77
+ console.log(`[Events] ✅ Connected to herd ${herdId}`);
78
+ }
79
+ else if (status === "CHANNEL_ERROR") {
80
+ console.warn(`[Events] 🟡 Failed to connect to herd ${herdId}`);
81
+ }
82
+ });
83
+ };
84
+ useEffect(() => {
85
+ cleanupChannels();
86
+ // Clear previous items when switching herds
87
+ clearNewItems();
88
+ // Create events channel for active herd
89
+ if (activeHerdId) {
90
+ const channel = createEventsChannel(activeHerdId);
91
+ channels.current.push(channel);
92
+ }
93
+ return cleanupChannels;
94
+ }, [activeHerdId, clearNewItems]);
95
+ return newEventItems;
96
+ }
@@ -0,0 +1,5 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../types/supabase";
3
+ import { IPlan } from "../types/db";
4
+ import { RealtimeData } from "../types/realtime";
5
+ export declare function useScoutRealtimePlans(scoutSupabase: SupabaseClient<Database>, shouldUpdateGlobalStateOnChanges: boolean): RealtimeData<IPlan>[];
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { useAppDispatch } from "../store/hooks";
3
+ import { useSelector } from "react-redux";
4
+ import { useEffect, useRef, useCallback, useState } from "react";
5
+ import { addPlan, deletePlan, updatePlan } from "../store/scout";
6
+ import { EnumRealtimeOperation } from "../types/realtime";
7
+ export function useScoutRealtimePlans(scoutSupabase, shouldUpdateGlobalStateOnChanges) {
8
+ const channels = useRef([]);
9
+ const dispatch = useAppDispatch();
10
+ const [newPlanItems, setNewPlanItems] = useState([]);
11
+ const activeHerdId = useSelector((state) => state.scout.active_herd_id);
12
+ // Plan broadcast handler
13
+ const handlePlanBroadcast = useCallback((payload) => {
14
+ console.log("[Plans] Broadcast received:", payload.payload.operation);
15
+ const data = payload.payload;
16
+ const planData = data.record || data.old_record;
17
+ if (!planData)
18
+ return;
19
+ let operation;
20
+ switch (data.operation) {
21
+ case "INSERT":
22
+ operation = EnumRealtimeOperation.INSERT;
23
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
24
+ console.log("[Plans] New plan received:", data.record);
25
+ dispatch(addPlan(data.record));
26
+ }
27
+ break;
28
+ case "UPDATE":
29
+ operation = EnumRealtimeOperation.UPDATE;
30
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
31
+ dispatch(updatePlan(data.record));
32
+ }
33
+ break;
34
+ case "DELETE":
35
+ operation = EnumRealtimeOperation.DELETE;
36
+ if (data.old_record && shouldUpdateGlobalStateOnChanges) {
37
+ dispatch(deletePlan(data.old_record));
38
+ }
39
+ break;
40
+ default:
41
+ return;
42
+ }
43
+ const realtimeData = {
44
+ data: planData,
45
+ operation,
46
+ };
47
+ console.log(`[scout-core realtime] PLAN ${data.operation} received:`, JSON.stringify(realtimeData));
48
+ setNewPlanItems((prev) => [realtimeData, ...prev]);
49
+ }, [dispatch]);
50
+ // Clear new items when herd changes
51
+ const clearNewItems = useCallback(() => {
52
+ setNewPlanItems([]);
53
+ }, []);
54
+ const cleanupChannels = () => {
55
+ channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
56
+ channels.current = [];
57
+ };
58
+ const createPlansChannel = (herdId) => {
59
+ return scoutSupabase
60
+ .channel(`${herdId}-plans`, { config: { private: true } })
61
+ .on("broadcast", { event: "*" }, handlePlanBroadcast)
62
+ .subscribe((status) => {
63
+ if (status === "SUBSCRIBED") {
64
+ console.log(`[Plans] ✅ Connected to herd ${herdId}`);
65
+ }
66
+ else if (status === "CHANNEL_ERROR") {
67
+ console.warn(`[Plans] 🟡 Failed to connect to herd ${herdId}`);
68
+ }
69
+ });
70
+ };
71
+ useEffect(() => {
72
+ cleanupChannels();
73
+ // Clear previous items when switching herds
74
+ clearNewItems();
75
+ // Create plans channel for active herd
76
+ if (activeHerdId) {
77
+ const channel = createPlansChannel(activeHerdId);
78
+ channels.current.push(channel);
79
+ }
80
+ return cleanupChannels;
81
+ }, [activeHerdId, clearNewItems]);
82
+ return newPlanItems;
83
+ }
@@ -0,0 +1,5 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../types/supabase";
3
+ import { ISessionWithCoordinates } from "../types/db";
4
+ import { RealtimeData } from "../types/realtime";
5
+ export declare function useScoutRealtimeSessions(scoutSupabase: SupabaseClient<Database>, shouldUpdateGlobalStateOnChanges: boolean): RealtimeData<ISessionWithCoordinates>[];
@@ -0,0 +1,83 @@
1
+ "use client";
2
+ import { useAppDispatch } from "../store/hooks";
3
+ import { useSelector } from "react-redux";
4
+ import { useEffect, useRef, useCallback, useState } from "react";
5
+ import { addSessionToStore, deleteSessionFromStore, updateSessionInStore, } from "../store/scout";
6
+ import { EnumRealtimeOperation } from "../types/realtime";
7
+ export function useScoutRealtimeSessions(scoutSupabase, shouldUpdateGlobalStateOnChanges) {
8
+ const channels = useRef([]);
9
+ const dispatch = useAppDispatch();
10
+ const [newSessionItems, setNewSessionItems] = useState([]);
11
+ const activeHerdId = useSelector((state) => state.scout.active_herd_id);
12
+ // Session broadcast handler
13
+ const handleSessionBroadcast = useCallback((payload) => {
14
+ console.log("[Sessions] Broadcast received:", payload.payload.operation);
15
+ const data = payload.payload;
16
+ const sessionData = data.record || data.old_record;
17
+ if (!sessionData)
18
+ return;
19
+ let operation;
20
+ switch (data.operation) {
21
+ case "INSERT":
22
+ operation = EnumRealtimeOperation.INSERT;
23
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
24
+ console.log("[Sessions] New session received:", data.record);
25
+ dispatch(addSessionToStore(data.record));
26
+ }
27
+ break;
28
+ case "UPDATE":
29
+ operation = EnumRealtimeOperation.UPDATE;
30
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
31
+ dispatch(updateSessionInStore(data.record));
32
+ }
33
+ break;
34
+ case "DELETE":
35
+ operation = EnumRealtimeOperation.DELETE;
36
+ if (data.old_record && shouldUpdateGlobalStateOnChanges) {
37
+ dispatch(deleteSessionFromStore(data.old_record));
38
+ }
39
+ break;
40
+ default:
41
+ return;
42
+ }
43
+ const realtimeData = {
44
+ data: sessionData,
45
+ operation,
46
+ };
47
+ console.log(`[scout-core realtime] SESSION ${data.operation} received:`, JSON.stringify(realtimeData));
48
+ setNewSessionItems((prev) => [realtimeData, ...prev]);
49
+ }, [dispatch]);
50
+ // Clear new items when herd changes
51
+ const clearNewItems = useCallback(() => {
52
+ setNewSessionItems([]);
53
+ }, []);
54
+ const cleanupChannels = () => {
55
+ channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
56
+ channels.current = [];
57
+ };
58
+ const createSessionsChannel = (herdId) => {
59
+ return scoutSupabase
60
+ .channel(`${herdId}-sessions`, { config: { private: true } })
61
+ .on("broadcast", { event: "*" }, handleSessionBroadcast)
62
+ .subscribe((status) => {
63
+ if (status === "SUBSCRIBED") {
64
+ console.log(`[Sessions] ✅ Connected to herd ${herdId}`);
65
+ }
66
+ else if (status === "CHANNEL_ERROR") {
67
+ console.warn(`[Sessions] 🟡 Failed to connect to herd ${herdId}`);
68
+ }
69
+ });
70
+ };
71
+ useEffect(() => {
72
+ cleanupChannels();
73
+ // Clear previous items when switching herds
74
+ clearNewItems();
75
+ // Create sessions channel for active herd
76
+ if (activeHerdId) {
77
+ const channel = createSessionsChannel(activeHerdId);
78
+ channels.current.push(channel);
79
+ }
80
+ return cleanupChannels;
81
+ }, [activeHerdId, clearNewItems]);
82
+ return newSessionItems;
83
+ }
@@ -0,0 +1,5 @@
1
+ import { SupabaseClient } from "@supabase/supabase-js";
2
+ import { Database } from "../types/supabase";
3
+ import { ITagPrettyLocation } from "../types/db";
4
+ import { RealtimeData } from "../types/realtime";
5
+ export declare function useScoutRealtimeTags(scoutSupabase: SupabaseClient<Database>, shouldUpdateGlobalStateOnChanges: boolean): RealtimeData<ITagPrettyLocation>[];
@@ -0,0 +1,85 @@
1
+ "use client";
2
+ import { useAppDispatch } from "../store/hooks";
3
+ import { useSelector } from "react-redux";
4
+ import { useEffect, useRef, useCallback, useState } from "react";
5
+ import { addTag, deleteTag, updateTag } from "../store/scout";
6
+ import { EnumRealtimeOperation } from "../types/realtime";
7
+ export function useScoutRealtimeTags(scoutSupabase, shouldUpdateGlobalStateOnChanges) {
8
+ const channels = useRef([]);
9
+ const dispatch = useAppDispatch();
10
+ const [newTagItems, setNewTagItems] = useState([]);
11
+ const activeHerdId = useSelector((state) => state.scout.active_herd_id);
12
+ // Tag broadcast handler
13
+ const handleTagBroadcast = useCallback((payload) => {
14
+ console.log("[Tags] Broadcast received:", payload.payload.operation);
15
+ const data = payload.payload;
16
+ const tagData = data.record || data.old_record;
17
+ if (!tagData)
18
+ return;
19
+ let operation;
20
+ switch (data.operation) {
21
+ case "INSERT":
22
+ operation = EnumRealtimeOperation.INSERT;
23
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
24
+ console.log("[Tags] New tag received:", data.record);
25
+ dispatch(addTag(data.record));
26
+ }
27
+ break;
28
+ case "UPDATE":
29
+ operation = EnumRealtimeOperation.UPDATE;
30
+ if (data.record && shouldUpdateGlobalStateOnChanges) {
31
+ console.log("[Tags] Tag updated:", data.record);
32
+ dispatch(updateTag(data.record));
33
+ }
34
+ break;
35
+ case "DELETE":
36
+ operation = EnumRealtimeOperation.DELETE;
37
+ if (data.old_record && shouldUpdateGlobalStateOnChanges) {
38
+ console.log("[Tags] Tag deleted:", data.old_record);
39
+ dispatch(deleteTag(data.old_record));
40
+ }
41
+ break;
42
+ default:
43
+ return;
44
+ }
45
+ const realtimeData = {
46
+ data: tagData,
47
+ operation,
48
+ };
49
+ console.log(`[scout-core realtime] TAG ${data.operation} received:`, JSON.stringify(realtimeData));
50
+ setNewTagItems((prev) => [realtimeData, ...prev]);
51
+ }, [dispatch]);
52
+ // Clear new items when herd changes
53
+ const clearNewItems = useCallback(() => {
54
+ setNewTagItems([]);
55
+ }, []);
56
+ const cleanupChannels = () => {
57
+ channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
58
+ channels.current = [];
59
+ };
60
+ const createTagsChannel = (herdId) => {
61
+ return scoutSupabase
62
+ .channel(`${herdId}-tags`, { config: { private: true } })
63
+ .on("broadcast", { event: "*" }, handleTagBroadcast)
64
+ .subscribe((status) => {
65
+ if (status === "SUBSCRIBED") {
66
+ console.log(`[Tags] ✅ Connected to herd ${herdId}`);
67
+ }
68
+ else if (status === "CHANNEL_ERROR") {
69
+ console.warn(`[Tags] 🟡 Failed to connect to herd ${herdId}`);
70
+ }
71
+ });
72
+ };
73
+ useEffect(() => {
74
+ cleanupChannels();
75
+ // Clear previous items when switching herds
76
+ clearNewItems();
77
+ // Create tags channel for active herd
78
+ if (activeHerdId) {
79
+ const channel = createTagsChannel(activeHerdId);
80
+ channels.current.push(channel);
81
+ }
82
+ return cleanupChannels;
83
+ }, [activeHerdId, clearNewItems]);
84
+ return newTagItems;
85
+ }
@@ -1,52 +1,37 @@
1
1
  "use client";
2
- import { useAppDispatch } from "../store/hooks";
3
2
  import { useEffect, useRef, useCallback, useState } from "react";
4
- import { upsertVersionSoftware, deleteVersionSoftwareById, } from "../store/scout";
5
3
  import { EnumRealtimeOperation } from "../types/realtime";
6
4
  export function useScoutRealtimeVersionsSoftware(scoutSupabase) {
7
5
  const channels = useRef([]);
8
- const dispatch = useAppDispatch();
9
6
  const [newVersionsItems, setNewVersionsItems] = useState([]);
10
7
  // Handle versions software broadcasts
11
8
  const handleVersionsSoftwareBroadcast = useCallback((payload) => {
12
- console.log("[VersionsSoftware] Broadcast received:", payload.payload.operation);
13
- const data = payload.payload;
9
+ const { event, payload: data } = payload;
14
10
  const versionData = data.record || data.old_record;
15
- if (!versionData)
11
+ if (!versionData) {
16
12
  return;
13
+ }
17
14
  let operation;
18
15
  switch (data.operation) {
19
16
  case "INSERT":
20
17
  operation = EnumRealtimeOperation.INSERT;
21
- if (data.record) {
22
- console.log("[VersionsSoftware] New version received:", data.record);
23
- dispatch(upsertVersionSoftware(data.record));
24
- }
25
18
  break;
26
19
  case "UPDATE":
27
20
  operation = EnumRealtimeOperation.UPDATE;
28
- if (data.record) {
29
- console.log("[VersionsSoftware] Version updated:", data.record);
30
- dispatch(upsertVersionSoftware(data.record));
31
- }
32
21
  break;
33
22
  case "DELETE":
34
23
  operation = EnumRealtimeOperation.DELETE;
35
- if (data.old_record) {
36
- console.log("[VersionsSoftware] Version deleted:", data.old_record);
37
- dispatch(deleteVersionSoftwareById(data.old_record.id));
38
- }
39
24
  break;
40
25
  default:
41
26
  return;
42
27
  }
43
- console.log(`[VERSIONS_SOFTWARE] ${data.operation} received for version ${versionData.system}@${versionData.version}:`, JSON.stringify(versionData));
28
+ console.log(`[scout-core realtime] VERSIONS_SOFTWARE ${data.operation} received for version ${versionData.system}@${versionData.version}:`, JSON.stringify(versionData));
44
29
  const realtimeData = {
45
30
  data: versionData,
46
31
  operation,
47
32
  };
48
33
  setNewVersionsItems((prev) => [realtimeData, ...prev]);
49
- }, [dispatch]);
34
+ }, []);
50
35
  // Clear new items
51
36
  const clearNewItems = useCallback(() => {
52
37
  setNewVersionsItems([]);
@@ -1,10 +1,9 @@
1
1
  import { useEffect, useCallback, useRef, useMemo } from "react";
2
2
  import { useAppDispatch } from "../store/hooks";
3
3
  import { useStore } from "react-redux";
4
- import { EnumScoutStateStatus, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setUser, setDataSource, setDataSourceInfo, setVersionsSoftware, } from "../store/scout";
4
+ import { EnumScoutStateStatus, setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setUser, setDataSource, setDataSourceInfo, } from "../store/scout";
5
5
  import { EnumHerdModulesLoadingState } from "../types/herd_module";
6
6
  import { server_load_herd_modules } from "../helpers/herds";
7
- import { get_versions_software } from "../helpers/versions_software";
8
7
  import { scoutCache } from "../helpers/cache";
9
8
  import { EnumDataSource } from "../types/data_source";
10
9
  import { createBrowserClient } from "@supabase/ssr";
@@ -88,10 +87,7 @@ export function useScoutRefresh(options = {}) {
88
87
  if (cacheFirst) {
89
88
  const cacheStartTime = Date.now();
90
89
  try {
91
- const [cacheResult, versionsCacheResult] = await Promise.all([
92
- scoutCache.getHerdModules(),
93
- scoutCache.getVersionsSoftware(),
94
- ]);
90
+ const cacheResult = await scoutCache.getHerdModules();
95
91
  cacheLoadDuration = Date.now() - cacheStartTime;
96
92
  timingRefs.current.cacheLoadDuration = cacheLoadDuration;
97
93
  dispatch(setCacheLoadDuration(cacheLoadDuration));
@@ -110,19 +106,13 @@ export function useScoutRefresh(options = {}) {
110
106
  console.log(`[useScoutRefresh] Updating store with cached herd modules`);
111
107
  dispatch(setHerdModules(cachedHerdModules));
112
108
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
113
- // Load cached software versions immediately if available
114
- if (versionsCacheResult.data && !versionsCacheResult.isStale) {
115
- console.log(`[useScoutRefresh] Loaded ${versionsCacheResult.data.length} software versions from cache`);
116
- dispatch(setVersionsSoftware(versionsCacheResult.data));
117
- }
118
109
  // If cache is fresh, we still background fetch but don't wait
119
110
  if (!cacheResult.isStale) {
120
111
  // Background fetch fresh data without blocking
121
112
  (async () => {
122
113
  try {
123
- console.log("[useScoutRefresh] Starting background parallel API calls: herd modules, user, software versions");
124
114
  const backgroundStartTime = Date.now();
125
- const [backgroundHerdModulesResult, backgroundUserResult, backgroundVersionsResult,] = await Promise.all([
115
+ const [backgroundHerdModulesResult, backgroundUserResult] = await Promise.all([
126
116
  (async () => {
127
117
  const start = Date.now();
128
118
  const result = await server_load_herd_modules();
@@ -146,45 +136,25 @@ export function useScoutRefresh(options = {}) {
146
136
  dispatch(setUserApiDuration(duration));
147
137
  return { data: data.user, status: "success" };
148
138
  })(),
149
- (async () => {
150
- const start = Date.now();
151
- const result = await get_versions_software(supabase);
152
- const duration = Date.now() - start;
153
- return { ...result, duration };
154
- })(),
155
139
  ]);
156
140
  const backgroundDuration = Date.now() - backgroundStartTime;
157
- console.log(`[useScoutRefresh] Background parallel API calls completed in ${backgroundDuration}ms (herd modules, user, software versions)`);
158
141
  // Validate background responses
159
- if (backgroundHerdModulesResult.status === "success" &&
160
- backgroundHerdModulesResult.data &&
142
+ if (backgroundHerdModulesResult.data &&
161
143
  Array.isArray(backgroundHerdModulesResult.data) &&
162
144
  backgroundUserResult &&
163
145
  backgroundUserResult.data) {
164
- // Update cache with fresh herd modules data
146
+ // Update cache with fresh data
165
147
  try {
166
148
  await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs);
167
149
  }
168
150
  catch (cacheError) {
169
- console.warn("[useScoutRefresh] Background herd modules cache save failed:", cacheError);
151
+ console.warn("[useScoutRefresh] Background cache save failed:", cacheError);
170
152
  await handleIndexedDbError(cacheError, "background cache save", async () => {
171
153
  if (backgroundHerdModulesResult.data) {
172
154
  await scoutCache.setHerdModules(backgroundHerdModulesResult.data, cacheTtlMs);
173
155
  }
174
156
  });
175
157
  }
176
- // Update cache with fresh software versions separately
177
- if (backgroundVersionsResult &&
178
- backgroundVersionsResult.status === "success" &&
179
- backgroundVersionsResult.data) {
180
- try {
181
- await scoutCache.setVersionsSoftware(backgroundVersionsResult.data, cacheTtlMs);
182
- console.log(`[useScoutRefresh] Background cached ${backgroundVersionsResult.data.length} software versions`);
183
- }
184
- catch (versionsCacheError) {
185
- console.warn("[useScoutRefresh] Background software versions cache save failed:", versionsCacheError);
186
- }
187
- }
188
158
  // Update store with fresh data from background request
189
159
  console.log(`[useScoutRefresh] Updating store with background herd modules`);
190
160
  dispatch(setHerdModules(backgroundHerdModulesResult.data));
@@ -192,13 +162,6 @@ export function useScoutRefresh(options = {}) {
192
162
  console.log(`[useScoutRefresh] Updating store with background user data`);
193
163
  dispatch(setUser(backgroundUserResult.data));
194
164
  }
195
- // Update software versions if successful
196
- if (backgroundVersionsResult &&
197
- backgroundVersionsResult.status === "success" &&
198
- backgroundVersionsResult.data) {
199
- console.log(`[useScoutRefresh] Updating store with background software versions`);
200
- dispatch(setVersionsSoftware(backgroundVersionsResult.data));
201
- }
202
165
  // Update data source to DATABASE
203
166
  dispatch(setDataSource(EnumDataSource.DATABASE));
204
167
  dispatch(setDataSourceInfo({
@@ -230,10 +193,9 @@ export function useScoutRefresh(options = {}) {
230
193
  // Continue with API call
231
194
  }
232
195
  }
233
- // Step 2: Load fresh data from API (herd modules, user, and software versions in parallel)
234
- console.log("[useScoutRefresh] Starting parallel API calls: herd modules, user, software versions");
196
+ // Step 2: Load fresh data from API
235
197
  const parallelStartTime = Date.now();
236
- const [herdModulesResult, userResult, versionsResult] = await Promise.all([
198
+ const [herdModulesResult, userResult] = await Promise.all([
237
199
  (async () => {
238
200
  const start = Date.now();
239
201
  const result = await server_load_herd_modules();
@@ -251,19 +213,9 @@ export function useScoutRefresh(options = {}) {
251
213
  start,
252
214
  };
253
215
  })(),
254
- (async () => {
255
- const start = Date.now();
256
- const result = await get_versions_software(supabase);
257
- const duration = Date.now() - start;
258
- return {
259
- result,
260
- duration,
261
- start,
262
- };
263
- })(),
264
216
  ]);
265
217
  const parallelDuration = Date.now() - parallelStartTime;
266
- console.log(`[useScoutRefresh] Parallel API calls completed in ${parallelDuration}ms (herd modules, user, software versions)`);
218
+ console.log(`[useScoutRefresh] Parallel API requests completed in ${parallelDuration}ms`);
267
219
  // Extract results and timing
268
220
  const herdModulesResponse = herdModulesResult.result;
269
221
  const res_new_user = userResult.result;
@@ -305,23 +257,12 @@ export function useScoutRefresh(options = {}) {
305
257
  const cacheSaveStartTime = Date.now();
306
258
  try {
307
259
  await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
308
- // Cache software versions separately
309
- if (versionsResult.result.status === "success" &&
310
- versionsResult.result.data) {
311
- try {
312
- await scoutCache.setVersionsSoftware(versionsResult.result.data, cacheTtlMs);
313
- console.log(`[useScoutRefresh] Cached ${versionsResult.result.data.length} software versions`);
314
- }
315
- catch (versionsCacheError) {
316
- console.warn("[useScoutRefresh] Failed to cache software versions:", versionsCacheError);
317
- }
318
- }
319
260
  const cacheSaveDuration = Date.now() - cacheSaveStartTime;
320
261
  timingRefs.current.cacheSaveDuration = cacheSaveDuration;
321
262
  console.log(`[useScoutRefresh] Cache updated in ${cacheSaveDuration}ms with TTL: ${Math.round(cacheTtlMs / 1000)}s`);
322
263
  }
323
264
  catch (cacheError) {
324
- console.warn("[useScoutRefresh] Herd modules cache save failed:", cacheError);
265
+ console.warn("[useScoutRefresh] Cache save failed:", cacheError);
325
266
  await handleIndexedDbError(cacheError, "cache save", async () => {
326
267
  await scoutCache.setHerdModules(compatible_new_herd_modules, cacheTtlMs);
327
268
  });
@@ -333,12 +274,6 @@ export function useScoutRefresh(options = {}) {
333
274
  dispatch(setHerdModules(compatible_new_herd_modules));
334
275
  console.log(`[useScoutRefresh] Updating store with fresh user data`);
335
276
  dispatch(setUser(res_new_user.data));
336
- // Update software versions
337
- if (versionsResult.result.status === "success" &&
338
- versionsResult.result.data) {
339
- console.log(`[useScoutRefresh] Updating store with fresh software versions`);
340
- dispatch(setVersionsSoftware(versionsResult.result.data));
341
- }
342
277
  dispatch(setHerdModulesLoadingState(EnumHerdModulesLoadingState.SUCCESSFULLY_LOADED));
343
278
  const dataProcessingDuration = Date.now() - dataProcessingStartTime;
344
279
  timingRefs.current.dataProcessingDuration = dataProcessingDuration;
package/dist/index.d.ts CHANGED
@@ -41,6 +41,10 @@ export * from "./helpers/components";
41
41
  export * from "./hooks/useScoutRealtimeConnectivity";
42
42
  export * from "./hooks/useScoutRealtimeDevices";
43
43
  export * from "./hooks/useScoutRealtimeVersionsSoftware";
44
+ export * from "./hooks/useScoutRealtimeEvents";
45
+ export * from "./hooks/useScoutRealtimeTags";
46
+ export * from "./hooks/useScoutRealtimeSessions";
47
+ export * from "./hooks/useScoutRealtimePlans";
44
48
  export * from "./hooks/useScoutRefresh";
45
49
  export * from "./providers";
46
50
  export * from "./store/scout";
package/dist/index.js CHANGED
@@ -45,6 +45,10 @@ export * from "./helpers/components";
45
45
  export * from "./hooks/useScoutRealtimeConnectivity";
46
46
  export * from "./hooks/useScoutRealtimeDevices";
47
47
  export * from "./hooks/useScoutRealtimeVersionsSoftware";
48
+ export * from "./hooks/useScoutRealtimeEvents";
49
+ export * from "./hooks/useScoutRealtimeTags";
50
+ export * from "./hooks/useScoutRealtimeSessions";
51
+ export * from "./hooks/useScoutRealtimePlans";
48
52
  export * from "./hooks/useScoutRefresh";
49
53
  // Providers
50
54
  export * from "./providers";
@@ -1389,6 +1389,7 @@ export declare function useSupabase(): SupabaseClient<Database, "public", "publi
1389
1389
  frequency_hz: number | null;
1390
1390
  bandwidth_hz: number | null;
1391
1391
  associated_station: string | null;
1392
+ mode: string | null;
1392
1393
  };
1393
1394
  device_heartbeat_analysis: {
1394
1395
  device_id: number | null;
@@ -1,4 +1,4 @@
1
- import { IUser, IVersionsSoftware } from "../types/db";
1
+ import { IUser } from "../types/db";
2
2
  import { IHerdModule, EnumHerdModulesLoadingState } from "../types/herd_module";
3
3
  import { EnumDataSource, IDataSourceInfo } from "../types/data_source";
4
4
  import { MapDeviceIdToConnectivity } from "../types/connectivity";
@@ -23,7 +23,6 @@ export interface ScoutState {
23
23
  data_source: EnumDataSource;
24
24
  data_source_info: IDataSourceInfo | null;
25
25
  active_herd_gps_trackers_connectivity: MapDeviceIdToConnectivity;
26
- versions_software: IVersionsSoftware[];
27
26
  }
28
27
  export interface RootState {
29
28
  scout: ScoutState;
@@ -173,19 +172,7 @@ export declare const scoutSlice: import("@reduxjs/toolkit").Slice<ScoutState, {
173
172
  payload: any;
174
173
  type: string;
175
174
  }) => void;
176
- setVersionsSoftware: (state: import("immer").WritableDraft<ScoutState>, action: {
177
- payload: any;
178
- type: string;
179
- }) => void;
180
- upsertVersionSoftware: (state: import("immer").WritableDraft<ScoutState>, action: {
181
- payload: any;
182
- type: string;
183
- }) => void;
184
- deleteVersionSoftwareById: (state: import("immer").WritableDraft<ScoutState>, action: {
185
- payload: any;
186
- type: string;
187
- }) => void;
188
175
  }, "scout", "scout", import("@reduxjs/toolkit").SliceSelectors<ScoutState>>;
189
- export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiServerProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiServerProcessingDuration">, setHerdModulesApiTotalRequestDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiTotalRequestDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setCacheLoadDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setCacheLoadDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, setDataSource: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSource">, setDataSourceInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSourceInfo">, appendEventsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendEventsToHerdModule">, replaceEventsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceEventsForHerdModule">, appendArtifactsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendArtifactsToHerdModule">, replaceArtifactsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceArtifactsForHerdModule">, updateEventValuesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateEventValuesForHerdModule">, updatePageIndexForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePageIndexForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, addTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addTag">, deleteTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteTag">, updateTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateTag">, addNewDeviceToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addNewDeviceToHerdModule">, updateDeviceForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDeviceForHerdModule">, addDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addDevice">, deleteDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteDevice">, updateDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDevice">, addPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addPlan">, deletePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deletePlan">, updatePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePlan">, addSessionToStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addSessionToStore">, deleteSessionFromStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteSessionFromStore">, updateSessionInStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionInStore">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">, setVersionsSoftware: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setVersionsSoftware">, upsertVersionSoftware: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/upsertVersionSoftware">, deleteVersionSoftwareById: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteVersionSoftwareById">;
176
+ export declare const setHerdModules: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModules">, setStatus: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setStatus">, setHerdModulesLoadingState: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadingState">, setHerdModulesLoadedInMs: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesLoadedInMs">, setHerdModulesApiServerProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiServerProcessingDuration">, setHerdModulesApiTotalRequestDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setHerdModulesApiTotalRequestDuration">, setUserApiDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUserApiDuration">, setDataProcessingDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataProcessingDuration">, setCacheLoadDuration: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setCacheLoadDuration">, setActiveHerdId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdId">, setActiveDeviceId: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveDeviceId">, setDataSource: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSource">, setDataSourceInfo: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setDataSourceInfo">, appendEventsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendEventsToHerdModule">, replaceEventsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceEventsForHerdModule">, appendArtifactsToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendArtifactsToHerdModule">, replaceArtifactsForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/replaceArtifactsForHerdModule">, updateEventValuesForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateEventValuesForHerdModule">, updatePageIndexForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePageIndexForHerdModule">, appendPlansToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/appendPlansToHerdModule">, setUser: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setUser">, addTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addTag">, deleteTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteTag">, updateTag: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateTag">, addNewDeviceToHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addNewDeviceToHerdModule">, updateDeviceForHerdModule: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDeviceForHerdModule">, addDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addDevice">, deleteDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteDevice">, updateDevice: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateDevice">, addPlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addPlan">, deletePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deletePlan">, updatePlan: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updatePlan">, addSessionToStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/addSessionToStore">, deleteSessionFromStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/deleteSessionFromStore">, updateSessionInStore: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/updateSessionInStore">, setActiveHerdGpsTrackersConnectivity: import("@reduxjs/toolkit").ActionCreatorWithPayload<any, "scout/setActiveHerdGpsTrackersConnectivity">;
190
177
  declare const _default: import("redux").Reducer<ScoutState>;
191
178
  export default _default;
@@ -25,7 +25,6 @@ const initialState = {
25
25
  data_source: EnumDataSource.UNKNOWN,
26
26
  data_source_info: null,
27
27
  active_herd_gps_trackers_connectivity: {},
28
- versions_software: [],
29
28
  };
30
29
  export const scoutSlice = createSlice({
31
30
  name: "scout",
@@ -285,27 +284,8 @@ export const scoutSlice = createSlice({
285
284
  setActiveHerdGpsTrackersConnectivity: (state, action) => {
286
285
  state.active_herd_gps_trackers_connectivity = action.payload;
287
286
  },
288
- setVersionsSoftware: (state, action) => {
289
- state.versions_software = action.payload;
290
- },
291
- upsertVersionSoftware: (state, action) => {
292
- const version = action.payload;
293
- const existingIndex = state.versions_software.findIndex((v) => v.id === version.id);
294
- if (existingIndex !== -1) {
295
- // Update existing version
296
- state.versions_software[existingIndex] = version;
297
- }
298
- else {
299
- // Add new version
300
- state.versions_software = [version, ...state.versions_software];
301
- }
302
- },
303
- deleteVersionSoftwareById: (state, action) => {
304
- const versionId = action.payload;
305
- state.versions_software = state.versions_software.filter((version) => version.id !== versionId);
306
- },
307
287
  },
308
288
  });
309
289
  // Action creators are generated for each case reducer function
310
- export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setActiveHerdId, setActiveDeviceId, setDataSource, setDataSourceInfo, appendEventsToHerdModule, replaceEventsForHerdModule, appendArtifactsToHerdModule, replaceArtifactsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, setActiveHerdGpsTrackersConnectivity, setVersionsSoftware, upsertVersionSoftware, deleteVersionSoftwareById, } = scoutSlice.actions;
290
+ export const { setHerdModules, setStatus, setHerdModulesLoadingState, setHerdModulesLoadedInMs, setHerdModulesApiServerProcessingDuration, setHerdModulesApiTotalRequestDuration, setUserApiDuration, setDataProcessingDuration, setCacheLoadDuration, setActiveHerdId, setActiveDeviceId, setDataSource, setDataSourceInfo, appendEventsToHerdModule, replaceEventsForHerdModule, appendArtifactsToHerdModule, replaceArtifactsForHerdModule, updateEventValuesForHerdModule, updatePageIndexForHerdModule, appendPlansToHerdModule, setUser, addTag, deleteTag, updateTag, addNewDeviceToHerdModule, updateDeviceForHerdModule, addDevice, deleteDevice, updateDevice, addPlan, deletePlan, updatePlan, addSessionToStore, deleteSessionFromStore, updateSessionInStore, setActiveHerdGpsTrackersConnectivity, } = scoutSlice.actions;
311
291
  export default scoutSlice.reducer;
@@ -1441,6 +1441,7 @@ export type Database = {
1441
1441
  frequency_hz: number | null;
1442
1442
  bandwidth_hz: number | null;
1443
1443
  associated_station: string | null;
1444
+ mode: string | null;
1444
1445
  };
1445
1446
  device_heartbeat_analysis: {
1446
1447
  device_id: number | null;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adventurelabs/scout-core",
3
- "version": "1.1.1",
3
+ "version": "1.2.2",
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",