feat: dealer flow, mirror portfolio (M21), options convexity, FINRA short interest, alert producers, vendor gate
CI / Test & Type-Check (push) Canceled after 0s
CI / Test & Type-Check (push) Canceled after 0s
Snapshot of in-progress module work across multiple slices: - Dealer Flow: dealerExposureEngine, dealerMapService, dealerMapExplain, dealerMapIntegrity, dealerMapReplay, dealerStudyEngine, hanStyleLevels - Mirror Portfolio (M21): fundRepository, captureIngest, mirrorAlertProducers, fund holdings strip, live book, position capture ingest - Options: BSM, NormalizedOptionSurface types, OptionsChainRouter, ConvexityGate, option legs panel - Alert producers: vixLevel, rotation, thesis, unlock, portfolioRisk, mirror (fund_capture, fund_13f, mirror_diff) - FINRA short interest adapter + queue integration - SEC company tickers adapter + ingest (symbol search index seed) - Vendor gate (rate-limit-first data plane, ADR-0009) - CUSIP registry, reverse 13F refresh, stock float service - LRU cache, portfolio backtest engine - Frontend: dealer-flow, funds, journal, lab, monitor, plan, portfolio, reports, screener, strategies, theses, guided-start, exits, more pages - Volume profile, workspace profile, visibility-aware poll - ADRs 0010 (mirror math not advice), 0011 (symbol search index) - VENDOR_INTEGRATIONS.md, END_USER_TEST.md - .gitignore: exclude DBs, .DS_Store, local config, agent scratch
This commit is contained in:
@@ -0,0 +1,56 @@
|
||||
"use client";
|
||||
|
||||
import { useEffect, useRef } from "react";
|
||||
|
||||
/**
|
||||
* Run `tick` on an interval, but pause while the document is hidden
|
||||
* (background Safari tab / phone locked). Resumes with an immediate tick
|
||||
* when the page becomes visible again.
|
||||
*/
|
||||
export function useVisibilityAwarePoll(
|
||||
tick: () => void | Promise<void>,
|
||||
intervalMs: number,
|
||||
enabled = true,
|
||||
): void {
|
||||
const tickRef = useRef(tick);
|
||||
tickRef.current = tick;
|
||||
|
||||
useEffect(() => {
|
||||
if (!enabled || intervalMs <= 0) return;
|
||||
|
||||
let id: ReturnType<typeof setInterval> | null = null;
|
||||
|
||||
const run = () => {
|
||||
void tickRef.current();
|
||||
};
|
||||
|
||||
const start = () => {
|
||||
if (id != null) return;
|
||||
id = setInterval(run, intervalMs);
|
||||
};
|
||||
|
||||
const stop = () => {
|
||||
if (id != null) {
|
||||
clearInterval(id);
|
||||
id = null;
|
||||
}
|
||||
};
|
||||
|
||||
const onVisibility = () => {
|
||||
if (document.hidden) {
|
||||
stop();
|
||||
} else {
|
||||
run();
|
||||
start();
|
||||
}
|
||||
};
|
||||
|
||||
if (!document.hidden) start();
|
||||
|
||||
document.addEventListener("visibilitychange", onVisibility);
|
||||
return () => {
|
||||
stop();
|
||||
document.removeEventListener("visibilitychange", onVisibility);
|
||||
};
|
||||
}, [intervalMs, enabled]);
|
||||
}
|
||||
Reference in New Issue
Block a user