UNPKG

@adventurelabs/scout-core

Version:

Core utilities and helpers for Adventure Labs Scout applications

74 lines (73 loc) 2.99 kB
"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]; }