react-ai-renderer 0.1.15 → 0.1.16

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.d.ts CHANGED
@@ -20,11 +20,28 @@ interface ComponentHandler extends BaseComponentHandler {
20
20
  onRenderFinished?: (item: ComponentData$1, scope: any) => void;
21
21
  /** @deprecated 使用 onRenderProcess 替代 */
22
22
  onRender?: (item: ComponentData$1, scope: any) => void;
23
- /** 自定义占位组件,可以是 React 组件、React 元素、字符串或返回 React 元素的函数 */
24
- placeholder?: React.ComponentType<any> | React.ReactElement | string | ((componentName: string) => React.ReactElement);
23
+ /** 自定义加载组件,可以是 React 组件、React 元素、字符串、布尔值或返回 React 元素的函数 */
24
+ loader?: React.ComponentType<any> | React.ReactElement | string | boolean | ((componentName: string) => React.ReactElement);
25
25
  /** 组件的显示标签,用于在占位组件中显示 */
26
26
  label?: string;
27
27
  }
28
+ /** 增强模式的组件配置 */
29
+ interface EnhancedComponentConfig {
30
+ /** 组件本身 */
31
+ value: React.ComponentType<any>;
32
+ /** 组件的显示标签 */
33
+ label?: string;
34
+ /** 自定义加载组件,可以是 React 组件、React 元素、字符串、布尔值或返回 React 元素的函数 */
35
+ loader?: React.ComponentType<any> | React.ReactElement | string | boolean | ((componentName: string) => React.ReactElement);
36
+ /** 组件渲染完成后的钩子 */
37
+ onRenderFinished?: (item: ComponentData$1, scope: any) => void;
38
+ /** 组件渲染过程中的钩子 */
39
+ onRenderProcess?: (item: ComponentData$1, scope: any) => void;
40
+ /** 是否自闭合 */
41
+ selfClosing?: boolean;
42
+ }
43
+ /** 组件值类型:可以是组件本身,也可以是增强配置对象 */
44
+ type ComponentValue = React.ComponentType<any> | EnhancedComponentConfig;
28
45
  interface ParserState {
29
46
  position: number;
30
47
  stack: ComponentData$1[];
@@ -49,8 +66,8 @@ interface ReactAIRendererProps {
49
66
  content?: string;
50
67
  /** 作用域对象,用于传递变量和函数给组件 */
51
68
  scope?: Record<string, any>;
52
- /** 自定义组件映射 */
53
- components?: Record<string, React.ComponentType<any>>;
69
+ /** 自定义组件映射,支持普通模式(组件)和增强模式(配置对象) */
70
+ components?: Record<string, ComponentValue>;
54
71
  /** 子元素,作为 content 的替代方案 */
55
72
  children?: string;
56
73
  /** 组件处理器数组 */
@@ -121,4 +138,4 @@ declare class MDXStreamingParser {
121
138
 
122
139
  declare function ReactAIRenderer({ content, scope, components, children, componentHandlers, useGithubStyles, mdxLayoutClassName, mdxLayoutStyle }: ReactAIRendererProps): React.JSX.Element;
123
140
 
124
- export { ComponentData$1 as ComponentData, ComponentHandler, MDXStreamingParser, MdxLayout, MdxLayoutProps, ParseResult, ParserState, ReactAIRendererProps, ReactMarkdownProps, Think, ThinkProps, ToolCall, ToolCallProps, ReactAIRenderer as default };
141
+ export { ComponentData$1 as ComponentData, ComponentHandler, ComponentValue, EnhancedComponentConfig, MDXStreamingParser, MdxLayout, MdxLayoutProps, ParseResult, ParserState, ReactAIRendererProps, ReactMarkdownProps, Think, ThinkProps, ToolCall, ToolCallProps, ReactAIRenderer as default };
package/dist/index.js CHANGED
@@ -754,7 +754,6 @@ var MDXStreamingParser = /** @class */function () {
754
754
  // 这比手动转换 JavaScript 对象字面量为 JSON 更可靠
755
755
  props[propName] = new Function('return ' + rawValue)();
756
756
  } catch (e) {
757
- console.warn("Failed to parse prop value for ".concat(propName, ":"), value, e);
758
757
  // 如果 Function 构造器失败,尝试手动转换并解析为 JSON
759
758
  try {
760
759
  // 将 JavaScript 对象字面量转换为有效的 JSON
@@ -58445,7 +58444,7 @@ function renderMdx(mdxContent, scope, registeredComponents) {
58445
58444
  // 递归解析组件的函数 - 返回结构化对象
58446
58445
  function parseComponentRecursively(allComponentHandlers, item, scope) {
58447
58446
  return __awaiter(this, void 0, void 0, function () {
58448
- var componentHandler, props, propsString, childrenContent_1, parsedChildren_1, componentString, isComplete;
58447
+ var isComplete, componentHandler, props, propsString, childrenContent_1, parsedChildren_1, componentString;
58449
58448
  return __generator(this, function (_a) {
58450
58449
  switch (_a.label) {
58451
58450
  case 0:
@@ -58456,6 +58455,7 @@ function parseComponentRecursively(allComponentHandlers, item, scope) {
58456
58455
  }];
58457
58456
  }
58458
58457
  if (!(item.type === 'component')) return [3 /*break*/, 3];
58458
+ isComplete = item.isComplete === true;
58459
58459
  componentHandler = allComponentHandlers.find(function (c) {
58460
58460
  return c.name === item.value;
58461
58461
  });
@@ -58479,7 +58479,7 @@ function parseComponentRecursively(allComponentHandlers, item, scope) {
58479
58479
  _a.label = 2;
58480
58480
  case 2:
58481
58481
  componentString = (componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.selfClosing) ? "<".concat(item.value, " ").concat(propsString, " />") : ["<".concat(item.value, " ").concat(propsString, ">"), childrenContent_1, "</".concat(item.value, ">")].join('\n');
58482
- isComplete = item.isComplete === true;
58482
+ // 调用组件的渲染钩子
58483
58483
  if (isComplete) {
58484
58484
  // 渲染完成后的钩子
58485
58485
  if (componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.onRenderFinished) {
@@ -58606,15 +58606,17 @@ function MdxLayout(_a) {
58606
58606
  var ComponentPlaceholder = function (_a) {
58607
58607
  var componentName = _a.componentName,
58608
58608
  style = _a.style,
58609
- customPlaceholder = _a.customPlaceholder;
58610
- // 如果有自定义占位内容,优先使用
58611
- if (customPlaceholder) {
58609
+ loader = _a.loader;
58610
+ // 如果有自定义加载内容,优先使用
58611
+ if (loader) {
58612
+ // 如果是布尔值 true,使用默认样式
58613
+ if (typeof loader === 'boolean') ;
58612
58614
  // 如果是 React 元素,直接返回
58613
- if (/*#__PURE__*/React__default.isValidElement(customPlaceholder)) {
58614
- return customPlaceholder;
58615
+ else if (/*#__PURE__*/React__default.isValidElement(loader)) {
58616
+ return loader;
58615
58617
  }
58616
58618
  // 如果是字符串,显示字符串
58617
- if (typeof customPlaceholder === 'string') {
58619
+ else if (typeof loader === 'string') {
58618
58620
  return /*#__PURE__*/jsx("div", {
58619
58621
  style: __assign({
58620
58622
  border: '1px dashed #d1d5db',
@@ -58628,28 +58630,28 @@ var ComponentPlaceholder = function (_a) {
58628
58630
  justifyContent: 'center',
58629
58631
  minHeight: '60px'
58630
58632
  }, style),
58631
- children: customPlaceholder
58633
+ children: loader
58632
58634
  });
58633
58635
  }
58634
58636
  // 如果是函数,调用它
58635
- if (typeof customPlaceholder === 'function') {
58637
+ else if (typeof loader === 'function') {
58636
58638
  try {
58637
58639
  // 检查是否是 React 组件构造函数
58638
- var proto = customPlaceholder.prototype;
58640
+ var proto = loader.prototype;
58639
58641
  if (proto && (proto instanceof React__default.Component || proto.isReactComponent)) {
58640
58642
  // 是 React 组件类,创建元素
58641
- var Component = customPlaceholder;
58643
+ var Component = loader;
58642
58644
  return /*#__PURE__*/jsx(Component, {
58643
58645
  componentName: componentName
58644
58646
  });
58645
58647
  } else {
58646
58648
  // 是普通函数,调用它(类型断言为函数)
58647
- var func = customPlaceholder;
58649
+ var func = loader;
58648
58650
  return func(componentName);
58649
58651
  }
58650
58652
  } catch (e) {
58651
58653
  // 如果出错,尝试作为组件使用
58652
- var Component = customPlaceholder;
58654
+ var Component = loader;
58653
58655
  return /*#__PURE__*/jsx(Component, {
58654
58656
  componentName: componentName
58655
58657
  });
@@ -58745,6 +58747,51 @@ var FallbackView = /** @class */function (_super) {
58745
58747
  return FallbackView;
58746
58748
  }(React__default.Component);
58747
58749
 
58750
+ function isEnhancedComponentConfig(value) {
58751
+ return typeof value === 'object' && value !== null && 'value' in value && typeof value.value !== 'undefined';
58752
+ }
58753
+ /**
58754
+ * 从组件值中提取实际的组件
58755
+ */
58756
+ function extractComponent(value) {
58757
+ return isEnhancedComponentConfig(value) ? value.value : value;
58758
+ }
58759
+ /**
58760
+ * 将 components 转换为 ComponentHandler 数组
58761
+ */
58762
+ function convertComponentsToHandlers(components, componentHandlers) {
58763
+ return Object.entries(components).filter(function (_a) {
58764
+ var _b = __read(_a, 1),
58765
+ name = _b[0];
58766
+ return !componentHandlers.some(function (handler) {
58767
+ return handler.name === name;
58768
+ });
58769
+ }).map(function (_a) {
58770
+ var _b = __read(_a, 2),
58771
+ name = _b[0],
58772
+ componentValue = _b[1];
58773
+ if (isEnhancedComponentConfig(componentValue)) {
58774
+ // 增强模式:从配置对象中提取信息
58775
+ var config = componentValue;
58776
+ return {
58777
+ component: config.value,
58778
+ name: name,
58779
+ selfClosing: config.selfClosing !== undefined ? config.selfClosing : isSelfClosingComponent(config.value),
58780
+ onRenderFinished: config.onRenderFinished,
58781
+ onRenderProcess: config.onRenderProcess,
58782
+ loader: config.loader,
58783
+ label: config.label
58784
+ };
58785
+ } else {
58786
+ // 普通模式:直接使用组件
58787
+ return {
58788
+ component: componentValue,
58789
+ name: name,
58790
+ selfClosing: isSelfClosingComponent(componentValue)
58791
+ };
58792
+ }
58793
+ });
58794
+ }
58748
58795
  function ReactAIRenderer(_a) {
58749
58796
  var _this = this;
58750
58797
  var content = _a.content,
@@ -58767,24 +58814,16 @@ function ReactAIRenderer(_a) {
58767
58814
  });
58768
58815
  }
58769
58816
  content = content || children || '';
58770
- var allComponents = __assign(__assign({}, BuiltInComponents), components);
58771
- var allComponentHandlers = __spreadArray(__spreadArray([], __read(components ? Object.entries(components).filter(function (_a) {
58772
- var _b = __read(_a, 1),
58773
- name = _b[0];
58774
- return !componentHandlers.some(function (handler) {
58775
- return handler.name === name;
58776
- });
58777
- }).map(function (_a) {
58817
+ // 构建 allComponents:从增强配置中提取实际的组件
58818
+ var normalizedComponents = components ? Object.fromEntries(Object.entries(components).map(function (_a) {
58778
58819
  var _b = __read(_a, 2),
58779
58820
  name = _b[0],
58780
- component = _b[1];
58781
- var selfClosing = isSelfClosingComponent(component);
58782
- return {
58783
- component: component,
58784
- name: name,
58785
- selfClosing: selfClosing
58786
- };
58787
- }) : []), false), __read(componentHandlers), false);
58821
+ value = _b[1];
58822
+ return [name, extractComponent(value)];
58823
+ })) : {};
58824
+ var allComponents = __assign(__assign({}, BuiltInComponents), normalizedComponents);
58825
+ // 构建 allComponentHandlers:支持增强模式
58826
+ var allComponentHandlers = __spreadArray(__spreadArray([], __read(components ? convertComponentsToHandlers(components, componentHandlers) : []), false), __read(componentHandlers), false);
58788
58827
  var _e = __read(useState(null), 2),
58789
58828
  component = _e[0],
58790
58829
  setComponent = _e[1];
@@ -58792,6 +58831,8 @@ function ReactAIRenderer(_a) {
58792
58831
  var fallbackErrorRef = useRef({
58793
58832
  hasError: false
58794
58833
  });
58834
+ // 用于缓存已完成的组件,避免重复渲染
58835
+ var completedComponentsCacheRef = useRef(new Map());
58795
58836
  var parser = new MDXStreamingParser(allComponentHandlers);
58796
58837
  var mdxContent = content || '';
58797
58838
  // FallbackView 错误状态变化时的回调
@@ -58804,9 +58845,10 @@ function ReactAIRenderer(_a) {
58804
58845
  useEffect(function () {
58805
58846
  var parseMDX = function () {
58806
58847
  return __awaiter(_this, void 0, void 0, function () {
58807
- var ThinkComponent, ResultComponent, protectedContent, _a, thinkContent, resultContent, parsedData, parsedComponents, finalComponent, fallbackComponent, _loop_1, i, MDXComponent, parsedDataLength, lastItem;
58808
- return __generator(this, function (_b) {
58809
- switch (_b.label) {
58848
+ var ThinkComponent, ResultComponent, protectedContent, _a, thinkContent, resultContent, parsedData, parsedComponents, currentComponentCount, cacheKeys, cacheKeys_1, cacheKeys_1_1, key, indexMatch, index, finalComponent, fallbackComponent, _loop_1, i, MDXComponent, parsedDataLength, lastItem;
58849
+ var e_1, _b;
58850
+ return __generator(this, function (_c) {
58851
+ switch (_c.label) {
58810
58852
  case 0:
58811
58853
  ThinkComponent = null;
58812
58854
  ResultComponent = null;
@@ -58815,8 +58857,8 @@ function ReactAIRenderer(_a) {
58815
58857
  if (!thinkContent) return [3 /*break*/, 2];
58816
58858
  return [4 /*yield*/, renderMdx(thinkContent, scope, allComponents)];
58817
58859
  case 1:
58818
- ThinkComponent = _b.sent();
58819
- _b.label = 2;
58860
+ ThinkComponent = _c.sent();
58861
+ _c.label = 2;
58820
58862
  case 2:
58821
58863
  parsedData = [];
58822
58864
  if (!resultContent) return [3 /*break*/, 8];
@@ -58826,46 +58868,110 @@ function ReactAIRenderer(_a) {
58826
58868
  return parseComponentRecursively(allComponentHandlers, item, scope);
58827
58869
  }))];
58828
58870
  case 3:
58829
- parsedComponents = _b.sent();
58871
+ parsedComponents = _c.sent();
58872
+ currentComponentCount = parsedData.length;
58873
+ cacheKeys = Array.from(completedComponentsCacheRef.current.keys());
58874
+ try {
58875
+ for (cacheKeys_1 = __values(cacheKeys), cacheKeys_1_1 = cacheKeys_1.next(); !cacheKeys_1_1.done; cacheKeys_1_1 = cacheKeys_1.next()) {
58876
+ key = cacheKeys_1_1.value;
58877
+ indexMatch = key.match(/-(\d+)$/);
58878
+ if (indexMatch) {
58879
+ index = parseInt(indexMatch[1], 10);
58880
+ if (index >= currentComponentCount) {
58881
+ // 如果索引超出当前组件数量,删除缓存
58882
+ completedComponentsCacheRef.current.delete(key);
58883
+ }
58884
+ }
58885
+ }
58886
+ } catch (e_1_1) {
58887
+ e_1 = {
58888
+ error: e_1_1
58889
+ };
58890
+ } finally {
58891
+ try {
58892
+ if (cacheKeys_1_1 && !cacheKeys_1_1.done && (_b = cacheKeys_1.return)) _b.call(cacheKeys_1);
58893
+ } finally {
58894
+ if (e_1) throw e_1.error;
58895
+ }
58896
+ }
58830
58897
  finalComponent = [];
58831
58898
  fallbackComponent = [];
58832
58899
  _loop_1 = function (i) {
58833
- var item, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName;
58834
- return __generator(this, function (_c) {
58835
- switch (_c.label) {
58900
+ var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey;
58901
+ return __generator(this, function (_d) {
58902
+ switch (_d.label) {
58836
58903
  case 0:
58837
58904
  item = parsedComponents[i];
58905
+ currentParsedItem = parsedData[i];
58838
58906
  _result = void 0;
58839
58907
  placeholderForFallback = null;
58840
58908
  if (!(item.type === 'text')) return [3 /*break*/, 2];
58841
58909
  return [4 /*yield*/, renderText(item.value, scope, allComponents)];
58842
58910
  case 1:
58843
- _result = _c.sent();
58844
- return [3 /*break*/, 4];
58911
+ _result = _d.sent();
58912
+ finalComponent.push(_result);
58913
+ return [3 /*break*/, 11];
58845
58914
  case 2:
58846
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
58847
- case 3:
58848
- _result = _c.sent();
58849
58915
  componentNameMatch = item.value.match(/<([A-Z][A-Za-z0-9]*)/);
58850
- if (componentNameMatch) {
58851
- componentName_1 = componentNameMatch[1];
58852
- componentHandler = allComponentHandlers.find(function (c) {
58853
- return c.name === componentName_1;
58854
- });
58855
- displayName = componentName_1;
58856
- if (componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.label) {
58857
- displayName = componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.label;
58858
- }
58859
- placeholderForFallback = /*#__PURE__*/React__default.createElement(ComponentPlaceholder, {
58860
- componentName: displayName,
58861
- customPlaceholder: componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.placeholder,
58862
- key: "fallback-placeholder-".concat(i)
58863
- });
58916
+ if (!componentNameMatch) return [3 /*break*/, 9];
58917
+ componentName_1 = componentNameMatch[1];
58918
+ componentHandler = allComponentHandlers.find(function (c) {
58919
+ return c.name === componentName_1;
58920
+ });
58921
+ displayName = componentName_1;
58922
+ if (componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.label) {
58923
+ displayName = componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.label;
58864
58924
  }
58865
- _c.label = 4;
58925
+ placeholderForFallback = /*#__PURE__*/React__default.createElement(ComponentPlaceholder, {
58926
+ componentName: displayName,
58927
+ loader: componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader,
58928
+ key: "fallback-loader-".concat(componentName_1)
58929
+ });
58930
+ if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/, 6];
58931
+ cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
58932
+ if (!completedComponentsCacheRef.current.has(cacheKey)) return [3 /*break*/, 3];
58933
+ // 使用缓存的组件
58934
+ _result = completedComponentsCacheRef.current.get(cacheKey);
58935
+ return [3 /*break*/, 5];
58936
+ case 3:
58937
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
58866
58938
  case 4:
58939
+ // 缓存不存在,调用 renderMdx 并存入缓存
58940
+ _result = _d.sent();
58941
+ // 为组件设置 key,确保 React 能正确识别
58942
+ if (/*#__PURE__*/React__default.isValidElement(_result)) {
58943
+ _result = /*#__PURE__*/React__default.cloneElement(_result, {
58944
+ key: cacheKey
58945
+ });
58946
+ } else {
58947
+ _result = /*#__PURE__*/React__default.createElement(React__default.Fragment, {
58948
+ key: cacheKey
58949
+ }, _result);
58950
+ }
58951
+ // 存入缓存
58952
+ completedComponentsCacheRef.current.set(cacheKey, _result);
58953
+ _d.label = 5;
58954
+ case 5:
58955
+ finalComponent.push(_result);
58956
+ return [3 /*break*/, 8];
58957
+ case 6:
58958
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
58959
+ case 7:
58960
+ // 组件未完成,正常渲染
58961
+ _result = _d.sent();
58962
+ finalComponent.push(placeholderForFallback);
58963
+ _d.label = 8;
58964
+ case 8:
58965
+ return [3 /*break*/, 11];
58966
+ case 9:
58967
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
58968
+ case 10:
58969
+ // 没有匹配到组件名,正常渲染
58970
+ _result = _d.sent();
58867
58971
  finalComponent.push(_result);
58868
- // fallbackComponent 应该是 finalComponent 的前 i 个元素 + 当前 item 的 placeholder
58972
+ _d.label = 11;
58973
+ case 11:
58974
+ // fallbackComponent 应该是 finalComponent 的前 i 个元素 + 当前 item 的 loader
58869
58975
  fallbackComponent.length = 0;
58870
58976
  fallbackComponent.push.apply(fallbackComponent, __spreadArray([], __read(finalComponent.slice(0, i)), false));
58871
58977
  if (placeholderForFallback) {
@@ -58876,13 +58982,13 @@ function ReactAIRenderer(_a) {
58876
58982
  });
58877
58983
  };
58878
58984
  i = 0;
58879
- _b.label = 4;
58985
+ _c.label = 4;
58880
58986
  case 4:
58881
58987
  if (!(i < parsedComponents.length)) return [3 /*break*/, 7];
58882
58988
  return [5 /*yield**/, _loop_1(i)];
58883
58989
  case 5:
58884
- _b.sent();
58885
- _b.label = 6;
58990
+ _c.sent();
58991
+ _c.label = 6;
58886
58992
  case 6:
58887
58993
  i++;
58888
58994
  return [3 /*break*/, 4];
@@ -58897,7 +59003,7 @@ function ReactAIRenderer(_a) {
58897
59003
  children: finalComponent
58898
59004
  })
58899
59005
  });
58900
- _b.label = 8;
59006
+ _c.label = 8;
58901
59007
  case 8:
58902
59008
  MDXComponent = /*#__PURE__*/jsxs(React__default.Fragment, {
58903
59009
  children: [ThinkComponent, ResultComponent]