mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
0b167cc478
Bundle-weight optimization of @plannotator/ui for multi-chunk hosts, requested by Workspaces: the Mermaid runtime and Graphviz engine load inside the render effect, the username dictionary sits behind a synchronous identity generator slot, and KaTeX sits behind a math renderer slot with a loader seam on configurePlannotatorUI. Plannotator's own apps import eager entries (math, identity, and Mermaid for the plan editor) so their behavior is unchanged: single-file builds within noise of main, math typeset on first paint, identities from the full dictionary, and the share portal keeps Mermaid in its entry chunk so its failure surface matches main. Built-HTML registration markers guard the eager imports. Hosts that omit the eager entries get the lazy paths, a one-shot automatic re-attempt, and a Retry affordance on the diagram error panel; the module-map limitation of in-page retries is documented. AI-assisted (Claude) under maintainer direction.
31 lines
1.0 KiB
TypeScript
31 lines
1.0 KiB
TypeScript
import { useEffect, useSyncExternalStore } from 'react';
|
|
import {
|
|
getMathRenderer,
|
|
loadMathRenderer,
|
|
subscribeMathRenderer,
|
|
type MathRenderer,
|
|
} from '../utils/math';
|
|
|
|
/**
|
|
* The registered math renderer, read synchronously during render.
|
|
*
|
|
* With the slot filled before mount (Plannotator: `utils/math-eager`) this
|
|
* returns KaTeX on the first render and the effect below is a no-op, so the
|
|
* typeset HTML is in the first commit. With the slot empty it returns `null`,
|
|
* kicks off `loadMathRenderer()` from an effect, and the subscription
|
|
* re-renders the caller once the renderer lands. A rejected load is left to
|
|
* the loader's retry contract; the caller keeps showing the TeX placeholder.
|
|
*/
|
|
export function useMathRenderer(): MathRenderer | null {
|
|
const renderer = useSyncExternalStore(subscribeMathRenderer, getMathRenderer, getMathRenderer);
|
|
|
|
useEffect(() => {
|
|
if (renderer) return;
|
|
loadMathRenderer().catch(() => {
|
|
/* placeholder stays; the next mount retries */
|
|
});
|
|
}, [renderer]);
|
|
|
|
return renderer;
|
|
}
|