1import type { VNode } from "preact";2import {3 reloadAfterRuntimeStartupFailure,4 type RuntimeStartupFailure,5} from "../runtime/startup-recovery.ts";67/** Inputs for Lofi's explicit persistent-runtime recovery action. */8export interface RuntimeRecoveryProps {9 /** The startup failure to inspect, or `null` when the runtime opened. */10 readonly failure: RuntimeStartupFailure | null;11 /** Reload implementation; defaults to a full page reload. */12 readonly reload?: () => void;13}1415/**16 * Renders recovery only when another tab is running an incompatible broker version.17 *18 * @example19 * ```tsx20 * import { RuntimeRecovery } from "@nzip/lofi/preact";21 *22 * <RuntimeRecovery failure={startupFailure} />;23 * ```24 *25 * @param props The startup failure to inspect and an optional reload override.26 * @returns The recovery prompt, or `null` when no incompatible-broker failure is present.27 */28export function RuntimeRecovery({ failure, reload }: RuntimeRecoveryProps): VNode | null {29 if (failure?.code !== "broker-incompatible") return null;30 return (31 <div class="runtime-recovery" role="alert">32 <h4>Close other app tabs</h4>33 <p>{failure.message}</p>34 <p>This tab will not reload or retry automatically.</p>35 <button36 type="button"37 onClick={() => reloadAfterRuntimeStartupFailure(reload)}38 >39 Reload app40 </button>41 </div>42 );43}