@adventurelabs/scout-core 1.4.1 → 1.4.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.
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
|
|
@@ -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,113 @@
|
|
|
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 { EnumRealtimeOperation } from "../types/realtime";
|
|
6
|
+
export function useScoutRealtimeParts(scoutSupabase) {
|
|
7
|
+
const channels = useRef([]);
|
|
8
|
+
const dispatch = useAppDispatch();
|
|
9
|
+
const [latestPartUpdate, setLatestPartUpdate] = useState(null);
|
|
10
|
+
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
|
|
11
|
+
const herdModules = useSelector((state) => state.scout.herd_modules);
|
|
12
|
+
// Part broadcast handler
|
|
13
|
+
const handlePartBroadcast = useCallback((payload) => {
|
|
14
|
+
console.log("[Parts] Broadcast received:", payload.payload.operation);
|
|
15
|
+
const data = payload.payload;
|
|
16
|
+
const partData = data.record || data.old_record;
|
|
17
|
+
if (!partData)
|
|
18
|
+
return;
|
|
19
|
+
let operation;
|
|
20
|
+
// Find the target herd module and device
|
|
21
|
+
const herdModule = herdModules.find((hm) => hm.herd.id.toString() === activeHerdId);
|
|
22
|
+
if (!herdModule) {
|
|
23
|
+
console.warn("[Parts] No herd module found for active herd");
|
|
24
|
+
return;
|
|
25
|
+
}
|
|
26
|
+
const targetDevice = herdModule.devices.find((device) => device.id === partData.device_id);
|
|
27
|
+
if (!targetDevice) {
|
|
28
|
+
console.warn(`[Parts] No device found with ID: ${partData.device_id}`);
|
|
29
|
+
return;
|
|
30
|
+
}
|
|
31
|
+
// Ensure device has parts array
|
|
32
|
+
if (!targetDevice.parts) {
|
|
33
|
+
targetDevice.parts = [];
|
|
34
|
+
}
|
|
35
|
+
switch (data.operation) {
|
|
36
|
+
case "INSERT":
|
|
37
|
+
operation = EnumRealtimeOperation.INSERT;
|
|
38
|
+
if (data.record) {
|
|
39
|
+
console.log("[Parts] New part received:", data.record);
|
|
40
|
+
// Add part to device's parts array if not already present
|
|
41
|
+
const existingPartIndex = targetDevice.parts.findIndex((p) => p.id === data.record.id);
|
|
42
|
+
if (existingPartIndex === -1) {
|
|
43
|
+
targetDevice.parts.push(data.record);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
break;
|
|
47
|
+
case "UPDATE":
|
|
48
|
+
operation = EnumRealtimeOperation.UPDATE;
|
|
49
|
+
if (data.record) {
|
|
50
|
+
console.log("[Parts] Part updated:", data.record);
|
|
51
|
+
// Update existing part in device's parts array
|
|
52
|
+
const partIndex = targetDevice.parts.findIndex((p) => p.id === data.record.id);
|
|
53
|
+
if (partIndex !== -1) {
|
|
54
|
+
targetDevice.parts[partIndex] = data.record;
|
|
55
|
+
}
|
|
56
|
+
else {
|
|
57
|
+
// Part not found, add it
|
|
58
|
+
targetDevice.parts.push(data.record);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
break;
|
|
62
|
+
case "DELETE":
|
|
63
|
+
operation = EnumRealtimeOperation.DELETE;
|
|
64
|
+
if (data.old_record) {
|
|
65
|
+
console.log("[Parts] Part deleted:", data.old_record);
|
|
66
|
+
// Remove part from device's parts array
|
|
67
|
+
targetDevice.parts = targetDevice.parts.filter((p) => p.id !== data.old_record.id);
|
|
68
|
+
}
|
|
69
|
+
break;
|
|
70
|
+
default:
|
|
71
|
+
return;
|
|
72
|
+
}
|
|
73
|
+
const realtimeData = {
|
|
74
|
+
data: partData,
|
|
75
|
+
operation,
|
|
76
|
+
};
|
|
77
|
+
console.log(`[scout-core realtime] PART ${data.operation} received:`, JSON.stringify(realtimeData));
|
|
78
|
+
setLatestPartUpdate(realtimeData);
|
|
79
|
+
}, [dispatch, activeHerdId, herdModules]);
|
|
80
|
+
// Clear latest update
|
|
81
|
+
const clearLatestUpdate = useCallback(() => {
|
|
82
|
+
setLatestPartUpdate(null);
|
|
83
|
+
}, []);
|
|
84
|
+
const cleanupChannels = () => {
|
|
85
|
+
channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
|
|
86
|
+
channels.current = [];
|
|
87
|
+
};
|
|
88
|
+
const createPartsChannel = (herdId) => {
|
|
89
|
+
return scoutSupabase
|
|
90
|
+
.channel(`${herdId}-parts`, { config: { private: true } })
|
|
91
|
+
.on("broadcast", { event: "*" }, handlePartBroadcast)
|
|
92
|
+
.subscribe((status) => {
|
|
93
|
+
if (status === "SUBSCRIBED") {
|
|
94
|
+
console.log(`[Parts] ✅ Connected to herd ${herdId}`);
|
|
95
|
+
}
|
|
96
|
+
else if (status === "CHANNEL_ERROR") {
|
|
97
|
+
console.warn(`[Parts] 🟡 Failed to connect to herd ${herdId}`);
|
|
98
|
+
}
|
|
99
|
+
});
|
|
100
|
+
};
|
|
101
|
+
useEffect(() => {
|
|
102
|
+
cleanupChannels();
|
|
103
|
+
// Clear previous update when switching herds
|
|
104
|
+
clearLatestUpdate();
|
|
105
|
+
// Create parts channel for active herd
|
|
106
|
+
if (activeHerdId) {
|
|
107
|
+
const channel = createPartsChannel(activeHerdId);
|
|
108
|
+
channels.current.push(channel);
|
|
109
|
+
}
|
|
110
|
+
return cleanupChannels;
|
|
111
|
+
}, [activeHerdId, clearLatestUpdate]);
|
|
112
|
+
return [latestPartUpdate, clearLatestUpdate];
|
|
113
|
+
}
|
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";
|