@adventurelabs/scout-core
Version:
Core utilities and helpers for Adventure Labs Scout applications
74 lines (73 loc) • 2.99 kB
JavaScript
"use client";
import { useSelector } from "react-redux";
import { useEffect, useRef, useCallback, useState } from "react";
import { EnumRealtimeOperation } from "../types/realtime";
export function useScoutRealtimePins(scoutSupabase) {
const channels = useRef([]);
const [latestPinUpdate, setLatestPinUpdate] = useState(null);
const activeHerdId = useSelector((state) => state.scout.active_herd_id);
// Pin broadcast handler - just pass data, don't mutate state
const handlePinBroadcast = useCallback((payload) => {
console.log("[Pins] Broadcast received:", payload.payload.operation);
const data = payload.payload;
const pinData = data.record || data.old_record;
if (!pinData)
return;
let operation;
switch (data.operation) {
case "INSERT":
operation = EnumRealtimeOperation.INSERT;
console.log("[Pins] New pin received:", data.record);
break;
case "UPDATE":
operation = EnumRealtimeOperation.UPDATE;
console.log("[Pins] Pin updated:", data.record);
break;
case "DELETE":
operation = EnumRealtimeOperation.DELETE;
console.log("[Pins] Pin deleted:", data.old_record);
break;
default:
return;
}
const realtimeData = {
data: pinData,
operation,
};
console.log(`[scout-core realtime] PIN ${data.operation} received for pin "${pinData.name}" (${pinData.id}):`, JSON.stringify(realtimeData));
setLatestPinUpdate(realtimeData);
}, []);
// Clear latest update
const clearLatestUpdate = useCallback(() => {
setLatestPinUpdate(null);
}, []);
const cleanupChannels = () => {
channels.current.forEach((channel) => scoutSupabase.removeChannel(channel));
channels.current = [];
};
const createPinsChannel = (herdId) => {
return scoutSupabase
.channel(`${herdId}-pins`, { config: { private: true } })
.on("broadcast", { event: "*" }, handlePinBroadcast)
.subscribe((status) => {
if (status === "SUBSCRIBED") {
console.log(`[Pins] ✅ Connected to herd ${herdId} pins broadcasts`);
}
else if (status === "CHANNEL_ERROR") {
console.warn(`[Pins] 🟡 Failed to connect to herd ${herdId} pins broadcasts`);
}
});
};
useEffect(() => {
cleanupChannels();
// Clear previous update when switching herds
clearLatestUpdate();
// Create pins channel for active herd
if (activeHerdId) {
const channel = createPinsChannel(activeHerdId);
channels.current.push(channel);
}
return cleanupChannels;
}, [activeHerdId, clearLatestUpdate]);
return [latestPinUpdate, clearLatestUpdate];
}