"use client"; import React from "react"; import { useAppDispatch } from "@/redux/store"; import { setEvents, initPersistedTimings, } from "@/redux/slices/deviceEventsSlice"; declare global { interface Window { loopMeasurementEvent?: number[]; tdrMeasurementEvent?: number[]; comparisonEvent?: number[]; // renamed from alignmentEvent } } const POLL_MS = 2000; // poll every 2 seconds export default function DeviceEventsBridge() { const dispatch = useAppDispatch(); React.useEffect(() => { let lastSig = ""; // Hydrate persisted timings once try { const raw = typeof window !== "undefined" && localStorage.getItem("deviceEventsTimingsV1"); if (raw) { const parsed = JSON.parse(raw); dispatch( initPersistedTimings({ loop: parsed.loop, tdr: parsed.tdr, compare: parsed.compare || parsed.align, }) ); } } catch (e) { // eslint-disable-next-line no-console console.warn("DeviceEventsBridge hydration failed", e); } const readAndDispatch = () => { const ksx = Array.isArray(window.loopMeasurementEvent) ? window.loopMeasurementEvent : undefined; const ksy = Array.isArray(window.tdrMeasurementEvent) ? window.tdrMeasurementEvent : undefined; const ksz = Array.isArray(window.comparisonEvent) ? window.comparisonEvent : undefined; // Build a stable signature of first 32 values per array const to32 = (a?: number[]) => { const out: number[] = []; if (Array.isArray(a)) { for (let i = 0; i < 32; i++) out.push(a[i] ? 1 : 0); } else { for (let i = 0; i < 32; i++) out.push(0); } return out; }; const sig = `${to32(ksx).join("")}|${to32(ksy).join("")}|${to32(ksz).join( "" )}`; if (sig !== lastSig) { lastSig = sig; dispatch(setEvents({ ksx, ksy, ksz })); } }; readAndDispatch(); const id = setInterval(readAndDispatch, POLL_MS); return () => clearInterval(id); }, [dispatch]); return null; }