react-ai-renderer 0.1.21 → 0.1.24

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -338,22 +338,18 @@ var MDXStreamingParser = /** @class */function () {
338
338
  MDXStreamingParser.prototype.isComponentRegistered = function (name) {
339
339
  return this.registeredComponents.has(name);
340
340
  };
341
- MDXStreamingParser.prototype.parse = function (messageId, input) {
341
+ MDXStreamingParser.prototype.parse = function (_messageId, input) {
342
342
  var e_1, _a, e_2, _b, e_3, _c;
343
- // 获取或创建该消息的解析状态
344
- var state = this.messages.get(messageId);
345
- if (!state) {
346
- state = {
347
- position: 0,
348
- stack: [],
349
- buffer: '',
350
- pendingClosingTag: undefined,
351
- pendingOpeningTag: undefined
352
- };
353
- this.messages.set(messageId, state);
354
- }
343
+ // 每次对完整 content 从零解析,保证流式增量与组件 remount 后全量重解析结果一致
344
+ var state = {
345
+ position: 0,
346
+ stack: [],
347
+ buffer: '',
348
+ pendingClosingTag: undefined,
349
+ pendingOpeningTag: undefined
350
+ };
355
351
  var result = [];
356
- var i = state.position;
352
+ var i = 0;
357
353
  // 如果有暂存的不完整闭合标签,先尝试与当前输入合并处理
358
354
  if (state.pendingClosingTag) {
359
355
  var combinedInput = state.pendingClosingTag + input;
@@ -501,13 +497,11 @@ var MDXStreamingParser = /** @class */function () {
501
497
  // 如果部分标签是栈顶组件名的前缀,说明可能是不完整的闭合标签
502
498
  if (topComponentName.startsWith(partialTag) || partialTag.length === 0) {
503
499
  state.pendingClosingTag = input.slice(i);
504
- this.messages.set(messageId, state);
505
500
  break;
506
501
  }
507
502
  }
508
503
  // 否则,可能是其他不完整的标签,暂存起来
509
504
  state.pendingClosingTag = input.slice(i);
510
- this.messages.set(messageId, state);
511
505
  break;
512
506
  }
513
507
  var tagName = input.slice(i + 2, closeTagEnd);
@@ -553,7 +547,6 @@ var MDXStreamingParser = /** @class */function () {
553
547
  // 暂存起来,不添加到文本内容
554
548
  if (topComponentName.startsWith(tagName) && tagName.length < topComponentName.length) {
555
549
  state.pendingClosingTag = input.slice(i, closeTagEnd + 1);
556
- this.messages.set(messageId, state);
557
550
  break;
558
551
  }
559
552
  }
@@ -601,12 +594,10 @@ var MDXStreamingParser = /** @class */function () {
601
594
  // 找到了部分标签,暂存起来
602
595
  var partialTagEnd = i + tagEndMatch[0].length - 1;
603
596
  state.pendingOpeningTag = input.slice(i, partialTagEnd);
604
- this.messages.set(messageId, state);
605
597
  break;
606
598
  } else {
607
599
  // 标签完全不完整,暂存整个片段
608
600
  state.pendingOpeningTag = input.slice(i);
609
- this.messages.set(messageId, state);
610
601
  break;
611
602
  }
612
603
  } else {
@@ -644,18 +635,12 @@ var MDXStreamingParser = /** @class */function () {
644
635
  props = _k.props,
645
636
  endIndex = _k.endIndex,
646
637
  selfClosing = _k.selfClosing;
647
- // 检测组件是否完整:
648
- // 1. 自闭合组件一定是完整的
649
- // 2. 非自闭合组件:如果有 props 且不在 stack 中(已闭合),则是完整的
650
- // 对于流式渲染,如果 props 为空且不是自闭合,说明组件可能还在解析中
651
- var hasProps = props && Object.keys(props).length > 0;
652
- var isComplete = selfClosing || hasProps;
653
638
  var component = {
654
639
  type: "component",
655
640
  value: componentName,
656
641
  props: props || {},
657
642
  selfClosing: selfClosing,
658
- isComplete: isComplete // 自闭合一定完整,非自闭合取决于是否有 props
643
+ isComplete: selfClosing
659
644
  };
660
645
  if (!selfClosing) {
661
646
  state.stack.push(component);
@@ -723,9 +708,35 @@ var MDXStreamingParser = /** @class */function () {
723
708
  state.stack.forEach(function (component) {
724
709
  component.isComplete = false;
725
710
  });
726
- state.position = i;
727
- // 保存状态
728
- this.messages.set(messageId, state);
711
+ // 流式未闭合的根组件可能只在 stack 中,补进 result 供 loader 渲染
712
+ if (state.stack.length > 0) {
713
+ var root_1 = state.stack[0];
714
+ var already = result.some(function (item) {
715
+ return item.type === 'component' && item.value === root_1.value;
716
+ });
717
+ if (!already) {
718
+ result.push(root_1);
719
+ }
720
+ }
721
+ // 流式未闭合的开始标签(尚未入 stack)也产出占位组件,供 loader 渲染
722
+ if (state.pendingOpeningTag) {
723
+ var tagMatch = state.pendingOpeningTag.match(/^<([A-Z][A-Za-z0-9]*)/);
724
+ if (tagMatch && this.isComponentRegistered(tagMatch[1])) {
725
+ var name_1 = tagMatch[1];
726
+ var already = result.some(function (item) {
727
+ return item.type === 'component' && item.value === name_1;
728
+ });
729
+ if (!already) {
730
+ result.push({
731
+ type: 'component',
732
+ value: name_1,
733
+ props: {},
734
+ selfClosing: false,
735
+ isComplete: false
736
+ });
737
+ }
738
+ }
739
+ }
729
740
  return result;
730
741
  };
731
742
  MDXStreamingParser.prototype.findComponentClose = function (input, startIndex) {
@@ -39580,18 +39591,64 @@ function requireZTouch () {
39580
39591
  var _zTouch = _interopRequireDefault(requireZTouch());
39581
39592
  } (prism$1));
39582
39593
 
39583
- var themes = {
39594
+ var CODE_THEME_MAP = {
39595
+ github: "ghcolors",
39596
+ atom: "atom-dark",
39597
+ "atom-dark": "atom-dark",
39598
+ "atom-light": "atom-light",
39599
+ dracula: "dracula",
39600
+ "one-dark": "one-dark",
39601
+ "one-light": "one-light",
39602
+ nord: "nord",
39603
+ "material-dark": "material-dark",
39604
+ "material-light": "material-light",
39605
+ "solarized-light": "solarizedlight",
39606
+ "solarized-dark": "solarized-dark-atom",
39607
+ okaidia: "okaidia",
39608
+ tomorrow: "tomorrow",
39609
+ coy: "coy",
39610
+ "vsc-dark-plus": "vsc-dark-plus",
39611
+ vs: "vs",
39612
+ ghcolors: "ghcolors",
39613
+ prism: "prism",
39614
+ twilight: "twilight",
39615
+ "duotone-dark": "duotone-dark",
39616
+ "duotone-light": "duotone-light",
39617
+ "night-owl": "night-owl",
39618
+ darcula: "darcula",
39619
+ "gruvbox-dark": "gruvbox-dark",
39620
+ "gruvbox-light": "gruvbox-light"
39621
+ };
39622
+ // 预置的默认主题
39623
+ var DEFAULT_THEMES = {
39584
39624
  dark: prism$1.vscDarkPlus,
39585
39625
  light: prism$1.vs
39586
39626
  };
39627
+ /**
39628
+ * 根据 codeTheme 名称加载对应的 prism 样式
39629
+ */
39630
+ function loadCodeStyle(codeTheme) {
39631
+ // 先查映射表
39632
+ var moduleName = CODE_THEME_MAP[codeTheme] || codeTheme;
39633
+ try {
39634
+ // 使用 require 动态加载 prism 样式模块
39635
+ var styles = require("react-syntax-highlighter/dist/cjs/styles/prism/".concat(moduleName));
39636
+ return styles.default || styles;
39637
+ } catch (_a) {
39638
+ // 加载失败时回退到默认暗色主题
39639
+ return prism$1.vscDarkPlus;
39640
+ }
39641
+ }
39587
39642
  var CodeHighlight = function (_a) {
39588
39643
  var textContent = _a.textContent,
39589
39644
  _b = _a.language,
39590
39645
  language = _b === void 0 ? "txt" : _b,
39591
- darkMode = _a.darkMode;
39592
- var _c = __read(React.useState(false), 2),
39593
- showCopy = _c[0],
39594
- setShowCopy = _c[1];
39646
+ _c = _a.theme,
39647
+ theme = _c === void 0 ? "dark" : _c,
39648
+ codeTheme = _a.codeTheme;
39649
+ var _d = __read(React.useState(false), 2),
39650
+ showCopy = _d[0],
39651
+ setShowCopy = _d[1];
39595
39652
  var copyToClipboard = function (text) {
39596
39653
  return __awaiter(void 0, void 0, void 0, function () {
39597
39654
  var textarea;
@@ -39655,6 +39712,11 @@ var CodeHighlight = function (_a) {
39655
39712
  }, Date.now())
39656
39713
  });
39657
39714
  }
39715
+ // 根据 codeTheme / theme 计算最终的代码高亮样式
39716
+ var syntaxStyle = React.useMemo(function () {
39717
+ if (codeTheme) return loadCodeStyle(codeTheme);
39718
+ return DEFAULT_THEMES[theme] || DEFAULT_THEMES.dark;
39719
+ }, [codeTheme, theme]);
39658
39720
  return /*#__PURE__*/runtime.jsxs("div", {
39659
39721
  style: {
39660
39722
  position: "relative"
@@ -39665,7 +39727,7 @@ var CodeHighlight = function (_a) {
39665
39727
  right: "10px",
39666
39728
  top: "5px",
39667
39729
  zIndex: 1,
39668
- background: darkMode ? "#555" : "#333",
39730
+ background: theme === "light" ? "#e8e8e8" : "#555",
39669
39731
  color: "#fff",
39670
39732
  border: "none",
39671
39733
  padding: "4px 8px",
@@ -39685,7 +39747,7 @@ var CodeHighlight = function (_a) {
39685
39747
  },
39686
39748
  children: showCopy ? "点击复制" : "复制"
39687
39749
  }), /*#__PURE__*/runtime.jsx(SyntaxHighlighter, {
39688
- style: themes.dark,
39750
+ style: syntaxStyle,
39689
39751
  language: language,
39690
39752
  PreTag: "div",
39691
39753
  children: String(textContent).replace(/\n$/, "")
@@ -39811,44 +39873,48 @@ var AudioComponent = function (_a) {
39811
39873
  }), "\u4F60\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E"]
39812
39874
  });
39813
39875
  };
39814
- // 代码组件
39815
- var CodeComponent = function (props) {
39816
- var children = props.children,
39817
- className = props.className;
39818
- props.node;
39819
- var rest = __rest(props, ["children", "className", "node"]);
39820
- var match = /language-(\w+)/.exec(className || "");
39821
- String(children).replace(/\n$/, '');
39822
- var extractText = function (children) {
39823
- return React.Children.toArray(children).reduce(function (acc, child) {
39824
- if (typeof child === 'string') {
39825
- return acc + child;
39826
- } else if (/*#__PURE__*/React.isValidElement(child) && child.props && child.props.children) {
39827
- return acc + extractText(child.props.children);
39876
+ // 代码组件(支持 theme 和 codeTheme 透传)
39877
+ var createCodeComponent = function (theme, codeTheme) {
39878
+ var CodeComponent = function (props) {
39879
+ var children = props.children,
39880
+ className = props.className;
39881
+ props.node;
39882
+ var rest = __rest(props, ["children", "className", "node"]);
39883
+ var match = /language-(\w+)/.exec(className || "");
39884
+ var extractText = function (children) {
39885
+ return React.Children.toArray(children).reduce(function (acc, child) {
39886
+ if (typeof child === 'string') {
39887
+ return acc + child;
39888
+ } else if (/*#__PURE__*/React.isValidElement(child) && child.props && child.props.children) {
39889
+ return acc + extractText(child.props.children);
39890
+ }
39891
+ return acc;
39892
+ }, '');
39893
+ };
39894
+ var content = extractText(children);
39895
+ // 增强语言检测逻辑,检查内容中是否包含mermaid特征
39896
+ var language = match ? match[1] : "txt";
39897
+ // 如果内容包含mermaid特征且语言未正确识别,则强制设置为mermaid
39898
+ if (!match || match[1] !== "mermaid") {
39899
+ var trimmedContent = content.trim();
39900
+ if (trimmedContent.startsWith('graph') || trimmedContent.startsWith('flowchart') || trimmedContent.startsWith('sequenceDiagram') || trimmedContent.startsWith('gantt') || trimmedContent.startsWith('classDiagram') || trimmedContent.startsWith('stateDiagram') || trimmedContent.startsWith('pie') || trimmedContent.startsWith('erDiagram') || trimmedContent.startsWith('journey') || trimmedContent.startsWith('requirementDiagram') || trimmedContent.startsWith('gitGraph')) {
39901
+ language = "mermaid";
39828
39902
  }
39829
- return acc;
39830
- }, '');
39903
+ }
39904
+ return language !== "txt" ? /*#__PURE__*/runtime.jsx(CodeHighlight, {
39905
+ ...rest,
39906
+ language: language,
39907
+ textContent: content,
39908
+ theme: theme,
39909
+ codeTheme: codeTheme,
39910
+ children: content
39911
+ }) : /*#__PURE__*/runtime.jsx("code", {
39912
+ className: className,
39913
+ ...props,
39914
+ children: content
39915
+ });
39831
39916
  };
39832
- var content = extractText(children);
39833
- // 增强语言检测逻辑,检查内容中是否包含mermaid特征
39834
- var language = match ? match[1] : "txt";
39835
- // 如果内容包含mermaid特征且语言未正确识别,则强制设置为mermaid
39836
- if (!match || match[1] !== "mermaid") {
39837
- var trimmedContent = content.trim();
39838
- if (trimmedContent.startsWith('graph') || trimmedContent.startsWith('flowchart') || trimmedContent.startsWith('sequenceDiagram') || trimmedContent.startsWith('gantt') || trimmedContent.startsWith('classDiagram') || trimmedContent.startsWith('stateDiagram') || trimmedContent.startsWith('pie') || trimmedContent.startsWith('erDiagram') || trimmedContent.startsWith('journey') || trimmedContent.startsWith('requirementDiagram') || trimmedContent.startsWith('gitGraph')) {
39839
- language = "mermaid";
39840
- }
39841
- }
39842
- return language !== "txt" ? /*#__PURE__*/runtime.jsx(CodeHighlight, {
39843
- ...rest,
39844
- language: language,
39845
- textContent: content,
39846
- children: content
39847
- }) : /*#__PURE__*/runtime.jsx("code", {
39848
- className: className,
39849
- ...props,
39850
- children: content
39851
- });
39917
+ return CodeComponent;
39852
39918
  };
39853
39919
  // 段落组件
39854
39920
  var PComponent = function (pProps) {
@@ -39876,16 +39942,23 @@ var PreComponent = function (props) {
39876
39942
  ...props
39877
39943
  });
39878
39944
  };
39879
- var BuiltInComponents = {
39880
- _THINK: Think,
39881
- // _TOOL_CALL: ToolCall,
39882
- pre: PreComponent,
39883
- code: CodeComponent,
39884
- p: PComponent,
39885
- a: AComponent,
39886
- video: VideoComponent,
39887
- audio: AudioComponent
39888
- };
39945
+ /**
39946
+ * 创建带主题配置的内置组件集合
39947
+ * @param theme 整体主题 (dark / light / 自定义)
39948
+ * @param codeTheme 代码语法主题 (github / atom / 自定义)
39949
+ */
39950
+ function createBuiltInComponents(theme, codeTheme) {
39951
+ var themedCode = createCodeComponent(theme, codeTheme);
39952
+ return {
39953
+ _THINK: Think,
39954
+ pre: PreComponent,
39955
+ code: themedCode,
39956
+ p: PComponent,
39957
+ a: AComponent,
39958
+ video: VideoComponent,
39959
+ audio: AudioComponent
39960
+ };
39961
+ }
39889
39962
 
39890
39963
  var ErrorBoundary = /** @class */function (_super) {
39891
39964
  __extends(ErrorBoundary, _super);
@@ -59412,15 +59485,9 @@ var FallbackView = /** @class */function (_super) {
59412
59485
  function isEnhancedComponentConfig(value) {
59413
59486
  return typeof value === 'object' && value !== null && 'value' in value && typeof value.value !== 'undefined';
59414
59487
  }
59415
- /**
59416
- * 从组件值中提取实际的组件
59417
- */
59418
59488
  function extractComponent(value) {
59419
59489
  return isEnhancedComponentConfig(value) ? value.value : value;
59420
59490
  }
59421
- /**
59422
- * 将 components 转换为 ComponentHandler 数组
59423
- */
59424
59491
  function convertComponentsToHandlers(components, componentHandlers) {
59425
59492
  var e_1, _a;
59426
59493
  var handlers = [];
@@ -59472,6 +59539,58 @@ function convertComponentsToHandlers(components, componentHandlers) {
59472
59539
  }
59473
59540
  return handlers;
59474
59541
  }
59542
+ function buildLoaderShellFromParsed(parsedData, allComponentHandlers, layoutProps) {
59543
+ if (!parsedData.length) return null;
59544
+ var nodes = [];
59545
+ var _loop_2 = function (i) {
59546
+ var item = parsedData[i];
59547
+ if (item.type === 'text') {
59548
+ var t = String(item.value || '').trim();
59549
+ if (t) {
59550
+ nodes.push(/*#__PURE__*/React.createElement('div', {
59551
+ key: "sync-txt-".concat(i),
59552
+ style: {
59553
+ whiteSpace: 'pre-wrap'
59554
+ }
59555
+ }, t));
59556
+ }
59557
+ return "continue";
59558
+ }
59559
+ if (item.type !== 'component' || item.isComplete === true) return "continue";
59560
+ var handler = allComponentHandlers.find(function (c) {
59561
+ return c.name === item.value;
59562
+ });
59563
+ if (!(handler === null || handler === void 0 ? void 0 : handler.loader)) return "continue";
59564
+ var displayName = handler.label || item.value;
59565
+ nodes.push(/*#__PURE__*/React.createElement(ComponentPlaceholder, {
59566
+ key: "sync-loader-".concat(item.value, "-").concat(i),
59567
+ componentName: displayName,
59568
+ loader: handler.loader
59569
+ }));
59570
+ };
59571
+ for (var i = 0; i < parsedData.length; i++) {
59572
+ _loop_2(i);
59573
+ }
59574
+ if (!nodes.length) return null;
59575
+ return /*#__PURE__*/React.createElement(MdxLayout, __assign(__assign({}, layoutProps), {
59576
+ children: React.createElement.apply(React, __spreadArray([React.Fragment, null], __read(nodes), false))
59577
+ }));
59578
+ }
59579
+ function parsedStructureSignature(parsedData) {
59580
+ return parsedData.map(function (p) {
59581
+ if (p.type === 'text') return "t:".concat(String(p.value || '').length);
59582
+ return "c:".concat(p.value, ":").concat(p.isComplete === true ? '1' : '0');
59583
+ }).join('|');
59584
+ }
59585
+ function hasPendingLoaderComponents(parsedData, handlers) {
59586
+ return parsedData.some(function (item) {
59587
+ var _a;
59588
+ if (item.type !== 'component' || item.isComplete === true) return false;
59589
+ return Boolean((_a = handlers.find(function (h) {
59590
+ return h.name === item.value;
59591
+ })) === null || _a === void 0 ? void 0 : _a.loader);
59592
+ });
59593
+ }
59475
59594
  function ReactAIRenderer(_a) {
59476
59595
  var _this = this;
59477
59596
  var content = _a.content,
@@ -59484,14 +59603,19 @@ function ReactAIRenderer(_a) {
59484
59603
  componentHandlers = _d === void 0 ? [] : _d,
59485
59604
  useGithubStyles = _a.useGithubStyles,
59486
59605
  mdxLayoutClassName = _a.mdxLayoutClassName,
59487
- mdxLayoutStyle = _a.mdxLayoutStyle;
59488
- var _e = __read(React.useState(null), 2),
59489
- component = _e[0],
59490
- setComponent = _e[1];
59606
+ mdxLayoutStyle = _a.mdxLayoutStyle,
59607
+ _e = _a.theme,
59608
+ theme = _e === void 0 ? "dark" : _e,
59609
+ codeTheme = _a.codeTheme;
59610
+ var _f = __read(React.useState(null), 2),
59611
+ component = _f[0],
59612
+ setComponent = _f[1];
59491
59613
  var fallbackErrorRef = React.useRef({
59492
59614
  hasError: false
59493
59615
  });
59494
59616
  var completedComponentsCacheRef = React.useRef(new Map());
59617
+ var parserRef = React.useRef(null);
59618
+ var lastLoaderSigRef = React.useRef('');
59495
59619
  var isBrowser = typeof window !== 'undefined';
59496
59620
  content = content || children || '';
59497
59621
  var normalizedComponents = components ? Object.fromEntries(Object.entries(components).filter(function (_a) {
@@ -59505,11 +59629,26 @@ function ReactAIRenderer(_a) {
59505
59629
  value = _b[1];
59506
59630
  return [name, extractComponent(value)];
59507
59631
  })) : {};
59508
- var allComponents = __assign(__assign({}, BuiltInComponents), normalizedComponents);
59632
+ // 根据 theme / codeTheme 创建带主题配置的内置组件
59633
+ var themedBuiltInComponents = React.useMemo(function () {
59634
+ return createBuiltInComponents(theme, codeTheme);
59635
+ }, [theme, codeTheme]);
59636
+ var allComponents = __assign(__assign({}, themedBuiltInComponents), normalizedComponents);
59509
59637
  var allComponentHandlers = __spreadArray(__spreadArray([], __read(components ? convertComponentsToHandlers(components, componentHandlers) : []), false), __read(componentHandlers), false);
59510
- var parser = new MDXStreamingParser(allComponentHandlers);
59638
+ if (!parserRef.current) {
59639
+ parserRef.current = new MDXStreamingParser(allComponentHandlers);
59640
+ }
59641
+ var parser = parserRef.current;
59511
59642
  var mdxContent = content || '';
59512
- // FallbackView 错误状态变化时的回调
59643
+ var handlersRef = React.useRef(allComponentHandlers);
59644
+ handlersRef.current = allComponentHandlers;
59645
+ var layoutProps = React.useMemo(function () {
59646
+ return {
59647
+ useGithubStyles: useGithubStyles,
59648
+ className: mdxLayoutClassName,
59649
+ style: mdxLayoutStyle
59650
+ };
59651
+ }, [useGithubStyles, mdxLayoutClassName, mdxLayoutStyle]);
59513
59652
  var handleFallbackErrorChange = function (hasError, error) {
59514
59653
  fallbackErrorRef.current = {
59515
59654
  hasError: hasError,
@@ -59518,17 +59657,32 @@ function ReactAIRenderer(_a) {
59518
59657
  };
59519
59658
  React.useEffect(function () {
59520
59659
  if (!isBrowser) return;
59660
+ var cancelled = false;
59521
59661
  var parseMDX = function () {
59522
59662
  return __awaiter(_this, void 0, void 0, function () {
59523
- var ThinkComponent, ResultComponent, protectedContent, _a, thinkContent, resultContent, parsedData, parsedComponents, currentComponentCount, cacheKeys, cacheKeys_1, cacheKeys_1_1, key, indexMatch, index, finalComponent, fallbackComponent, _loop_2, i, MDXComponent, parsedDataLength, lastItem;
59663
+ var protectedContent, _a, thinkContent, resultContent, parsedData_1, loaderSig, shell, ThinkComponent, ResultComponent, parsedData, parsedComponents, currentComponentCount, cacheKeys, cacheKeys_1, cacheKeys_1_1, key, indexMatch, index, finalComponent, fallbackComponent, _loop_3, i, MDXComponent, parsedDataLength, lastItem;
59524
59664
  var e_2, _b;
59525
59665
  return __generator(this, function (_c) {
59526
59666
  switch (_c.label) {
59527
59667
  case 0:
59528
- ThinkComponent = null;
59529
- ResultComponent = null;
59530
59668
  protectedContent = protectSpecialSyntax(mdxContent);
59531
59669
  _a = remarkThinkUpdate(protectedContent), thinkContent = _a.thinkContent, resultContent = _a.resultContent;
59670
+ if (resultContent) {
59671
+ resultContent = fixMDXContent(resultContent);
59672
+ parsedData_1 = parser.parse('magic', resultContent);
59673
+ loaderSig = parsedStructureSignature(parsedData_1);
59674
+ if (hasPendingLoaderComponents(parsedData_1, handlersRef.current)) {
59675
+ if (loaderSig !== lastLoaderSigRef.current) {
59676
+ lastLoaderSigRef.current = loaderSig;
59677
+ shell = buildLoaderShellFromParsed(parsedData_1, handlersRef.current, layoutProps);
59678
+ if (shell && !cancelled) setComponent(shell);
59679
+ }
59680
+ return [2 /*return*/];
59681
+ }
59682
+ lastLoaderSigRef.current = '';
59683
+ }
59684
+ ThinkComponent = null;
59685
+ ResultComponent = null;
59532
59686
  if (!thinkContent) return [3 /*break*/, 2];
59533
59687
  return [4 /*yield*/, renderMdx(thinkContent, scope, allComponents)];
59534
59688
  case 1:
@@ -59537,7 +59691,6 @@ function ReactAIRenderer(_a) {
59537
59691
  case 2:
59538
59692
  parsedData = [];
59539
59693
  if (!resultContent) return [3 /*break*/, 8];
59540
- resultContent = fixMDXContent(resultContent);
59541
59694
  parsedData = parser.parse('magic', resultContent);
59542
59695
  return [4 /*yield*/, Promise.all(parsedData.map(function (item) {
59543
59696
  return parseComponentRecursively(allComponentHandlers, item, scope);
@@ -59553,7 +59706,6 @@ function ReactAIRenderer(_a) {
59553
59706
  if (indexMatch) {
59554
59707
  index = parseInt(indexMatch[1], 10);
59555
59708
  if (index >= currentComponentCount) {
59556
- // 如果索引超出当前组件数量,删除缓存
59557
59709
  completedComponentsCacheRef.current.delete(key);
59558
59710
  }
59559
59711
  }
@@ -59571,7 +59723,7 @@ function ReactAIRenderer(_a) {
59571
59723
  }
59572
59724
  finalComponent = [];
59573
59725
  fallbackComponent = [];
59574
- _loop_2 = function (i) {
59726
+ _loop_3 = function (i) {
59575
59727
  var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey;
59576
59728
  return __generator(this, function (_d) {
59577
59729
  switch (_d.label) {
@@ -59585,10 +59737,10 @@ function ReactAIRenderer(_a) {
59585
59737
  case 1:
59586
59738
  _result = _d.sent();
59587
59739
  finalComponent.push(_result);
59588
- return [3 /*break*/, 11];
59740
+ return [3 /*break*/, 12];
59589
59741
  case 2:
59590
59742
  componentNameMatch = item.value.match(/<([A-Z][A-Za-z0-9]*)/);
59591
- if (!componentNameMatch) return [3 /*break*/, 9];
59743
+ if (!componentNameMatch) return [3 /*break*/, 10];
59592
59744
  componentName_1 = componentNameMatch[1];
59593
59745
  componentHandler = allComponentHandlers.find(function (c) {
59594
59746
  return c.name === componentName_1;
@@ -59605,15 +59757,12 @@ function ReactAIRenderer(_a) {
59605
59757
  if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/, 6];
59606
59758
  cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
59607
59759
  if (!completedComponentsCacheRef.current.has(cacheKey)) return [3 /*break*/, 3];
59608
- // 使用缓存的组件
59609
59760
  _result = completedComponentsCacheRef.current.get(cacheKey);
59610
59761
  return [3 /*break*/, 5];
59611
59762
  case 3:
59612
59763
  return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59613
59764
  case 4:
59614
- // 缓存不存在,调用 renderMdx 并存入缓存
59615
59765
  _result = _d.sent();
59616
- // 为组件设置 key,确保 React 能正确识别
59617
59766
  if (/*#__PURE__*/React.isValidElement(_result)) {
59618
59767
  _result = /*#__PURE__*/React.cloneElement(_result, {
59619
59768
  key: cacheKey
@@ -59623,30 +59772,30 @@ function ReactAIRenderer(_a) {
59623
59772
  key: cacheKey
59624
59773
  }, _result);
59625
59774
  }
59626
- // 存入缓存
59627
59775
  completedComponentsCacheRef.current.set(cacheKey, _result);
59628
59776
  _d.label = 5;
59629
59777
  case 5:
59630
59778
  finalComponent.push(_result);
59631
- return [3 /*break*/, 8];
59779
+ return [3 /*break*/, 9];
59632
59780
  case 6:
59633
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59634
- case 7:
59635
- // 组件未完成,正常渲染
59636
- _result = _d.sent();
59781
+ if (!placeholderForFallback) return [3 /*break*/, 7];
59637
59782
  finalComponent.push(placeholderForFallback);
59638
- _d.label = 8;
59783
+ return [3 /*break*/, 9];
59784
+ case 7:
59785
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59639
59786
  case 8:
59640
- return [3 /*break*/, 11];
59787
+ _result = _d.sent();
59788
+ finalComponent.push(_result);
59789
+ _d.label = 9;
59641
59790
  case 9:
59642
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59791
+ return [3 /*break*/, 12];
59643
59792
  case 10:
59644
- // 没有匹配到组件名,正常渲染
59793
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59794
+ case 11:
59645
59795
  _result = _d.sent();
59646
59796
  finalComponent.push(_result);
59647
- _d.label = 11;
59648
- case 11:
59649
- // fallbackComponent 应该是 finalComponent 的前 i 个元素 + 当前 item 的 loader
59797
+ _d.label = 12;
59798
+ case 12:
59650
59799
  fallbackComponent.length = 0;
59651
59800
  fallbackComponent.push.apply(fallbackComponent, __spreadArray([], __read(finalComponent.slice(0, i)), false));
59652
59801
  if (placeholderForFallback) {
@@ -59660,7 +59809,7 @@ function ReactAIRenderer(_a) {
59660
59809
  _c.label = 4;
59661
59810
  case 4:
59662
59811
  if (!(i < parsedComponents.length)) return [3 /*break*/, 7];
59663
- return [5 /*yield**/, _loop_2(i)];
59812
+ return [5 /*yield**/, _loop_3(i)];
59664
59813
  case 5:
59665
59814
  _c.sent();
59666
59815
  _c.label = 6;
@@ -59683,13 +59832,13 @@ function ReactAIRenderer(_a) {
59683
59832
  MDXComponent = /*#__PURE__*/runtime.jsxs(React.Fragment, {
59684
59833
  children: [ThinkComponent, ResultComponent]
59685
59834
  });
59835
+ if (cancelled) return [2 /*return*/];
59686
59836
  if (!fallbackErrorRef.current.hasError) {
59687
59837
  setComponent(MDXComponent);
59688
59838
  } else {
59689
59839
  parsedDataLength = parsedData.length;
59690
59840
  if (parsedDataLength > 0) {
59691
59841
  lastItem = parsedData[parsedDataLength - 1];
59692
- // 如果最后一个组件是完整的,强制更新
59693
59842
  if (lastItem.isComplete === true) {
59694
59843
  setComponent(MDXComponent);
59695
59844
  } else if (lastItem.type === 'text') {
@@ -59703,7 +59852,10 @@ function ReactAIRenderer(_a) {
59703
59852
  });
59704
59853
  };
59705
59854
  parseMDX();
59706
- }, [content]);
59855
+ return function () {
59856
+ cancelled = true;
59857
+ };
59858
+ }, [content, theme, codeTheme]);
59707
59859
  if (!isBrowser) {
59708
59860
  return null;
59709
59861
  }