@adventurelabs/scout-core 1.4.1 → 1.4.3
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.
- package/dist/hooks/index.d.ts +1 -0
- package/dist/hooks/index.js +1 -0
- package/dist/hooks/useScoutRealtimeDevices.js +5 -15
- package/dist/hooks/useScoutRealtimeEvents.d.ts +1 -1
- package/dist/hooks/useScoutRealtimeEvents.js +6 -24
- package/dist/hooks/useScoutRealtimeParts.d.ts +5 -0
- package/dist/hooks/useScoutRealtimeParts.js +73 -0
- package/dist/hooks/useScoutRealtimePins.d.ts +1 -1
- package/dist/hooks/useScoutRealtimePins.js +6 -13
- package/dist/hooks/useScoutRealtimePlans.d.ts +1 -1
- package/dist/hooks/useScoutRealtimePlans.js +6 -16
- package/dist/hooks/useScoutRealtimeSessions.d.ts +1 -1
- package/dist/hooks/useScoutRealtimeSessions.js +7 -25
- package/dist/hooks/useScoutRealtimeTags.d.ts +1 -1
- package/dist/hooks/useScoutRealtimeTags.js +6 -21
- package/dist/index.d.ts +1 -0
- package/dist/index.js +1 -0
- package/package.json +1 -1
package/dist/hooks/index.d.ts
CHANGED
|
@@ -7,5 +7,6 @@ export { useScoutRealtimeTags } from "./useScoutRealtimeTags";
|
|
|
7
7
|
export { useScoutRealtimeSessions } from "./useScoutRealtimeSessions";
|
|
8
8
|
export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
|
|
9
9
|
export { useScoutRealtimePins } from "./useScoutRealtimePins";
|
|
10
|
+
export { useScoutRealtimeParts } from "./useScoutRealtimeParts";
|
|
10
11
|
export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useIntersectionObserver, } from "./useInfiniteQuery";
|
|
11
12
|
export { useLoadingPerformance, useSessionSummariesByHerd, useHasSessionSummaries, } from "../store/hooks";
|
package/dist/hooks/index.js
CHANGED
|
@@ -7,6 +7,7 @@ export { useScoutRealtimeTags } from "./useScoutRealtimeTags";
|
|
|
7
7
|
export { useScoutRealtimeSessions } from "./useScoutRealtimeSessions";
|
|
8
8
|
export { useScoutRealtimePlans } from "./useScoutRealtimePlans";
|
|
9
9
|
export { useScoutRealtimePins } from "./useScoutRealtimePins";
|
|
10
|
+
export { useScoutRealtimeParts } from "./useScoutRealtimeParts";
|
|
10
11
|
// RTK Query infinite scroll hooks
|
|
11
12
|
export { useInfiniteSessionsByHerd, useInfiniteSessionsByDevice, useInfiniteEventsByHerd, useInfiniteEventsByDevice, useInfiniteArtifactsByHerd, useInfiniteArtifactsByDevice, useIntersectionObserver, } from "./useInfiniteQuery";
|
|
12
13
|
// Session summaries and performance hooks
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useAppDispatch } from "../store/hooks";
|
|
3
2
|
import { useSelector } from "react-redux";
|
|
4
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
5
|
-
import { addDevice, deleteDevice, updateDevice } from "../store/scout";
|
|
6
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
7
5
|
export function useScoutRealtimeDevices(scoutSupabase) {
|
|
8
6
|
const channels = useRef([]);
|
|
9
|
-
const dispatch = useAppDispatch();
|
|
10
7
|
const [latestDeviceUpdate, setLatestDeviceUpdate] = useState(null);
|
|
11
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
12
|
-
// Device broadcast handler
|
|
9
|
+
// Device broadcast handler - just pass data, don't mutate state
|
|
13
10
|
const handleDeviceBroadcast = useCallback((payload) => {
|
|
14
11
|
console.log("[Devices] Broadcast received:", payload.payload.operation);
|
|
15
12
|
const data = payload.payload;
|
|
@@ -20,22 +17,15 @@ export function useScoutRealtimeDevices(scoutSupabase) {
|
|
|
20
17
|
switch (data.operation) {
|
|
21
18
|
case "INSERT":
|
|
22
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
23
|
-
|
|
24
|
-
console.log("[Devices] New device received:", data.record);
|
|
25
|
-
dispatch(addDevice(data.record));
|
|
26
|
-
}
|
|
20
|
+
console.log("[Devices] New device received:", data.record);
|
|
27
21
|
break;
|
|
28
22
|
case "UPDATE":
|
|
29
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
30
|
-
|
|
31
|
-
dispatch(updateDevice(data.record));
|
|
32
|
-
}
|
|
24
|
+
console.log("[Devices] Device updated:", data.record);
|
|
33
25
|
break;
|
|
34
26
|
case "DELETE":
|
|
35
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
36
|
-
|
|
37
|
-
dispatch(deleteDevice(data.old_record));
|
|
38
|
-
}
|
|
28
|
+
console.log("[Devices] Device deleted:", data.old_record);
|
|
39
29
|
break;
|
|
40
30
|
default:
|
|
41
31
|
return;
|
|
@@ -46,7 +36,7 @@ export function useScoutRealtimeDevices(scoutSupabase) {
|
|
|
46
36
|
};
|
|
47
37
|
console.log(`[scout-core realtime] DEVICE ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
48
38
|
setLatestDeviceUpdate(realtimeData);
|
|
49
|
-
}, [
|
|
39
|
+
}, []);
|
|
50
40
|
// Clear latest update
|
|
51
41
|
const clearLatestUpdate = useCallback(() => {
|
|
52
42
|
setLatestDeviceUpdate(null);
|
|
@@ -2,4 +2,4 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
3
|
import { IEventAndTagsPrettyLocation } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
|
-
export declare function useScoutRealtimeEvents(scoutSupabase: SupabaseClient<Database
|
|
5
|
+
export declare function useScoutRealtimeEvents(scoutSupabase: SupabaseClient<Database>): [RealtimeData<IEventAndTagsPrettyLocation> | null, () => void];
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useAppDispatch } from "../store/hooks";
|
|
3
2
|
import { useSelector } from "react-redux";
|
|
4
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
5
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
6
|
-
|
|
7
|
-
export function useScoutRealtimeEvents(scoutSupabase, invalidateRTKQuery = true) {
|
|
5
|
+
export function useScoutRealtimeEvents(scoutSupabase) {
|
|
8
6
|
const channels = useRef([]);
|
|
9
|
-
const dispatch = useAppDispatch();
|
|
10
7
|
const [latestEventUpdate, setLatestEventUpdate] = useState(null);
|
|
11
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
12
|
-
// Event broadcast handler
|
|
9
|
+
// Event broadcast handler - just pass data, don't mutate state
|
|
13
10
|
const handleEventBroadcast = useCallback((payload) => {
|
|
14
11
|
console.log("[Events] Broadcast received:", payload.payload.operation);
|
|
15
12
|
const data = payload.payload;
|
|
@@ -20,30 +17,15 @@ export function useScoutRealtimeEvents(scoutSupabase, invalidateRTKQuery = true)
|
|
|
20
17
|
switch (data.operation) {
|
|
21
18
|
case "INSERT":
|
|
22
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
23
|
-
|
|
24
|
-
console.log("[Events] New event received, invalidating RTK Query cache:", data.record);
|
|
25
|
-
// Invalidate all events queries to refetch fresh data
|
|
26
|
-
dispatch(scoutApi.util.invalidateTags(["Event"]));
|
|
27
|
-
}
|
|
20
|
+
console.log("[Events] New event received:", data.record);
|
|
28
21
|
break;
|
|
29
22
|
case "UPDATE":
|
|
30
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
31
|
-
|
|
32
|
-
console.log("[Events] Event updated, invalidating RTK Query cache:", data.record);
|
|
33
|
-
// Invalidate specific event and list queries
|
|
34
|
-
dispatch(scoutApi.util.invalidateTags([
|
|
35
|
-
{ type: "Event", id: data.record.id || "unknown" },
|
|
36
|
-
{ type: "Event", id: "LIST" },
|
|
37
|
-
]));
|
|
38
|
-
}
|
|
24
|
+
console.log("[Events] Event updated:", data.record);
|
|
39
25
|
break;
|
|
40
26
|
case "DELETE":
|
|
41
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
42
|
-
|
|
43
|
-
console.log("[Events] Event deleted, invalidating RTK Query cache:", data.old_record);
|
|
44
|
-
// Invalidate all events queries since item was deleted
|
|
45
|
-
dispatch(scoutApi.util.invalidateTags(["Event"]));
|
|
46
|
-
}
|
|
28
|
+
console.log("[Events] Event deleted:", data.old_record);
|
|
47
29
|
break;
|
|
48
30
|
default:
|
|
49
31
|
return;
|
|
@@ -54,7 +36,7 @@ export function useScoutRealtimeEvents(scoutSupabase, invalidateRTKQuery = true)
|
|
|
54
36
|
};
|
|
55
37
|
console.log(`[scout-core realtime] EVENT ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
56
38
|
setLatestEventUpdate(realtimeData);
|
|
57
|
-
}, [
|
|
39
|
+
}, []);
|
|
58
40
|
// Clear latest update
|
|
59
41
|
const clearLatestUpdate = useCallback(() => {
|
|
60
42
|
setLatestEventUpdate(null);
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { SupabaseClient } from "@supabase/supabase-js";
|
|
2
|
+
import { Database } from "../types/supabase";
|
|
3
|
+
import { IPart } from "../types/db";
|
|
4
|
+
import { RealtimeData } from "../types/realtime";
|
|
5
|
+
export declare function useScoutRealtimeParts(scoutSupabase: SupabaseClient<Database>): [RealtimeData<IPart> | null, () => void];
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
import { useSelector } from "react-redux";
|
|
3
|
+
import { useEffect, useRef, useCallback, useState } from "react";
|
|
4
|
+
import { EnumRealtimeOperation } from "../types/realtime";
|
|
5
|
+
export function useScoutRealtimeParts(scoutSupabase) {
|
|
6
|
+
const channels = useRef([]);
|
|
7
|
+
const [latestPartUpdate, setLatestPartUpdate] = useState(null);
|
|
8
|
+
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
9
|
+
// Part broadcast handler - just pass data, don't mutate state
|
|
10
|
+
const handlePartBroadcast = useCallback((payload) => {
|
|
11
|
+
console.log("[Parts] Broadcast received:", payload.payload.operation);
|
|
12
|
+
const data = payload.payload;
|
|
13
|
+
const partData = data.record || data.old_record;
|
|
14
|
+
if (!partData)
|
|
15
|
+
return;
|
|
16
|
+
let operation;
|
|
17
|
+
switch (data.operation) {
|
|
18
|
+
case "INSERT":
|
|
19
|
+
operation = EnumRealtimeOperation.INSERT;
|
|
20
|
+
console.log("[Parts] New part received:", data.record);
|
|
21
|
+
break;
|
|
22
|
+
case "UPDATE":
|
|
23
|
+
operation = EnumRealtimeOperation.UPDATE;
|
|
24
|
+
console.log("[Parts] Part updated:", data.record);
|
|
25
|
+
break;
|
|
26
|
+
case "DELETE":
|
|
27
|
+
operation = EnumRealtimeOperation.DELETE;
|
|
28
|
+
console.log("[Parts] Part deleted:", data.old_record);
|
|
29
|
+
break;
|
|
30
|
+
default:
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const realtimeData = {
|
|
34
|
+
data: partData,
|
|
35
|
+
operation,
|
|
36
|
+
};
|
|
37
|
+
console.log(`[scout-core realtime] PART ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
38
|
+
setLatestPartUpdate(realtimeData);
|
|
39
|
+
}, []);
|
|
40
|
+
// Clear latest update
|
|
41
|
+
const clearLatestUpdate = useCallback(() => {
|
|
42
|
+
setLatestPartUpdate(null);
|
|
43
|
+
}, []);
|
|
44
|
+
const cleanupChannels = () => {
|
|
45
|
+
channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
|
|
46
|
+
channels.current = [];
|
|
47
|
+
};
|
|
48
|
+
const createPartsChannel = (herdId) => {
|
|
49
|
+
return scoutSupabase
|
|
50
|
+
.channel(`${herdId}-parts`, { config: { private: true } })
|
|
51
|
+
.on("broadcast", { event: "*" }, handlePartBroadcast)
|
|
52
|
+
.subscribe((status) => {
|
|
53
|
+
if (status === "SUBSCRIBED") {
|
|
54
|
+
console.log(`[Parts] ✅ Connected to herd ${herdId}`);
|
|
55
|
+
}
|
|
56
|
+
else if (status === "CHANNEL_ERROR") {
|
|
57
|
+
console.warn(`[Parts] 🟡 Failed to connect to herd ${herdId}`);
|
|
58
|
+
}
|
|
59
|
+
});
|
|
60
|
+
};
|
|
61
|
+
useEffect(() => {
|
|
62
|
+
cleanupChannels();
|
|
63
|
+
// Clear previous update when switching herds
|
|
64
|
+
clearLatestUpdate();
|
|
65
|
+
// Create parts channel for active herd
|
|
66
|
+
if (activeHerdId) {
|
|
67
|
+
const channel = createPartsChannel(activeHerdId);
|
|
68
|
+
channels.current.push(channel);
|
|
69
|
+
}
|
|
70
|
+
return cleanupChannels;
|
|
71
|
+
}, [activeHerdId, clearLatestUpdate]);
|
|
72
|
+
return [latestPartUpdate, clearLatestUpdate];
|
|
73
|
+
}
|
|
@@ -2,4 +2,4 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
3
|
import { IPin } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
|
-
export declare function useScoutRealtimePins(scoutSupabase: SupabaseClient<Database
|
|
5
|
+
export declare function useScoutRealtimePins(scoutSupabase: SupabaseClient<Database>): [RealtimeData<IPin> | null, () => void];
|
|
@@ -2,11 +2,11 @@
|
|
|
2
2
|
import { useSelector } from "react-redux";
|
|
3
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
4
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
5
|
-
export function useScoutRealtimePins(scoutSupabase
|
|
5
|
+
export function useScoutRealtimePins(scoutSupabase) {
|
|
6
6
|
const channels = useRef([]);
|
|
7
7
|
const [latestPinUpdate, setLatestPinUpdate] = useState(null);
|
|
8
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
9
|
-
// Pin broadcast handler
|
|
9
|
+
// Pin broadcast handler - just pass data, don't mutate state
|
|
10
10
|
const handlePinBroadcast = useCallback((payload) => {
|
|
11
11
|
console.log("[Pins] Broadcast received:", payload.payload.operation);
|
|
12
12
|
const data = payload.payload;
|
|
@@ -17,22 +17,15 @@ export function useScoutRealtimePins(scoutSupabase, shouldUpdateGlobalStateOnCha
|
|
|
17
17
|
switch (data.operation) {
|
|
18
18
|
case "INSERT":
|
|
19
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
20
|
-
|
|
21
|
-
console.log("[Pins] New pin received:", data.record);
|
|
22
|
-
// TODO: dispatch(addPinToStore(data.record));
|
|
23
|
-
}
|
|
20
|
+
console.log("[Pins] New pin received:", data.record);
|
|
24
21
|
break;
|
|
25
22
|
case "UPDATE":
|
|
26
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
27
|
-
|
|
28
|
-
// TODO: dispatch(updatePinInStore(data.record));
|
|
29
|
-
}
|
|
24
|
+
console.log("[Pins] Pin updated:", data.record);
|
|
30
25
|
break;
|
|
31
26
|
case "DELETE":
|
|
32
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
33
|
-
|
|
34
|
-
// TODO: dispatch(deletePinFromStore(data.old_record));
|
|
35
|
-
}
|
|
28
|
+
console.log("[Pins] Pin deleted:", data.old_record);
|
|
36
29
|
break;
|
|
37
30
|
default:
|
|
38
31
|
return;
|
|
@@ -43,7 +36,7 @@ export function useScoutRealtimePins(scoutSupabase, shouldUpdateGlobalStateOnCha
|
|
|
43
36
|
};
|
|
44
37
|
console.log(`[scout-core realtime] PIN ${data.operation} received for pin "${pinData.name}" (${pinData.id}):`, JSON.stringify(realtimeData));
|
|
45
38
|
setLatestPinUpdate(realtimeData);
|
|
46
|
-
}, [
|
|
39
|
+
}, []);
|
|
47
40
|
// Clear latest update
|
|
48
41
|
const clearLatestUpdate = useCallback(() => {
|
|
49
42
|
setLatestPinUpdate(null);
|
|
@@ -2,4 +2,4 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
3
|
import { IPlan } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
|
-
export declare function useScoutRealtimePlans(scoutSupabase: SupabaseClient<Database
|
|
5
|
+
export declare function useScoutRealtimePlans(scoutSupabase: SupabaseClient<Database>): [RealtimeData<IPlan> | null, () => void];
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useAppDispatch } from "../store/hooks";
|
|
3
2
|
import { useSelector } from "react-redux";
|
|
4
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
5
|
-
import { addPlan, deletePlan, updatePlan } from "../store/scout";
|
|
6
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
7
|
-
export function useScoutRealtimePlans(scoutSupabase
|
|
5
|
+
export function useScoutRealtimePlans(scoutSupabase) {
|
|
8
6
|
const channels = useRef([]);
|
|
9
|
-
const dispatch = useAppDispatch();
|
|
10
7
|
const [latestPlanUpdate, setLatestPlanUpdate] = useState(null);
|
|
11
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
12
|
-
// Plan broadcast handler
|
|
9
|
+
// Plan broadcast handler - just pass data, don't mutate state
|
|
13
10
|
const handlePlanBroadcast = useCallback((payload) => {
|
|
14
11
|
console.log("[Plans] Broadcast received:", payload.payload.operation);
|
|
15
12
|
const data = payload.payload;
|
|
@@ -20,22 +17,15 @@ export function useScoutRealtimePlans(scoutSupabase, shouldUpdateGlobalStateOnCh
|
|
|
20
17
|
switch (data.operation) {
|
|
21
18
|
case "INSERT":
|
|
22
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
23
|
-
|
|
24
|
-
console.log("[Plans] New plan received:", data.record);
|
|
25
|
-
dispatch(addPlan(data.record));
|
|
26
|
-
}
|
|
20
|
+
console.log("[Plans] New plan received:", data.record);
|
|
27
21
|
break;
|
|
28
22
|
case "UPDATE":
|
|
29
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
30
|
-
|
|
31
|
-
dispatch(updatePlan(data.record));
|
|
32
|
-
}
|
|
24
|
+
console.log("[Plans] Plan updated:", data.record);
|
|
33
25
|
break;
|
|
34
26
|
case "DELETE":
|
|
35
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
36
|
-
|
|
37
|
-
dispatch(deletePlan(data.old_record));
|
|
38
|
-
}
|
|
28
|
+
console.log("[Plans] Plan deleted:", data.old_record);
|
|
39
29
|
break;
|
|
40
30
|
default:
|
|
41
31
|
return;
|
|
@@ -46,7 +36,7 @@ export function useScoutRealtimePlans(scoutSupabase, shouldUpdateGlobalStateOnCh
|
|
|
46
36
|
};
|
|
47
37
|
console.log(`[scout-core realtime] PLAN ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
48
38
|
setLatestPlanUpdate(realtimeData);
|
|
49
|
-
}, [
|
|
39
|
+
}, []);
|
|
50
40
|
// Clear latest update
|
|
51
41
|
const clearLatestUpdate = useCallback(() => {
|
|
52
42
|
setLatestPlanUpdate(null);
|
|
@@ -2,4 +2,4 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
3
|
import { ISessionWithCoordinates } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
|
-
export declare function useScoutRealtimeSessions(scoutSupabase: SupabaseClient<Database
|
|
5
|
+
export declare function useScoutRealtimeSessions(scoutSupabase: SupabaseClient<Database>): [RealtimeData<ISessionWithCoordinates> | null, () => void];
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
2
|
import { useSelector } from "react-redux";
|
|
3
|
-
import { useAppDispatch } from "../store/hooks";
|
|
4
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
5
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
6
|
-
|
|
7
|
-
export function useScoutRealtimeSessions(scoutSupabase, invalidateRTKQuery = true) {
|
|
5
|
+
export function useScoutRealtimeSessions(scoutSupabase) {
|
|
8
6
|
const channels = useRef([]);
|
|
9
|
-
const dispatch = useAppDispatch();
|
|
10
7
|
const [latestSessionUpdate, setLatestSessionUpdate] = useState(null);
|
|
11
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
12
|
-
// Session broadcast handler
|
|
9
|
+
// Session broadcast handler - just pass data, don't mutate state
|
|
13
10
|
const handleSessionBroadcast = useCallback((payload) => {
|
|
14
11
|
console.log("[Sessions] Broadcast received:", payload.payload.operation);
|
|
15
12
|
const data = payload.payload;
|
|
@@ -20,30 +17,15 @@ export function useScoutRealtimeSessions(scoutSupabase, invalidateRTKQuery = tru
|
|
|
20
17
|
switch (data.operation) {
|
|
21
18
|
case "INSERT":
|
|
22
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
23
|
-
|
|
24
|
-
console.log("[Sessions] New session received, invalidating RTK Query cache:", data.record);
|
|
25
|
-
// Invalidate all sessions queries to refetch fresh data
|
|
26
|
-
dispatch(scoutApi.util.invalidateTags(["Session"]));
|
|
27
|
-
}
|
|
20
|
+
console.log("[Sessions] New session received:", data.record);
|
|
28
21
|
break;
|
|
29
22
|
case "UPDATE":
|
|
30
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
31
|
-
|
|
32
|
-
console.log("[Sessions] Session updated, invalidating RTK Query cache:", data.record);
|
|
33
|
-
// Invalidate specific session and list queries
|
|
34
|
-
dispatch(scoutApi.util.invalidateTags([
|
|
35
|
-
{ type: "Session", id: data.record.id || "unknown" },
|
|
36
|
-
{ type: "Session", id: "LIST" },
|
|
37
|
-
]));
|
|
38
|
-
}
|
|
24
|
+
console.log("[Sessions] Session updated:", data.record);
|
|
39
25
|
break;
|
|
40
26
|
case "DELETE":
|
|
41
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
42
|
-
|
|
43
|
-
console.log("[Sessions] Session deleted, invalidating RTK Query cache:", data.old_record);
|
|
44
|
-
// Invalidate all sessions queries since item was deleted
|
|
45
|
-
dispatch(scoutApi.util.invalidateTags(["Session"]));
|
|
46
|
-
}
|
|
28
|
+
console.log("[Sessions] Session deleted:", data.old_record);
|
|
47
29
|
break;
|
|
48
30
|
default:
|
|
49
31
|
return;
|
|
@@ -54,7 +36,7 @@ export function useScoutRealtimeSessions(scoutSupabase, invalidateRTKQuery = tru
|
|
|
54
36
|
};
|
|
55
37
|
console.log(`[scout-core realtime] SESSION ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
56
38
|
setLatestSessionUpdate(realtimeData);
|
|
57
|
-
}, [
|
|
39
|
+
}, []);
|
|
58
40
|
// Clear latest update
|
|
59
41
|
const clearLatestUpdate = useCallback(() => {
|
|
60
42
|
setLatestSessionUpdate(null);
|
|
@@ -86,6 +68,6 @@ export function useScoutRealtimeSessions(scoutSupabase, invalidateRTKQuery = tru
|
|
|
86
68
|
channels.current.push(channel);
|
|
87
69
|
}
|
|
88
70
|
return cleanupChannels;
|
|
89
|
-
}, [activeHerdId, clearLatestUpdate
|
|
71
|
+
}, [activeHerdId, clearLatestUpdate]);
|
|
90
72
|
return [latestSessionUpdate, clearLatestUpdate];
|
|
91
73
|
}
|
|
@@ -2,4 +2,4 @@ import { SupabaseClient } from "@supabase/supabase-js";
|
|
|
2
2
|
import { Database } from "../types/supabase";
|
|
3
3
|
import { ITagPrettyLocation } from "../types/db";
|
|
4
4
|
import { RealtimeData } from "../types/realtime";
|
|
5
|
-
export declare function useScoutRealtimeTags(scoutSupabase: SupabaseClient<Database
|
|
5
|
+
export declare function useScoutRealtimeTags(scoutSupabase: SupabaseClient<Database>): [RealtimeData<ITagPrettyLocation> | null, () => void];
|
|
@@ -1,15 +1,12 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { useAppDispatch } from "../store/hooks";
|
|
3
2
|
import { useSelector } from "react-redux";
|
|
4
3
|
import { useEffect, useRef, useCallback, useState } from "react";
|
|
5
4
|
import { EnumRealtimeOperation } from "../types/realtime";
|
|
6
|
-
|
|
7
|
-
export function useScoutRealtimeTags(scoutSupabase, invalidateRTKQuery = true) {
|
|
5
|
+
export function useScoutRealtimeTags(scoutSupabase) {
|
|
8
6
|
const channels = useRef([]);
|
|
9
|
-
const dispatch = useAppDispatch();
|
|
10
7
|
const [latestTagUpdate, setLatestTagUpdate] = useState(null);
|
|
11
8
|
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
12
|
-
// Tag broadcast handler
|
|
9
|
+
// Tag broadcast handler - just pass data, don't mutate state
|
|
13
10
|
const handleTagBroadcast = useCallback((payload) => {
|
|
14
11
|
console.log("[Tags] Broadcast received:", payload.payload.operation);
|
|
15
12
|
const data = payload.payload;
|
|
@@ -20,27 +17,15 @@ export function useScoutRealtimeTags(scoutSupabase, invalidateRTKQuery = true) {
|
|
|
20
17
|
switch (data.operation) {
|
|
21
18
|
case "INSERT":
|
|
22
19
|
operation = EnumRealtimeOperation.INSERT;
|
|
23
|
-
|
|
24
|
-
console.log("[Tags] New tag received, invalidating RTK Query cache:", data.record);
|
|
25
|
-
// Tags are part of events, so invalidate events queries
|
|
26
|
-
dispatch(scoutApi.util.invalidateTags(["Event"]));
|
|
27
|
-
}
|
|
20
|
+
console.log("[Tags] New tag received:", data.record);
|
|
28
21
|
break;
|
|
29
22
|
case "UPDATE":
|
|
30
23
|
operation = EnumRealtimeOperation.UPDATE;
|
|
31
|
-
|
|
32
|
-
console.log("[Tags] Tag updated, invalidating RTK Query cache:", data.record);
|
|
33
|
-
// Invalidate events queries since tags are embedded in events
|
|
34
|
-
dispatch(scoutApi.util.invalidateTags(["Event"]));
|
|
35
|
-
}
|
|
24
|
+
console.log("[Tags] Tag updated:", data.record);
|
|
36
25
|
break;
|
|
37
26
|
case "DELETE":
|
|
38
27
|
operation = EnumRealtimeOperation.DELETE;
|
|
39
|
-
|
|
40
|
-
console.log("[Tags] Tag deleted, invalidating RTK Query cache:", data.old_record);
|
|
41
|
-
// Invalidate events queries since tags are embedded in events
|
|
42
|
-
dispatch(scoutApi.util.invalidateTags(["Event"]));
|
|
43
|
-
}
|
|
28
|
+
console.log("[Tags] Tag deleted:", data.old_record);
|
|
44
29
|
break;
|
|
45
30
|
default:
|
|
46
31
|
return;
|
|
@@ -51,7 +36,7 @@ export function useScoutRealtimeTags(scoutSupabase, invalidateRTKQuery = true) {
|
|
|
51
36
|
};
|
|
52
37
|
console.log(`[scout-core realtime] TAG ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
53
38
|
setLatestTagUpdate(realtimeData);
|
|
54
|
-
}, [
|
|
39
|
+
}, []);
|
|
55
40
|
// Clear latest update
|
|
56
41
|
const clearLatestUpdate = useCallback(() => {
|
|
57
42
|
setLatestTagUpdate(null);
|
package/dist/index.d.ts
CHANGED
|
@@ -45,6 +45,7 @@ export * from "./hooks/useScoutRealtimeVersionsSoftware";
|
|
|
45
45
|
export * from "./hooks/useScoutRealtimeEvents";
|
|
46
46
|
export * from "./hooks/useScoutRealtimeTags";
|
|
47
47
|
export * from "./hooks/useScoutRealtimeSessions";
|
|
48
|
+
export * from "./hooks/useScoutRealtimeParts";
|
|
48
49
|
export * from "./hooks/useScoutRealtimePlans";
|
|
49
50
|
export * from "./hooks/useScoutRealtimePins";
|
|
50
51
|
export * from "./hooks/useScoutRefresh";
|
package/dist/index.js
CHANGED
|
@@ -49,6 +49,7 @@ export * from "./hooks/useScoutRealtimeVersionsSoftware";
|
|
|
49
49
|
export * from "./hooks/useScoutRealtimeEvents";
|
|
50
50
|
export * from "./hooks/useScoutRealtimeTags";
|
|
51
51
|
export * from "./hooks/useScoutRealtimeSessions";
|
|
52
|
+
export * from "./hooks/useScoutRealtimeParts";
|
|
52
53
|
export * from "./hooks/useScoutRealtimePlans";
|
|
53
54
|
export * from "./hooks/useScoutRealtimePins";
|
|
54
55
|
export * from "./hooks/useScoutRefresh";
|