1/**2 * Preact binding for first-load progress: the phases between a painted shell3 * and an open runtime, for status UI that names the engine download a cold4 * first visit actually waits on.5 *6 * @module7 */89import { useEffect, useState } from "preact/hooks";10import {11 type BootProgress,12 getBootProgress,13 subscribeBootProgress,14} from "../runtime/boot-progress.ts";1516export type { BootProgress, BootProgressPhase } from "../runtime/boot-progress.ts";1718/**19 * Subscribes a Preact component to first-load progress, so a loading state can20 * distinguish the engine download (with byte progress on a cold first visit)21 * from opening persistent storage.22 *23 * @example24 * ```tsx25 * import { useBootProgress } from "@nzip/lofi/preact";26 *27 * const boot = useBootProgress();28 * if (boot.phase === "downloading" && boot.totalBytes) {29 * const percent = Math.round((boot.loadedBytes / boot.totalBytes) * 100);30 * return <p>Downloading the app ยท {percent}%</p>;31 * }32 * ```33 *34 * @returns The current first-load progress, kept live via subscription.35 */36export function useBootProgress(): BootProgress {37 const [progress, setProgress] = useState<BootProgress>(getBootProgress());38 useEffect(() => subscribeBootProgress(setProgress), []);39 return progress;40}