UNPKG

@mui/internal-docs-infra

Version:

MUI Infra - internal documentation creation tools.

925 lines (879 loc) 38.3 kB
'use client'; import _objectSpread from "@babel/runtime/helpers/esm/objectSpread2"; import _typeof from "@babel/runtime/helpers/esm/typeof"; import _slicedToArray from "@babel/runtime/helpers/esm/slicedToArray"; import _createForOfIteratorHelper from "@babel/runtime/helpers/esm/createForOfIteratorHelper"; import _regeneratorRuntime from "@babel/runtime/helpers/esm/regeneratorRuntime"; import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import _toConsumableArray from "@babel/runtime/helpers/esm/toConsumableArray"; import * as React from 'react'; import { useCodeContext } from "../CodeProvider/CodeContext.js"; import { CodeHighlighterContext } from "./CodeHighlighterContext.js"; import { CodeErrorsContext } from "../useErrors/ErrorsContext.js"; import { maybeInitialData } from "./maybeInitialData.js"; import { loadFallbackCode } from "./loadFallbackCode.js"; import { hasAllVariants } from "./hasAllVariants.js"; import { loadVariant } from "./loadVariant.js"; import { CodeHighlighterFallbackContext } from "./CodeHighlighterFallbackContext.js"; import { useControlledCode } from "../CodeControllerContext/index.js"; import { codeToFallbackProps } from "./codeToFallbackProps.js"; import { parseCode } from "./parseCode.js"; import { applyTransforms, getAvailableTransforms } from "./transformCode.js"; import { parseControlledCode } from "./parseControlledCode.js"; import { useOnHydrate } from "../useOnHydrate/index.js"; import { useOnIdle } from "../useOnIdle/index.js"; import { mergeMetadata } from "./mergeMetadata.js"; import { jsx as _jsx } from "react/jsx-runtime"; var DEBUG = false; // Set to true for debugging purposes function useInitialData(_ref) { var variants = _ref.variants, variantName = _ref.variantName, code = _ref.code, setCode = _ref.setCode, fileName = _ref.fileName, url = _ref.url, highlightAt = _ref.highlightAt, fallbackUsesExtraFiles = _ref.fallbackUsesExtraFiles, fallbackUsesAllVariants = _ref.fallbackUsesAllVariants, isControlled = _ref.isControlled, globalsCode = _ref.globalsCode, setProcessedGlobalsCode = _ref.setProcessedGlobalsCode, setErrors = _ref.setErrors; var _useCodeContext = useCodeContext(), sourceParser = _useCodeContext.sourceParser, loadCodeMeta = _useCodeContext.loadCodeMeta, loadVariantMeta = _useCodeContext.loadVariantMeta, loadSource = _useCodeContext.loadSource; var _React$useMemo = React.useMemo(function () { return maybeInitialData(variants, variantName, code, fileName, highlightAt === 'init', fallbackUsesExtraFiles, fallbackUsesAllVariants); }, [variants, variantName, code, fileName, highlightAt, fallbackUsesExtraFiles, fallbackUsesAllVariants]), initialData = _React$useMemo.initialData, reason = _React$useMemo.reason; // TODO: fallbackInitialRenderOnly option? this would mean we can't fetch fallback data on the client side // Load initial data if not provided React.useEffect(function () { if (initialData || isControlled) { return; } if (!url) { // URL is required for loading fallback data var urlError = new Error('URL is required for loading fallback data when no initial code is provided'); console.error('CodeHighlighterClient: URL is required for loading fallback data', urlError); setErrors(function (prev) { return [].concat(_toConsumableArray(prev), [urlError]); }); return; } // TODO: abort controller _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee() { var loaded; return _regeneratorRuntime().wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: if (DEBUG) { // eslint-disable-next-line no-console console.log('Loading initial data for CodeHighlighterClient: ', reason); } _context.next = 3; return loadFallbackCode(url, variantName, code, highlightAt === 'init', fallbackUsesExtraFiles, fallbackUsesAllVariants, sourceParser, loadSource, loadVariantMeta, loadCodeMeta, fileName, variants, globalsCode // Let loadFallbackCode handle processing )["catch"](function (error) { return { error: error }; }); case 3: loaded = _context.sent; if ('error' in loaded) { setErrors(function (prev) { return [].concat(_toConsumableArray(prev), [loaded.error]); }); } else { setCode(loaded.code); // Store processed globalsCode from loadFallbackCode result if (loaded.processedGlobalsCode) { setProcessedGlobalsCode(loaded.processedGlobalsCode); } } case 5: case "end": return _context.stop(); } }, _callee); }))(); }, [initialData, reason, isControlled, variantName, code, setCode, highlightAt, url, sourceParser, loadSource, loadVariantMeta, loadCodeMeta, fallbackUsesExtraFiles, fallbackUsesAllVariants, fileName, variants, globalsCode, setProcessedGlobalsCode, setErrors]); } function useAllVariants(_ref3) { var readyForContent = _ref3.readyForContent, variants = _ref3.variants, isControlled = _ref3.isControlled, url = _ref3.url, code = _ref3.code, setCode = _ref3.setCode, processedGlobalsCode = _ref3.processedGlobalsCode, globalsCode = _ref3.globalsCode, setProcessedGlobalsCode = _ref3.setProcessedGlobalsCode, setErrors = _ref3.setErrors; var _useCodeContext2 = useCodeContext(), loadCodeMeta = _useCodeContext2.loadCodeMeta, loadVariantMeta = _useCodeContext2.loadVariantMeta, loadSource = _useCodeContext2.loadSource; React.useEffect(function () { if (readyForContent || isControlled) { return; } if (!url) { // URL is required for loading variants return; } // TODO: abort controller _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee3() { var loadedCode, globalsCodeObjects, result, resultCode, errors, _iterator, _step, item; return _regeneratorRuntime().wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: _context3.prev = 0; loadedCode = code; if (loadedCode) { _context3.next = 8; break; } if (loadCodeMeta) { _context3.next = 5; break; } throw new Error('"loadCodeMeta" function is required when no code is provided'); case 5: _context3.next = 7; return loadCodeMeta(url); case 7: loadedCode = _context3.sent; case 8: // Use the already-processed globalsCode from state, or process it if not available globalsCodeObjects = []; if (!processedGlobalsCode) { _context3.next = 13; break; } // Use the already-processed globalsCode from state globalsCodeObjects = processedGlobalsCode; _context3.next = 18; break; case 13: if (!(globalsCode && globalsCode.length > 0)) { _context3.next = 18; break; } _context3.next = 16; return Promise.all(globalsCode.map(/*#__PURE__*/function () { var _ref5 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee2(item) { return _regeneratorRuntime().wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: if (!(typeof item === 'string')) { _context2.next = 4; break; } if (loadCodeMeta) { _context2.next = 3; break; } throw new Error('"loadCodeMeta" function is required for string URLs in globalsCode'); case 3: return _context2.abrupt("return", loadCodeMeta(item)); case 4: return _context2.abrupt("return", item); case 5: case "end": return _context2.stop(); } }, _callee2); })); return function (_x) { return _ref5.apply(this, arguments); }; }())); case 16: globalsCodeObjects = _context3.sent; // Store processed globalsCode in state for future use setProcessedGlobalsCode(globalsCodeObjects); case 18: _context3.next = 20; return Promise.all(variants.map(function (name) { // Resolve globalsCode for this specific variant var globalsForVariant = globalsCodeObjects.map(function (codeObj) { // Only include if this variant exists in the globalsCode return codeObj[name]; }).filter(function (item) { return Boolean(item); }); return loadVariant(url, name, loadedCode[name], undefined, // sourceParser - skip parsing loadSource, loadVariantMeta, undefined, // sourceTransformers - skip transforming { disableParsing: true, disableTransforms: true, globalsCode: globalsForVariant }).then(function (variant) { return { name: name, variant: variant }; })["catch"](function (error) { return { error: error }; }); })); case 20: result = _context3.sent; resultCode = {}; errors = []; _iterator = _createForOfIteratorHelper(result); try { for (_iterator.s(); !(_step = _iterator.n()).done;) { item = _step.value; if ('error' in item) { errors.push(item.error); } else { resultCode[item.name] = item.variant.code; } } } catch (err) { _iterator.e(err); } finally { _iterator.f(); } if (errors.length > 0) { console.error('CodeHighlighterClient: Failed to load variants', errors); // Add individual errors for specific error reporting setErrors(function (prev) { return [].concat(_toConsumableArray(prev), errors); }); } else { setCode(resultCode); } _context3.next = 32; break; case 28: _context3.prev = 28; _context3.t0 = _context3["catch"](0); console.error('CodeHighlighterClient: Failed to load all variants', _context3.t0); setErrors(function (prev) { return [].concat(_toConsumableArray(prev), [_context3.t0 instanceof Error ? _context3.t0 : new Error(String(_context3.t0))]); }); case 32: case "end": return _context3.stop(); } }, _callee3, null, [[0, 28]]); }))(); }, [readyForContent, isControlled, variants, url, code, setCode, loadSource, loadVariantMeta, loadCodeMeta, processedGlobalsCode, globalsCode, setProcessedGlobalsCode, setErrors]); return { readyForContent: readyForContent }; } function useCodeParsing(_ref6) { var code = _ref6.code, readyForContent = _ref6.readyForContent, highlightAt = _ref6.highlightAt; var _useCodeContext3 = useCodeContext(), parseSource = _useCodeContext3.parseSource; // Use timing hooks to determine when to highlight var isHydrated = useOnHydrate(); var isIdle = useOnIdle(); // Determine if we should highlight based on the highlightAt setting var shouldHighlight = React.useMemo(function () { if (!readyForContent) { return false; } switch (highlightAt) { case 'hydration': return isHydrated; case 'idle': return isIdle; case 'init': default: return true; } }, [readyForContent, highlightAt, isHydrated, isIdle]); // Parse the internal code state when ready and timing conditions are met var parsedCode = React.useMemo(function () { if (!code || !shouldHighlight || !parseSource) { return undefined; } return parseCode(code, parseSource); }, [code, shouldHighlight, parseSource]); var deferHighlight = !shouldHighlight; return { parsedCode: parsedCode, deferHighlight: deferHighlight }; } function useCodeTransforms(_ref7) { var parsedCode = _ref7.parsedCode, variantName = _ref7.variantName; var _useCodeContext4 = useCodeContext(), sourceParser = _useCodeContext4.sourceParser; var _React$useState = React.useState(undefined), _React$useState2 = _slicedToArray(_React$useState, 2), transformedCode = _React$useState2[0], setTransformedCode = _React$useState2[1]; // Get available transforms from the current variant (separate memo for efficiency) var availableTransforms = React.useMemo(function () { return getAvailableTransforms(parsedCode, variantName); }, [parsedCode, variantName]); // Effect to compute transformations for all variants React.useEffect(function () { if (!parsedCode || !sourceParser) { setTransformedCode(parsedCode); return; } // Process transformations for all variants _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee4() { var parseSource, enhanced; return _regeneratorRuntime().wrap(function _callee4$(_context4) { while (1) switch (_context4.prev = _context4.next) { case 0: _context4.prev = 0; _context4.next = 3; return sourceParser; case 3: parseSource = _context4.sent; _context4.next = 6; return applyTransforms(parsedCode, parseSource); case 6: enhanced = _context4.sent; setTransformedCode(enhanced); _context4.next = 14; break; case 10: _context4.prev = 10; _context4.t0 = _context4["catch"](0); console.error('Failed to process transforms:', _context4.t0); setTransformedCode(parsedCode); case 14: case "end": return _context4.stop(); } }, _callee4, null, [[0, 10]]); }))(); }, [parsedCode, sourceParser]); return { transformedCode: transformedCode, availableTransforms: availableTransforms }; } function useControlledCodeParsing(_ref9) { var controlledCode = _ref9.controlledCode; var _useCodeContext5 = useCodeContext(), parseSource = _useCodeContext5.parseSource; // Parse the controlled code separately (no need to check readyForContent) var parsedControlledCode = React.useMemo(function () { if (!controlledCode || !parseSource) { return undefined; } return parseControlledCode(controlledCode, parseSource); }, [controlledCode, parseSource]); return { parsedControlledCode: parsedControlledCode }; } function useGlobalsCodeMerging(_ref0) { var code = _ref0.code, globalsCode = _ref0.globalsCode, processedGlobalsCode = _ref0.processedGlobalsCode, setProcessedGlobalsCode = _ref0.setProcessedGlobalsCode, readyForContent = _ref0.readyForContent, variants = _ref0.variants; var _useCodeContext6 = useCodeContext(), loadCodeMeta = _useCodeContext6.loadCodeMeta, loadSource = _useCodeContext6.loadSource, loadVariantMeta = _useCodeContext6.loadVariantMeta; // Set processedGlobalsCode if we have ready Code objects but haven't stored them yet React.useEffect(function () { if (!globalsCode || processedGlobalsCode) { return; // No globals or already processed } // Check if all items are already Code objects (precomputed) if (globalsCode.every(function (item) { return _typeof(item) === 'object'; })) { var codeObjects = globalsCode; // Check if all Code objects have all their own variants var allReady = codeObjects.every(function (codeObj) { return hasAllVariants(Object.keys(codeObj), codeObj); }); if (allReady) { setProcessedGlobalsCode(codeObjects); return; } // If not all ready, fall through to loading logic below } // Need to load string URLs or load missing variants _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee8() { var basicCodeObjects, fullyLoadedCodeObjects; return _regeneratorRuntime().wrap(function _callee8$(_context8) { while (1) switch (_context8.prev = _context8.next) { case 0: _context8.prev = 0; _context8.next = 3; return Promise.all(globalsCode.map(/*#__PURE__*/function () { var _ref10 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee5(item) { return _regeneratorRuntime().wrap(function _callee5$(_context5) { while (1) switch (_context5.prev = _context5.next) { case 0: if (!(typeof item === 'string')) { _context5.next = 8; break; } if (loadCodeMeta) { _context5.next = 3; break; } throw new Error('"loadCodeMeta" function is required for string URLs in globalsCode'); case 3: _context5.next = 5; return loadCodeMeta(item); case 5: _context5.t0 = _context5.sent; _context5.t1 = item; return _context5.abrupt("return", { codeObj: _context5.t0, originalUrl: _context5.t1 }); case 8: return _context5.abrupt("return", { codeObj: item, originalUrl: undefined }); case 9: case "end": return _context5.stop(); } }, _callee5); })); return function (_x2) { return _ref10.apply(this, arguments); }; }())); case 3: basicCodeObjects = _context8.sent; _context8.next = 6; return Promise.all(basicCodeObjects.map(/*#__PURE__*/function () { var _ref12 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee7(_ref11) { var codeObj, originalUrl, loadedVariants; return _regeneratorRuntime().wrap(function _callee7$(_context7) { while (1) switch (_context7.prev = _context7.next) { case 0: codeObj = _ref11.codeObj, originalUrl = _ref11.originalUrl; if (!hasAllVariants(variants, codeObj)) { _context7.next = 3; break; } return _context7.abrupt("return", codeObj); case 3: // Need to load missing variants loadedVariants = _objectSpread({}, codeObj); _context7.next = 6; return Promise.all(variants.map(/*#__PURE__*/function () { var _ref13 = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime().mark(function _callee6(variantName) { var result; return _regeneratorRuntime().wrap(function _callee6$(_context6) { while (1) switch (_context6.prev = _context6.next) { case 0: if (!(codeObj[variantName] && _typeof(codeObj[variantName]) === 'object')) { _context6.next = 2; break; } return _context6.abrupt("return"); case 2: _context6.prev = 2; _context6.next = 5; return loadVariant(originalUrl || '', // Use the original URL if available variantName, codeObj[variantName], // May be undefined or string undefined, // sourceParser - skip parsing for now loadSource, loadVariantMeta, undefined, // sourceTransformers - skip transforming { disableParsing: true, disableTransforms: true }); case 5: result = _context6.sent; loadedVariants[variantName] = result.code; _context6.next = 12; break; case 9: _context6.prev = 9; _context6.t0 = _context6["catch"](2); console.warn("Failed to load variant ".concat(variantName, " for globalsCode:"), _context6.t0); // Keep the original variant data (may be undefined) case 12: case "end": return _context6.stop(); } }, _callee6, null, [[2, 9]]); })); return function (_x4) { return _ref13.apply(this, arguments); }; }())); case 6: return _context7.abrupt("return", loadedVariants); case 7: case "end": return _context7.stop(); } }, _callee7); })); return function (_x3) { return _ref12.apply(this, arguments); }; }())); case 6: fullyLoadedCodeObjects = _context8.sent; setProcessedGlobalsCode(fullyLoadedCodeObjects); _context8.next = 13; break; case 10: _context8.prev = 10; _context8.t0 = _context8["catch"](0); console.warn('Failed to load globalsCode:', _context8.t0); case 13: case "end": return _context8.stop(); } }, _callee8, null, [[0, 10]]); }))(); }, [globalsCode, processedGlobalsCode, setProcessedGlobalsCode, loadCodeMeta, loadSource, loadVariantMeta, variants]); // Determine globalsCodeObjects to use (prefer processed, fallback to direct if ready) var globalsCodeObjects = React.useMemo(function () { if (processedGlobalsCode) { return processedGlobalsCode; } if (globalsCode && globalsCode.every(function (item) { return _typeof(item) === 'object'; })) { var codeObjects = globalsCode; var allGlobalsReady = codeObjects.every(function (codeObj) { return hasAllVariants(Object.keys(codeObj), codeObj); }); if (allGlobalsReady) { return codeObjects; } } return undefined; }, [processedGlobalsCode, globalsCode]); // Merge globalsCode with code when ready return React.useMemo(function () { // If no globalsCode or code not ready, return as-is if (!globalsCode || !code || !readyForContent) { return code; } // If globalsCodeObjects isn't ready yet, return unmerged code for now if (!globalsCodeObjects) { return code; } // For precomputed code, do simple synchronous merging of extraFiles var mergedCode = _objectSpread({}, code); var hasChanges = false; variants.forEach(function (variant) { var variantData = code[variant]; if (!variantData || typeof variantData === 'string') { return; } // Get globalsCode for this variant (only exact matches, no fallback) var globalsForVariant = globalsCodeObjects.map(function (codeObj) { return codeObj[variant]; }).filter(function (item) { return Boolean(item) && _typeof(item) === 'object'; }); if (globalsForVariant.length > 0) { // Use mergeMetadata for sophisticated globals merging with proper positioning var currentVariant = variantData; globalsForVariant.forEach(function (globalVariant) { if (globalVariant.extraFiles) { // Convert globals extraFiles to metadata format for mergeMetadata var globalsMetadata = {}; for (var _i = 0, _Object$entries = Object.entries(globalVariant.extraFiles); _i < _Object$entries.length; _i++) { var _Object$entries$_i = _slicedToArray(_Object$entries[_i], 2), key = _Object$entries$_i[0], value = _Object$entries$_i[1]; if (typeof value === 'string') { globalsMetadata[key] = { source: value }; } else { globalsMetadata[key] = _objectSpread({}, value); } } // Use mergeMetadata to properly position and merge the globals currentVariant = mergeMetadata(currentVariant, globalsMetadata); } }); // Only update if the variant actually changed if (currentVariant !== variantData) { mergedCode[variant] = currentVariant; hasChanges = true; } } }); // Return merged code if we made changes, otherwise return original code return hasChanges ? mergedCode : code; }, [code, globalsCode, globalsCodeObjects, readyForContent, variants]); } function usePropsCodeGlobalsMerging(_ref14) { var code = _ref14.code, globalsCode = _ref14.globalsCode, processedGlobalsCode = _ref14.processedGlobalsCode, variants = _ref14.variants; // For props.code, always do synchronous merging if possible // We don't want to cache this in state since props.code can change frequently return React.useMemo(function () { if (!code || !globalsCode || !processedGlobalsCode) { return code; // No merge needed or not ready } // Use processedGlobalsCode for synchronous merging var globalsCodeObjects = processedGlobalsCode; // For props.code (controlled), do simple synchronous merging var mergedCode = _objectSpread({}, code); var hasChanges = false; variants.forEach(function (variant) { var variantData = code[variant]; if (!variantData || typeof variantData === 'string') { return; } // Get globalsCode for this variant (only exact matches, no fallback) var globalsForVariant = globalsCodeObjects.map(function (codeObj) { return codeObj[variant]; }).filter(function (item) { return Boolean(item) && _typeof(item) === 'object'; }); if (globalsForVariant.length > 0) { // Use mergeMetadata for sophisticated globals merging with proper positioning var currentVariant = variantData; globalsForVariant.forEach(function (globalVariant) { if (globalVariant.extraFiles) { // Convert globals extraFiles to metadata format for mergeMetadata var globalsMetadata = {}; for (var _i2 = 0, _Object$entries2 = Object.entries(globalVariant.extraFiles); _i2 < _Object$entries2.length; _i2++) { var _Object$entries2$_i = _slicedToArray(_Object$entries2[_i2], 2), key = _Object$entries2$_i[0], value = _Object$entries2$_i[1]; if (typeof value === 'string') { globalsMetadata[key] = { source: value }; } else { globalsMetadata[key] = _objectSpread({}, value); } } // Use mergeMetadata to properly position and merge the globals currentVariant = mergeMetadata(currentVariant, globalsMetadata); } }); // Only update if the variant actually changed if (currentVariant !== variantData) { mergedCode[variant] = currentVariant; hasChanges = true; } } }); // Return merged code if we made changes, otherwise return original code return hasChanges ? mergedCode : code; }, [code, globalsCode, processedGlobalsCode, variants]); } export function CodeHighlighterClient(props) { var _useControlledCode = useControlledCode(), controlledCode = _useControlledCode.controlledCode, controlledSelection = _useControlledCode.controlledSelection, controlledSetCode = _useControlledCode.controlledSetCode, controlledSetSelection = _useControlledCode.controlledSetSelection, controlledComponents = _useControlledCode.controlledComponents; var isControlled = Boolean(props.code || controlledCode); // TODO: props.code is for controlled components, props.precompute is for precomputed code // props.code should only be highlighted, but no additional fetching should be done // this is the case with live demos where the code can be edited by the user // then maybe props.code shouldn't allow highlighted code, only strings? // this is a code highlighter afterall, why would they want to control the highlighting aspect? // TODO: should we empty this state if controlled? var _React$useState3 = React.useState(_typeof(props.precompute) === 'object' ? props.precompute : undefined), _React$useState4 = _slicedToArray(_React$useState3, 2), code = _React$useState4[0], setCode = _React$useState4[1]; // Sync code state with precompute prop changes (for hot-reload) React.useEffect(function () { if (_typeof(props.precompute) === 'object') { setCode(props.precompute); } else if (props.precompute === undefined) { // Only reset to undefined if precompute is explicitly undefined setCode(undefined); } }, [props.precompute]); // State to store processed globalsCode to avoid duplicate loading var _React$useState5 = React.useState(undefined), _React$useState6 = _slicedToArray(_React$useState5, 2), processedGlobalsCode = _React$useState6[0], setProcessedGlobalsCode = _React$useState6[1]; // Error state for handling various loading and processing errors var _React$useState7 = React.useState([]), _React$useState8 = _slicedToArray(_React$useState7, 2), errors = _React$useState8[0], setErrors = _React$useState8[1]; var activeCode = controlledCode || props.code || code; var variants = React.useMemo(function () { return props.variants || Object.keys(props.components || activeCode || {}); }, [props.variants, props.components, activeCode]); // TODO: if using props.variant, then the variant is controlled and we can't use our own state // does props.variant make any sense instead of controlledSelection?.variant? var _React$useState9 = React.useState({ variant: props.initialVariant || props.defaultVariant || variants[0] }), _React$useState0 = _slicedToArray(_React$useState9, 2), selection = _React$useState0[0], setSelection = _React$useState0[1]; var variantName = (controlledSelection == null ? void 0 : controlledSelection.variant) || props.variant || selection.variant; var initialFilename; if (_typeof(activeCode == null ? void 0 : activeCode[variantName]) === 'object') { var variant = activeCode[variantName]; initialFilename = variant != null && variant.filesOrder ? variant.filesOrder[0] : variant == null ? void 0 : variant.fileName; } var fileName = (controlledSelection == null ? void 0 : controlledSelection.fileName) || props.fileName || initialFilename; var url = props.url, highlightAt = props.highlightAt, fallbackUsesExtraFiles = props.fallbackUsesExtraFiles, fallbackUsesAllVariants = props.fallbackUsesAllVariants; useInitialData({ variants: variants, variantName: variantName, code: code, setCode: setCode, fileName: fileName, url: url, highlightAt: highlightAt, fallbackUsesExtraFiles: fallbackUsesExtraFiles, fallbackUsesAllVariants: fallbackUsesAllVariants, isControlled: isControlled, globalsCode: props.globalsCode, setProcessedGlobalsCode: setProcessedGlobalsCode, setErrors: setErrors }); var readyForContent = React.useMemo(function () { if (!code) { return false; } return hasAllVariants(variants, code); }, [code, variants]); // Separate check for activeCode to determine when to show fallback var activeCodeReady = React.useMemo(function () { if (!activeCode) { return false; } // Controlled code is always ready since it comes from editing already-ready code if (controlledCode) { return true; } // For regular code, use the existing hasAllVariants function var regularCode = props.code || code; return regularCode ? hasAllVariants(variants, regularCode) : false; }, [activeCode, controlledCode, variants, props.code, code]); useAllVariants({ readyForContent: readyForContent, variants: variants, isControlled: isControlled, url: url, code: code, setCode: setCode, processedGlobalsCode: processedGlobalsCode, globalsCode: props.globalsCode, setProcessedGlobalsCode: setProcessedGlobalsCode, setErrors: setErrors }); // Merge globalsCode with internal state code (fetched data) - this should be stable once ready var stateCodeWithGlobals = useGlobalsCodeMerging({ code: code, // Only use internal state, not props.code globalsCode: props.globalsCode, processedGlobalsCode: processedGlobalsCode, setProcessedGlobalsCode: setProcessedGlobalsCode, readyForContent: readyForContent, variants: variants }); // For props.code (controlled), always re-merge when it changes (don't cache in state) var propsCodeWithGlobals = usePropsCodeGlobalsMerging({ code: props.code, globalsCode: props.globalsCode, processedGlobalsCode: processedGlobalsCode, variants: variants }); // Use props.code result if available, otherwise use state code result var codeWithGlobals = propsCodeWithGlobals || stateCodeWithGlobals; var _useCodeParsing = useCodeParsing({ code: codeWithGlobals, readyForContent: readyForContent || Boolean(props.code), highlightAt: highlightAt }), parsedCode = _useCodeParsing.parsedCode, deferHighlight = _useCodeParsing.deferHighlight; var _useCodeTransforms = useCodeTransforms({ parsedCode: parsedCode, variantName: variantName }), transformedCode = _useCodeTransforms.transformedCode, availableTransforms = _useCodeTransforms.availableTransforms; var _useControlledCodePar = useControlledCodeParsing({ controlledCode: controlledCode }), parsedControlledCode = _useControlledCodePar.parsedControlledCode; // Determine the final overlaid code (controlled takes precedence) var overlaidCode = parsedControlledCode || transformedCode || codeWithGlobals; // For fallback context, use the processed code or fall back to non-controlled code var codeForFallback = overlaidCode || (controlledCode ? undefined : props.code || code); var fallbackContext = React.useMemo(function () { return codeToFallbackProps(variantName, codeForFallback, fileName, props.fallbackUsesExtraFiles, props.fallbackUsesAllVariants); }, [variantName, codeForFallback, fileName, props.fallbackUsesExtraFiles, props.fallbackUsesAllVariants]); var context = React.useMemo(function () { return { code: overlaidCode, // Use processed/transformed code setCode: controlledSetCode, selection: controlledSelection || selection, setSelection: controlledSetSelection || setSelection, components: controlledComponents || props.components, availableTransforms: isControlled ? [] : availableTransforms, url: props.url, deferHighlight: deferHighlight, setErrors: setErrors }; }, [overlaidCode, controlledSetCode, selection, controlledSelection, controlledSetSelection, controlledComponents, props.components, isControlled, availableTransforms, props.url, deferHighlight, setErrors]); if (!props.variants && !props.components && !activeCode) { throw new Error('CodeHighlighterClient requires either `variants`, `components`, or `code` to be provided.'); } var errorsContextValue = React.useMemo(function () { return { errors: errors }; }, [errors]); // If there are errors and an errorHandler, show the errorHandler if (errors.length > 0 && props.errorHandler) { return /*#__PURE__*/_jsx(CodeErrorsContext.Provider, { value: errorsContextValue, children: props.errorHandler }); } var fallback = props.fallback; if (fallback && !props.skipFallback && !activeCodeReady) { return /*#__PURE__*/_jsx(CodeHighlighterFallbackContext.Provider, { value: fallbackContext, children: fallback }); } return /*#__PURE__*/_jsx(CodeHighlighterContext.Provider, { value: context, children: props.children }); }