// Returns a rune-wrapped boolean that mirrors the source getter, but only // flips to true after the source has been true for delayMs continuously. // Flips back to false immediately when the source becomes false. // // Used to suppress flash-of-skeleton on cache-hit navigation: skeletons // only render for loads that take longer than ~100ms. export function useDelayed( source: () => boolean, delayMs = 100 ): { readonly value: boolean } { let delayed = $state(false); let timeout: ReturnType | null = null; $effect(() => { const v = source(); if (timeout) { clearTimeout(timeout); timeout = null; } if (v) { timeout = setTimeout(() => { delayed = true; timeout = null; }, delayMs); } else { delayed = false; } return () => { if (timeout) { clearTimeout(timeout); timeout = null; } }; }); return { get value() { return delayed; } }; }