import { Component, type ErrorInfo, type ReactNode, } from "react"; import { useLocale } from "../i18n/index.js"; type RecoveryResult = | Readonly<{ action: "reload-once"; releasePair: string }> | Readonly<{ action: "support"; reason: string }>; type Props = Readonly<{ children: ReactNode; chunkId: string; recover(input: Readonly<{ chunkId: string; failureKind: "CHUNK_LOAD_FAILURE"; }>): Promise; }>; type State = Readonly<{ error: unknown | null; recovery: "idle" | "checking" | "reload-requested" | "support"; reason?: string; }>; export function isChunkLoadFailure(error: unknown): boolean { if (!(error instanceof Error)) return false; const value = `${error.name} ${error.message}`.toLowerCase(); return ( value.includes("chunkloaderror") || value.includes("loading chunk") || value.includes("dynamically imported module") || value.includes("failed to fetch module script") ); } export class ChunkRecoveryBoundary extends Component { state: State = { error: null, recovery: "idle" }; static getDerivedStateFromError(error: unknown): State { return { error, recovery: "checking" }; } componentDidCatch(error: unknown, _info: ErrorInfo) { if (!isChunkLoadFailure(error)) return; void this.props .recover({ chunkId: this.props.chunkId, failureKind: "CHUNK_LOAD_FAILURE", }) .then((result) => { this.setState({ error, recovery: result.action === "reload-once" ? "reload-requested" : "support", ...(result.action === "support" ? { reason: result.reason } : {}), }); }) .catch(() => { this.setState({ error, recovery: "support", reason: "recovery-controller-failed", }); }); } render() { const { error, recovery, reason } = this.state; if (error && !isChunkLoadFailure(error)) throw error; if (error && recovery === "checking") { return ; } if (error && recovery === "reload-requested") { return ; } if (error && recovery === "support") { return ; } return this.props.children; } } function ChunkRecoverySurface({ recovery, reason, }: Readonly<{ recovery: Exclude; reason?: string; }>) { const { message } = useLocale(); if (recovery === "checking") { return (
{message("chunk.checking")}
); } if (recovery === "reload-requested") { return (
{message("chunk.reloadOnce")}
); } return (

{message("chunk.failure.title")}

{message("chunk.failure.description")}

); }