@mui/internal-docs-infra
Version:
MUI Infra - internal documentation creation tools.
96 lines (92 loc) • 4.52 kB
JavaScript
'use client';
import * as React from 'react';
import { CodeContext } from "./CodeContext.mjs";
import { PreloadProvider } from "../ChunkProvider/PreloadProvider.mjs";
import { usePreload } from "../ChunkProvider/usePreload.mjs";
import { useCodeProviderValue } from "./useCodeProviderValue.mjs";
import { ensureGrammars, preloadAllGrammars } from "../pipeline/parseSource/grammarCache.mjs";
import { normalizeToScopes } from "../pipeline/parseSource/grammarMaps.mjs";
// Lazy wrapper for the emphasis enhancer: keeps its ~13 KB chunk out of this
// provider's initial bundle, loading it only when a block actually enhances.
import { enhanceCodeEmphasisLazy } from "../pipeline/enhanceCodeEmphasis/enhanceCodeEmphasisLazy.mjs";
import { PRELOAD_KEY_COMPUTE_DELTAS, PRELOAD_KEY_EDITING, PRELOAD_KEY_LOAD_FALLBACK, PRELOAD_KEY_LOAD_VARIANT, PRELOAD_KEY_TRANSFORM_ENGINE, computeHastDeltasFactory, editingEngineFactory, loadFallbackFactory, loadVariantFactory, transformEngineFactory } from "./constants.mjs";
// Lazy: the Starry Night engine (vscode-textmate + oniguruma) loads with the
// parser on demand instead of shipping in the initial bundle, and the instance
// starts with NO grammars — passing `[]` opts into per-language loading, so each
// block registers only the grammar scopes it needs via `ensureGrammars` (driven
// by `CodeHighlighter`'s speculative preload + readiness gate) instead of
// pulling all ~146 KB gzip of grammar JSON on mount. The consumer already awaits
// `sourceParser`, so this adds no first-render penalty.
import { jsx as _jsx } from "react/jsx-runtime";
const createSourceParserLazy = () => import("../pipeline/parseSource/parseSource.mjs").then(mod => mod.createParseSource([]));
/**
* Lazy counterpart to `CodeProvider`: the same context, but the heavy functions
* (the variant/fallback loaders and the transform-delta computer that pulls
* `jsondiffpatch`) are loaded via dynamic `import()` on demand instead of bundled.
* Use this as the general default to keep them out of the initial bundle.
*
* It renders its own `PreloadProvider`, so the heavy-chunk fetches dedupe across
* every code block in its subtree - and `CodeHighlighter`'s first-render
* speculative preload shares the same promise the eventual consumer resolves -
* with no extra wiring. (Cross-page network fetches of an identical chunk are
* deduped by the browser module cache regardless.)
*/
export function CodeProviderLazy({
children,
...rest
}) {
return /*#__PURE__*/_jsx(PreloadProvider, {
children: /*#__PURE__*/_jsx(CodeProviderLazyInner, {
...rest,
children: children
})
});
}
/**
* Inner provider: lives below the `PreloadProvider` above so its `usePreload`
* resolves to that provider's dedup cache.
*/
function CodeProviderLazyInner({
children,
loadCodeMeta,
loadVariantMeta,
loadSource,
sourceEnhancers,
preloadGrammars
}) {
const preload = usePreload();
// Optional provider-level grammar warm-up. Default (omitted) stays fully lazy:
// each block loads only the grammars it needs, on demand. Fails open.
const preloadGrammarsKey = Array.isArray(preloadGrammars) ? preloadGrammars.join('\n') : preloadGrammars;
React.useEffect(() => {
if (!preloadGrammars) {
return;
}
if (preloadGrammars === 'all') {
preloadAllGrammars().catch(() => {});
} else {
ensureGrammars(normalizeToScopes(preloadGrammars)).catch(() => {});
}
// `preloadGrammarsKey` captures the array contents so a new-but-equal array
// prop doesn't re-run; `ensureGrammars` is idempotent regardless.
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [preloadGrammarsKey]);
const heavy = React.useMemo(() => ({
loadCodeFallbackLoader: () => preload(PRELOAD_KEY_LOAD_FALLBACK, loadFallbackFactory),
loadIsomorphicCodeVariantLoader: () => preload(PRELOAD_KEY_LOAD_VARIANT, loadVariantFactory),
computeHastDeltasLoader: () => preload(PRELOAD_KEY_COMPUTE_DELTAS, computeHastDeltasFactory),
editingEngineLoader: () => preload(PRELOAD_KEY_EDITING, editingEngineFactory),
transformEngineLoader: () => preload(PRELOAD_KEY_TRANSFORM_ENGINE, transformEngineFactory),
defaultSourceEnhancers: [enhanceCodeEmphasisLazy]
}), [preload]);
const context = useCodeProviderValue({
loadCodeMeta,
loadVariantMeta,
loadSource,
sourceEnhancers
}, heavy, createSourceParserLazy);
return /*#__PURE__*/_jsx(CodeContext.Provider, {
value: context,
children: children
});
}