| 34 | const NO_ACTIVE_BUILDS_REFRESH_INTERVAL = 30_000; |
| 35 | |
| 36 | function useSafeSearchParams() { |
| 37 | // Have to wrap setSearchParams because React Router doesn't guarantee |
| 38 | // a stable reference for setSearchParams across renders. |
| 39 | const [searchParams, setSearchParams] = useSearchParams(); |
| 40 | const setterRef = useRef(setSearchParams); |
| 41 | useLayoutEffect(() => { |
| 42 | setterRef.current = setSearchParams; |
| 43 | }, [setSearchParams]); |
| 44 | const stableSetSearchParams = useCallback( |
| 45 | (...args: Parameters<typeof setSearchParams>) => setterRef.current(...args), |
| 46 | [], |
| 47 | ); |
| 48 | // Need this to return a tuple, not a plain array. Using "as const" |
| 49 | // would make it readonly and cause type mismatches at call sites. |
| 50 | return [searchParams, stableSetSearchParams] as ReturnType< |
| 51 | typeof useSearchParams |
| 52 | >; |
| 53 | } |
| 54 | |
| 55 | type BatchAction = "delete" | "update"; |
| 56 | |