'use client'; import { useRefWithInit } from "./useRefWithInit.mjs"; import { useOnMount } from "./useOnMount.mjs"; const EMPTY = 0; export class Timeout { static create() { return new Timeout(); } currentId = EMPTY; /** * Executes `fn` after `delay`, clearing any previously scheduled call. */ start(delay, fn) { this.clear(); this.currentId = setTimeout(() => { this.currentId = EMPTY; fn(); }, delay); /* Node.js types are enabled in development */ } isStarted() { return this.currentId !== EMPTY; } clear = () => { if (this.currentId !== EMPTY) { clearTimeout(this.currentId); this.currentId = EMPTY; } }; disposeEffect = () => { return this.clear; }; } /** * A `setTimeout` with automatic cleanup and guard. */ export function useTimeout() { const timeout = useRefWithInit(Timeout.create).current; useOnMount(timeout.disposeEffect); return timeout; }