UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

137 lines 7.61 kB
import type { Root as HastRoot } from 'hast'; /** * Compact serialization format for fallback HAST trees. * * A `FallbackNode` is either: * - a plain string (text node), or * - a variable-length tuple whose meaning is determined by length: * - `[tagName, children]` – no class, no props * - `[tagName, className, children]` – has class, no props * - `[tagName, className, properties, children]` – has class and props * - `[tagName, className, properties, children, extra]` – full * * Where: * - `tagName` – HTML element name (e.g. `'span'`, `'a'`) * - `className` – space-joined class string * - `properties` – remaining HTML properties (without `className`) * - `children` – a single text string **or** an array of child `FallbackNode`s * - `extra` – optional bag for anything else (data attributes, etc.) * * This eliminates the repeated `type`, `tagName`, `properties`, `children`, * and `value` keys that make raw HAST costly in RSC payloads. */ export type FallbackNode = string | FallbackElement; /** * A residual fallback that has been DEFLATE-compressed on its own. Mirrors the * `{ hastCompressed }` shape of `VariantSource`. * * Used for the parts of a variant's fallback that the `ContentLoading` * component never renders (extra files when the loading UI shows a single file, * extra variants when it shows a single variant). Those residual fallbacks * exist only as the DEFLATE dictionary for decompressing `hastCompressed`, so * shipping them as plain `FallbackNode[]` text would be dead weight in the * initial payload. They are compressed standalone — no preset text dictionary, * so the blob is self-contained — and decompressed back to `FallbackNode[]` * (via `decompressFallback`) only when the full content swaps in. */ export type CompressedFallback = { fallbackCompressed: string; }; export type FallbackElement = [tagName: string, children: string | FallbackNode[]] | [tagName: string, className: string, children: string | FallbackNode[]] | [tagName: string, className: string, properties: Record<string, unknown>, children: string | FallbackNode[]] | [tagName: string, className: string, properties: Record<string, unknown>, children: string | FallbackNode[], extra: Record<string, unknown>]; /** * Convert a HAST root into the compact `FallbackNode[]` format. */ export declare function hastToFallback(root: HastRoot): FallbackNode[]; /** * Convert the compact `FallbackNode[]` format back into a HAST root. */ export declare function fallbackToHast(nodes: FallbackNode[]): HastRoot; /** * Extract the text content from compact `FallbackNode[]` without * converting back to HAST. Used to build DEFLATE dictionaries. */ export declare function fallbackToText(nodes: FallbackNode[]): string; /** * Builds the variant-level root fallback from a final (post-enhancer) HAST * root. Each `span.frame` becomes a compact frame element whose single text * child is the frame's precomputed plain text (`frame.data.fallback`), so the * result is directly renderable as the pre-hydration code block **and** can be * redistributed back onto the decoded HAST's frames (see * `redistributeRootFallback`). * * The frame's `data-lined` attribute is dropped (line spans don't exist in the * fallback) while other frame attributes (e.g. `data-frame-type`) are kept so * the fallback's layout matches the highlighted render. Non-frame top-level * nodes (e.g. whitespace text between frames) are preserved in place. */ export declare function buildRootFallback(root: HastRoot): FallbackNode[]; /** * Whether a compact `fallback` already carries highlighting — i.e. at least one frame * keeps nested token spans (array children) instead of flat plain text. True exactly for * the promoted {@link promoteCriticalFallback} form; a plain {@link buildRootFallback} has * a string child on every frame. `<Pre>` uses this to defer the decompressing decode ONLY * when the first paint is already highlighted, so it never flashes plain → highlighted. */ export declare function fallbackIsHighlighted(fallback: FallbackNode[]): boolean; /** * The **sparse** highlighted-visible fallback: a map from frame index to the * highlighted `FallbackNode` for ONLY the frames visible on the initial collapsed * render (`visibleFrames`). Off-screen frames are omitted — they flatten to exactly * {@link buildRootFallback}'s plain output, so storing them would just duplicate * `fallback` in the precompute. {@link promoteCriticalFallback} splices these back * over the plain fallback for `highlightAt: 'init'` (paint highlighted on the first * render, zero decompression). Frame indices count `span.frame` children only, * matching `getInitialVisibleFrames`. * * The decoded `root` is shared/read-only; this only reads its frames (the synthetic * visible frame reuses the frame's `children` array without mutating it, and * `data-lined` is dropped via destructuring, not deletion). */ export declare function buildCriticalFallback(root: HastRoot, visibleFrames: { [key: number]: boolean; }): { [frameIndex: number]: FallbackNode; }; /** * Splice a sparse {@link buildCriticalFallback} diff back onto a plain `fallback`, * replacing each visible frame (matched by index in document order) with its * highlighted node. The result is the full highlighted-visible fallback; its text is * byte-identical to `fallback` (the highlight spans only wrap the same characters), so * it stays a valid DEFLATE dictionary — asserted by tests. Returns a new array; the * input is not mutated. */ export declare function promoteCriticalFallback(fallback: FallbackNode[], critical: { [frameIndex: number]: FallbackNode; }): FallbackNode[]; /** * Redistributes a root fallback (built by `buildRootFallback`) back onto the * frames of a decoded HAST root, setting each frame's `data.fallback` to the * corresponding fallback frame's text nodes (as HAST, not the compact form). * * Frames align 1:1 by position because the root fallback and the decoded HAST * are both derived from the same final tree. Non-frame fallback entries (e.g. * inter-frame whitespace) advance the cursor without being assigned. Mutates * `root` in place and returns it. */ export declare function redistributeRootFallback(root: HastRoot, fallback: FallbackNode[]): HastRoot; /** * Reduce a root fallback to the frames visible while the code block is * collapsed — the contiguous focused window (`padding-top`, `highlighted` / * `focus`, `padding-bottom`). Inter-frame nodes inside that window are kept so * the slice renders with the same spacing as the full fallback. * * Matches the runtime rule in `Pre.tsx`: when a block has no emphasis frames * (the whole source is the focused window) the first frame stands in. Returns * the input unchanged when it has no frames at all. * * When `collapsesToEmpty` is `true` the source records `focusedLines === 0` * (the `oversizedFocus: 'hide'` collapse-to-nothing case): the collapsed window * is intentionally empty, so the first-frame fallback is skipped and an empty * array is returned. Mirrors the runtime rule in `Pre.tsx` / * `getInitialVisibleSourceLines`. * * Used by `fallbackCollapsed` to paint only the on-screen lines while the * file's full fallback rides along compressed (see the prop-compression * pattern's "Splitting the Fallback by Visibility"). */ export declare function collapsedVisibleFallback(fallback: FallbackNode[], collapsesToEmpty?: boolean): FallbackNode[];