react-ai-renderer 0.1.20 → 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
@@ -31,58 +31,6 @@ function _interopNamespaceDefault(e) {
31
31
  var React__namespace = /*#__PURE__*/_interopNamespaceDefault(React);
32
32
  var runtime__namespace = /*#__PURE__*/_interopNamespaceDefault(runtime);
33
33
 
34
- // SSR 兼容性 polyfill
35
- // 这个文件确保在服务端渲染时不会因为访问 document 而报错
36
- // 在模块加载时就设置全局保护
37
- if (typeof globalThis !== 'undefined' && globalThis.document === undefined) {
38
- // 为 SSR 环境创建一个模拟的 document 对象
39
- var mockElement_1 = {
40
- innerHTML: '',
41
- textContent: '',
42
- appendChild: function () {
43
- return mockElement_1;
44
- },
45
- removeChild: function () {
46
- return mockElement_1;
47
- },
48
- remove: function () {},
49
- id: '',
50
- className: '',
51
- setAttribute: function () {},
52
- getAttribute: function () {
53
- return null;
54
- },
55
- removeAttribute: function () {},
56
- querySelector: function () {
57
- return null;
58
- },
59
- querySelectorAll: function () {
60
- return [];
61
- }
62
- };
63
- // 创建模拟的 document 对象
64
- var mockDocument = {
65
- createElement: function () {
66
- return mockElement_1;
67
- },
68
- getElementById: function () {
69
- return null;
70
- },
71
- querySelector: function () {
72
- return null;
73
- },
74
- querySelectorAll: function () {
75
- return [];
76
- },
77
- body: mockElement_1,
78
- head: mockElement_1,
79
- addEventListener: function () {},
80
- removeEventListener: function () {}
81
- };
82
- // 在 SSR 环境中提供全局的 document
83
- globalThis.document = mockDocument;
84
- }
85
-
86
34
  /******************************************************************************
87
35
  Copyright (c) Microsoft Corporation.
88
36
 
@@ -219,6 +167,165 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
219
167
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
220
168
  };
221
169
 
170
+ if (typeof globalThis !== 'undefined' && typeof globalThis.window === 'undefined') {
171
+ var mockElement_1 = {
172
+ innerHTML: '',
173
+ textContent: '',
174
+ nodeValue: '',
175
+ appendChild: function () {
176
+ return mockElement_1;
177
+ },
178
+ removeChild: function () {
179
+ return mockElement_1;
180
+ },
181
+ insertBefore: function () {
182
+ return mockElement_1;
183
+ },
184
+ replaceChild: function () {
185
+ return mockElement_1;
186
+ },
187
+ cloneNode: function () {
188
+ return mockElement_1;
189
+ },
190
+ remove: function () {},
191
+ id: '',
192
+ className: '',
193
+ classList: {
194
+ add: function () {},
195
+ remove: function () {},
196
+ contains: function () {
197
+ return false;
198
+ },
199
+ toggle: function () {
200
+ return false;
201
+ }
202
+ },
203
+ style: {},
204
+ setAttribute: function () {},
205
+ getAttribute: function () {
206
+ return null;
207
+ },
208
+ removeAttribute: function () {},
209
+ hasAttribute: function () {
210
+ return false;
211
+ },
212
+ querySelector: function () {
213
+ return null;
214
+ },
215
+ querySelectorAll: function () {
216
+ return [];
217
+ },
218
+ getElementsByTagName: function () {
219
+ return [];
220
+ },
221
+ getElementsByClassName: function () {
222
+ return [];
223
+ },
224
+ addEventListener: function () {},
225
+ removeEventListener: function () {},
226
+ dispatchEvent: function () {
227
+ return true;
228
+ },
229
+ parentNode: null,
230
+ parentElement: null,
231
+ childNodes: [],
232
+ children: [],
233
+ firstChild: null,
234
+ lastChild: null,
235
+ nextSibling: null,
236
+ previousSibling: null
237
+ };
238
+ var mockDocument = {
239
+ createElement: function () {
240
+ return mockElement_1;
241
+ },
242
+ createElementNS: function () {
243
+ return mockElement_1;
244
+ },
245
+ createTextNode: function (text) {
246
+ return __assign(__assign({}, mockElement_1), {
247
+ nodeValue: text,
248
+ textContent: text
249
+ });
250
+ },
251
+ createDocumentFragment: function () {
252
+ return mockElement_1;
253
+ },
254
+ getElementById: function () {
255
+ return null;
256
+ },
257
+ querySelector: function () {
258
+ return null;
259
+ },
260
+ querySelectorAll: function () {
261
+ return [];
262
+ },
263
+ getElementsByTagName: function () {
264
+ return [];
265
+ },
266
+ getElementsByClassName: function () {
267
+ return [];
268
+ },
269
+ body: mockElement_1,
270
+ head: mockElement_1,
271
+ documentElement: mockElement_1,
272
+ addEventListener: function () {},
273
+ removeEventListener: function () {},
274
+ createEvent: function () {
275
+ return {};
276
+ }
277
+ };
278
+ var mockWindow = {
279
+ document: mockDocument,
280
+ location: {
281
+ href: '',
282
+ origin: '',
283
+ protocol: 'https:',
284
+ host: '',
285
+ hostname: '',
286
+ port: '',
287
+ pathname: '/',
288
+ search: '',
289
+ hash: ''
290
+ },
291
+ navigator: {
292
+ userAgent: '',
293
+ language: 'en-US',
294
+ platform: ''
295
+ },
296
+ addEventListener: function () {},
297
+ removeEventListener: function () {},
298
+ getComputedStyle: function () {
299
+ return {};
300
+ },
301
+ matchMedia: function () {
302
+ return {
303
+ matches: false,
304
+ media: '',
305
+ addListener: function () {},
306
+ removeListener: function () {},
307
+ addEventListener: function () {},
308
+ removeEventListener: function () {},
309
+ dispatchEvent: function () {
310
+ return true;
311
+ }
312
+ };
313
+ },
314
+ requestAnimationFrame: function (cb) {
315
+ return setTimeout(cb, 16);
316
+ },
317
+ cancelAnimationFrame: function (id) {
318
+ return clearTimeout(id);
319
+ },
320
+ setTimeout: setTimeout,
321
+ clearTimeout: clearTimeout,
322
+ setInterval: setInterval,
323
+ clearInterval: clearInterval
324
+ };
325
+ globalThis.window = mockWindow;
326
+ globalThis.document = mockDocument;
327
+ }
328
+
222
329
  var MDXStreamingParser = /** @class */function () {
223
330
  function MDXStreamingParser(components) {
224
331
  // 将组件名称存储在Set中,而不是整个组件对象
@@ -231,22 +338,18 @@ var MDXStreamingParser = /** @class */function () {
231
338
  MDXStreamingParser.prototype.isComponentRegistered = function (name) {
232
339
  return this.registeredComponents.has(name);
233
340
  };
234
- MDXStreamingParser.prototype.parse = function (messageId, input) {
341
+ MDXStreamingParser.prototype.parse = function (_messageId, input) {
235
342
  var e_1, _a, e_2, _b, e_3, _c;
236
- // 获取或创建该消息的解析状态
237
- var state = this.messages.get(messageId);
238
- if (!state) {
239
- state = {
240
- position: 0,
241
- stack: [],
242
- buffer: '',
243
- pendingClosingTag: undefined,
244
- pendingOpeningTag: undefined
245
- };
246
- this.messages.set(messageId, state);
247
- }
343
+ // 每次对完整 content 从零解析,保证流式增量与组件 remount 后全量重解析结果一致
344
+ var state = {
345
+ position: 0,
346
+ stack: [],
347
+ buffer: '',
348
+ pendingClosingTag: undefined,
349
+ pendingOpeningTag: undefined
350
+ };
248
351
  var result = [];
249
- var i = state.position;
352
+ var i = 0;
250
353
  // 如果有暂存的不完整闭合标签,先尝试与当前输入合并处理
251
354
  if (state.pendingClosingTag) {
252
355
  var combinedInput = state.pendingClosingTag + input;
@@ -394,13 +497,11 @@ var MDXStreamingParser = /** @class */function () {
394
497
  // 如果部分标签是栈顶组件名的前缀,说明可能是不完整的闭合标签
395
498
  if (topComponentName.startsWith(partialTag) || partialTag.length === 0) {
396
499
  state.pendingClosingTag = input.slice(i);
397
- this.messages.set(messageId, state);
398
500
  break;
399
501
  }
400
502
  }
401
503
  // 否则,可能是其他不完整的标签,暂存起来
402
504
  state.pendingClosingTag = input.slice(i);
403
- this.messages.set(messageId, state);
404
505
  break;
405
506
  }
406
507
  var tagName = input.slice(i + 2, closeTagEnd);
@@ -446,7 +547,6 @@ var MDXStreamingParser = /** @class */function () {
446
547
  // 暂存起来,不添加到文本内容
447
548
  if (topComponentName.startsWith(tagName) && tagName.length < topComponentName.length) {
448
549
  state.pendingClosingTag = input.slice(i, closeTagEnd + 1);
449
- this.messages.set(messageId, state);
450
550
  break;
451
551
  }
452
552
  }
@@ -494,12 +594,10 @@ var MDXStreamingParser = /** @class */function () {
494
594
  // 找到了部分标签,暂存起来
495
595
  var partialTagEnd = i + tagEndMatch[0].length - 1;
496
596
  state.pendingOpeningTag = input.slice(i, partialTagEnd);
497
- this.messages.set(messageId, state);
498
597
  break;
499
598
  } else {
500
599
  // 标签完全不完整,暂存整个片段
501
600
  state.pendingOpeningTag = input.slice(i);
502
- this.messages.set(messageId, state);
503
601
  break;
504
602
  }
505
603
  } else {
@@ -537,18 +635,12 @@ var MDXStreamingParser = /** @class */function () {
537
635
  props = _k.props,
538
636
  endIndex = _k.endIndex,
539
637
  selfClosing = _k.selfClosing;
540
- // 检测组件是否完整:
541
- // 1. 自闭合组件一定是完整的
542
- // 2. 非自闭合组件:如果有 props 且不在 stack 中(已闭合),则是完整的
543
- // 对于流式渲染,如果 props 为空且不是自闭合,说明组件可能还在解析中
544
- var hasProps = props && Object.keys(props).length > 0;
545
- var isComplete = selfClosing || hasProps;
546
638
  var component = {
547
639
  type: "component",
548
640
  value: componentName,
549
641
  props: props || {},
550
642
  selfClosing: selfClosing,
551
- isComplete: isComplete // 自闭合一定完整,非自闭合取决于是否有 props
643
+ isComplete: selfClosing
552
644
  };
553
645
  if (!selfClosing) {
554
646
  state.stack.push(component);
@@ -616,9 +708,35 @@ var MDXStreamingParser = /** @class */function () {
616
708
  state.stack.forEach(function (component) {
617
709
  component.isComplete = false;
618
710
  });
619
- state.position = i;
620
- // 保存状态
621
- 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
+ }
622
740
  return result;
623
741
  };
624
742
  MDXStreamingParser.prototype.findComponentClose = function (input, startIndex) {
@@ -39473,18 +39591,64 @@ function requireZTouch () {
39473
39591
  var _zTouch = _interopRequireDefault(requireZTouch());
39474
39592
  } (prism$1));
39475
39593
 
39476
- 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 = {
39477
39624
  dark: prism$1.vscDarkPlus,
39478
39625
  light: prism$1.vs
39479
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
+ }
39480
39642
  var CodeHighlight = function (_a) {
39481
39643
  var textContent = _a.textContent,
39482
39644
  _b = _a.language,
39483
39645
  language = _b === void 0 ? "txt" : _b,
39484
- darkMode = _a.darkMode;
39485
- var _c = __read(React.useState(false), 2),
39486
- showCopy = _c[0],
39487
- 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];
39488
39652
  var copyToClipboard = function (text) {
39489
39653
  return __awaiter(void 0, void 0, void 0, function () {
39490
39654
  var textarea;
@@ -39548,6 +39712,11 @@ var CodeHighlight = function (_a) {
39548
39712
  }, Date.now())
39549
39713
  });
39550
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]);
39551
39720
  return /*#__PURE__*/runtime.jsxs("div", {
39552
39721
  style: {
39553
39722
  position: "relative"
@@ -39558,7 +39727,7 @@ var CodeHighlight = function (_a) {
39558
39727
  right: "10px",
39559
39728
  top: "5px",
39560
39729
  zIndex: 1,
39561
- background: darkMode ? "#555" : "#333",
39730
+ background: theme === "light" ? "#e8e8e8" : "#555",
39562
39731
  color: "#fff",
39563
39732
  border: "none",
39564
39733
  padding: "4px 8px",
@@ -39578,7 +39747,7 @@ var CodeHighlight = function (_a) {
39578
39747
  },
39579
39748
  children: showCopy ? "点击复制" : "复制"
39580
39749
  }), /*#__PURE__*/runtime.jsx(SyntaxHighlighter, {
39581
- style: themes.dark,
39750
+ style: syntaxStyle,
39582
39751
  language: language,
39583
39752
  PreTag: "div",
39584
39753
  children: String(textContent).replace(/\n$/, "")
@@ -39704,44 +39873,48 @@ var AudioComponent = function (_a) {
39704
39873
  }), "\u4F60\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E"]
39705
39874
  });
39706
39875
  };
39707
- // 代码组件
39708
- var CodeComponent = function (props) {
39709
- var children = props.children,
39710
- className = props.className;
39711
- props.node;
39712
- var rest = __rest(props, ["children", "className", "node"]);
39713
- var match = /language-(\w+)/.exec(className || "");
39714
- String(children).replace(/\n$/, '');
39715
- var extractText = function (children) {
39716
- return React.Children.toArray(children).reduce(function (acc, child) {
39717
- if (typeof child === 'string') {
39718
- return acc + child;
39719
- } else if (/*#__PURE__*/React.isValidElement(child) && child.props && child.props.children) {
39720
- 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";
39721
39902
  }
39722
- return acc;
39723
- }, '');
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
+ });
39724
39916
  };
39725
- var content = extractText(children);
39726
- // 增强语言检测逻辑,检查内容中是否包含mermaid特征
39727
- var language = match ? match[1] : "txt";
39728
- // 如果内容包含mermaid特征且语言未正确识别,则强制设置为mermaid
39729
- if (!match || match[1] !== "mermaid") {
39730
- var trimmedContent = content.trim();
39731
- 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')) {
39732
- language = "mermaid";
39733
- }
39734
- }
39735
- return language !== "txt" ? /*#__PURE__*/runtime.jsx(CodeHighlight, {
39736
- ...rest,
39737
- language: language,
39738
- textContent: content,
39739
- children: content
39740
- }) : /*#__PURE__*/runtime.jsx("code", {
39741
- className: className,
39742
- ...props,
39743
- children: content
39744
- });
39917
+ return CodeComponent;
39745
39918
  };
39746
39919
  // 段落组件
39747
39920
  var PComponent = function (pProps) {
@@ -39769,16 +39942,23 @@ var PreComponent = function (props) {
39769
39942
  ...props
39770
39943
  });
39771
39944
  };
39772
- var BuiltInComponents = {
39773
- _THINK: Think,
39774
- // _TOOL_CALL: ToolCall,
39775
- pre: PreComponent,
39776
- code: CodeComponent,
39777
- p: PComponent,
39778
- a: AComponent,
39779
- video: VideoComponent,
39780
- audio: AudioComponent
39781
- };
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
+ }
39782
39962
 
39783
39963
  var ErrorBoundary = /** @class */function (_super) {
39784
39964
  __extends(ErrorBoundary, _super);
@@ -43158,8 +43338,6 @@ function decodeNamedCharacterReference(value) {
43158
43338
  // reference to decode was not a semicolon (`&semi;`), we can assume that the
43159
43339
  // matching was not complete.
43160
43340
  if (
43161
- // @ts-expect-error: TypeScript is wrong that `textContent` on elements can
43162
- // yield `null`.
43163
43341
  character.charCodeAt(character.length - 1) === 59 /* `;` */ &&
43164
43342
  value !== 'semi'
43165
43343
  ) {
@@ -43168,8 +43346,6 @@ function decodeNamedCharacterReference(value) {
43168
43346
 
43169
43347
  // If the decoded string is equal to the input, the character reference was
43170
43348
  // not valid.
43171
- // @ts-expect-error: TypeScript is wrong that `textContent` on elements can
43172
- // yield `null`.
43173
43349
  return character === characterReference ? false : character
43174
43350
  }
43175
43351
 
@@ -54898,9 +55074,8 @@ function toResult(value) {
54898
55074
  }
54899
55075
 
54900
55076
  /**
54901
- * @typedef {import('unist').Node} UnistNode
54902
- * @typedef {import('unist').Parent} UnistParent
54903
- * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
55077
+ * @import {Node as UnistNode, Parent as UnistParent} from 'unist'
55078
+ * @import {VisitorResult} from 'unist-util-visit-parents'
54904
55079
  */
54905
55080
 
54906
55081
 
@@ -58500,11 +58675,18 @@ function parseComponentRecursively(allComponentHandlers, item, scope) {
58500
58675
  }))];
58501
58676
  case 1:
58502
58677
  parsedChildren_1 = _a.sent();
58503
- item.children.map(function (item, index) {
58504
- if (item.type === 'text') {
58505
- childrenContent_1 += escapeContentForStream(parsedChildren_1[index].value); // encodeURIComponent(parsedChildren[index]);
58678
+ item.children.forEach(function (childItem, index) {
58679
+ var parsedChild = parsedChildren_1[index];
58680
+ if (!parsedChild) {
58681
+ return;
58682
+ }
58683
+ if (!parsedChild.value) {
58684
+ return;
58685
+ }
58686
+ if (childItem.type === 'text') {
58687
+ childrenContent_1 += escapeContentForStream(parsedChild.value);
58506
58688
  } else {
58507
- childrenContent_1 += parsedChildren_1[index].value;
58689
+ childrenContent_1 += parsedChild.value;
58508
58690
  }
58509
58691
  });
58510
58692
  _a.label = 2;
@@ -59303,46 +59485,110 @@ var FallbackView = /** @class */function (_super) {
59303
59485
  function isEnhancedComponentConfig(value) {
59304
59486
  return typeof value === 'object' && value !== null && 'value' in value && typeof value.value !== 'undefined';
59305
59487
  }
59306
- /**
59307
- * 从组件值中提取实际的组件
59308
- */
59309
59488
  function extractComponent(value) {
59310
59489
  return isEnhancedComponentConfig(value) ? value.value : value;
59311
59490
  }
59312
- /**
59313
- * 将 components 转换为 ComponentHandler 数组
59314
- */
59315
59491
  function convertComponentsToHandlers(components, componentHandlers) {
59316
- return Object.entries(components).filter(function (_a) {
59317
- var _b = __read(_a, 1),
59318
- name = _b[0];
59319
- return !componentHandlers.some(function (handler) {
59320
- return handler.name === name;
59321
- });
59322
- }).map(function (_a) {
59323
- var _b = __read(_a, 2),
59324
- name = _b[0],
59325
- componentValue = _b[1];
59492
+ var e_1, _a;
59493
+ var handlers = [];
59494
+ var _loop_1 = function (name_1, componentValue) {
59495
+ if (!componentValue) return "continue";
59496
+ if (componentHandlers.some(function (handler) {
59497
+ return handler.name === name_1;
59498
+ })) return "continue";
59326
59499
  if (isEnhancedComponentConfig(componentValue)) {
59327
59500
  var config = componentValue;
59328
- return {
59501
+ if (!config.value) {
59502
+ return "continue";
59503
+ }
59504
+ handlers.push({
59329
59505
  component: config.value,
59330
- name: name,
59506
+ name: name_1,
59331
59507
  selfClosing: config.selfClosing !== undefined ? config.selfClosing : isSelfClosingComponent(config.value),
59332
59508
  onRenderStart: config.onRenderStart,
59333
59509
  onRenderProcess: config.onRenderProcess,
59334
59510
  onRenderFinished: config.onRenderFinished,
59335
59511
  loader: config.loader,
59336
59512
  label: config.label
59337
- };
59513
+ });
59338
59514
  } else {
59339
- // 普通模式:直接使用组件
59340
- return {
59515
+ handlers.push({
59341
59516
  component: componentValue,
59342
- name: name,
59517
+ name: name_1,
59343
59518
  selfClosing: isSelfClosingComponent(componentValue)
59344
- };
59519
+ });
59345
59520
  }
59521
+ };
59522
+ try {
59523
+ for (var _b = __values(Object.entries(components)), _c = _b.next(); !_c.done; _c = _b.next()) {
59524
+ var _d = __read(_c.value, 2),
59525
+ name_1 = _d[0],
59526
+ componentValue = _d[1];
59527
+ _loop_1(name_1, componentValue);
59528
+ }
59529
+ } catch (e_1_1) {
59530
+ e_1 = {
59531
+ error: e_1_1
59532
+ };
59533
+ } finally {
59534
+ try {
59535
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
59536
+ } finally {
59537
+ if (e_1) throw e_1.error;
59538
+ }
59539
+ }
59540
+ return handlers;
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);
59346
59592
  });
59347
59593
  }
59348
59594
  function ReactAIRenderer(_a) {
@@ -59357,38 +59603,52 @@ function ReactAIRenderer(_a) {
59357
59603
  componentHandlers = _d === void 0 ? [] : _d,
59358
59604
  useGithubStyles = _a.useGithubStyles,
59359
59605
  mdxLayoutClassName = _a.mdxLayoutClassName,
59360
- mdxLayoutStyle = _a.mdxLayoutStyle;
59361
- // 检查是否在浏览器环境中
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];
59613
+ var fallbackErrorRef = React.useRef({
59614
+ hasError: false
59615
+ });
59616
+ var completedComponentsCacheRef = React.useRef(new Map());
59617
+ var parserRef = React.useRef(null);
59618
+ var lastLoaderSigRef = React.useRef('');
59362
59619
  var isBrowser = typeof window !== 'undefined';
59363
- // 在服务端直接返回空内容,避免使用 hooks
59364
- if (!isBrowser) {
59365
- return /*#__PURE__*/runtime.jsx(React.Fragment, {
59366
- children: null
59367
- });
59368
- }
59369
59620
  content = content || children || '';
59370
- // 构建 allComponents:从增强配置中提取实际的组件
59371
- var normalizedComponents = components ? Object.fromEntries(Object.entries(components).map(function (_a) {
59621
+ var normalizedComponents = components ? Object.fromEntries(Object.entries(components).filter(function (_a) {
59622
+ var _b = __read(_a, 2);
59623
+ _b[0];
59624
+ var value = _b[1];
59625
+ return value != null;
59626
+ }).map(function (_a) {
59372
59627
  var _b = __read(_a, 2),
59373
59628
  name = _b[0],
59374
59629
  value = _b[1];
59375
59630
  return [name, extractComponent(value)];
59376
59631
  })) : {};
59377
- var allComponents = __assign(__assign({}, BuiltInComponents), normalizedComponents);
59378
- // 构建 allComponentHandlers:支持增强模式
59632
+ // 根据 theme / codeTheme 创建带主题配置的内置组件
59633
+ var themedBuiltInComponents = React.useMemo(function () {
59634
+ return createBuiltInComponents(theme, codeTheme);
59635
+ }, [theme, codeTheme]);
59636
+ var allComponents = __assign(__assign({}, themedBuiltInComponents), normalizedComponents);
59379
59637
  var allComponentHandlers = __spreadArray(__spreadArray([], __read(components ? convertComponentsToHandlers(components, componentHandlers) : []), false), __read(componentHandlers), false);
59380
- var _e = __read(React.useState(null), 2),
59381
- component = _e[0],
59382
- setComponent = _e[1];
59383
- // 用于跟踪 FallbackView 的错误状态
59384
- var fallbackErrorRef = React.useRef({
59385
- hasError: false
59386
- });
59387
- // 用于缓存已完成的组件,避免重复渲染
59388
- var completedComponentsCacheRef = React.useRef(new Map());
59389
- var parser = new MDXStreamingParser(allComponentHandlers);
59638
+ if (!parserRef.current) {
59639
+ parserRef.current = new MDXStreamingParser(allComponentHandlers);
59640
+ }
59641
+ var parser = parserRef.current;
59390
59642
  var mdxContent = content || '';
59391
- // 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]);
59392
59652
  var handleFallbackErrorChange = function (hasError, error) {
59393
59653
  fallbackErrorRef.current = {
59394
59654
  hasError: hasError,
@@ -59396,17 +59656,33 @@ function ReactAIRenderer(_a) {
59396
59656
  };
59397
59657
  };
59398
59658
  React.useEffect(function () {
59659
+ if (!isBrowser) return;
59660
+ var cancelled = false;
59399
59661
  var parseMDX = function () {
59400
59662
  return __awaiter(_this, void 0, void 0, function () {
59401
- 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;
59402
- var e_1, _b;
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;
59664
+ var e_2, _b;
59403
59665
  return __generator(this, function (_c) {
59404
59666
  switch (_c.label) {
59405
59667
  case 0:
59406
- ThinkComponent = null;
59407
- ResultComponent = null;
59408
59668
  protectedContent = protectSpecialSyntax(mdxContent);
59409
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;
59410
59686
  if (!thinkContent) return [3 /*break*/, 2];
59411
59687
  return [4 /*yield*/, renderMdx(thinkContent, scope, allComponents)];
59412
59688
  case 1:
@@ -59415,7 +59691,6 @@ function ReactAIRenderer(_a) {
59415
59691
  case 2:
59416
59692
  parsedData = [];
59417
59693
  if (!resultContent) return [3 /*break*/, 8];
59418
- resultContent = fixMDXContent(resultContent);
59419
59694
  parsedData = parser.parse('magic', resultContent);
59420
59695
  return [4 /*yield*/, Promise.all(parsedData.map(function (item) {
59421
59696
  return parseComponentRecursively(allComponentHandlers, item, scope);
@@ -59431,25 +59706,24 @@ function ReactAIRenderer(_a) {
59431
59706
  if (indexMatch) {
59432
59707
  index = parseInt(indexMatch[1], 10);
59433
59708
  if (index >= currentComponentCount) {
59434
- // 如果索引超出当前组件数量,删除缓存
59435
59709
  completedComponentsCacheRef.current.delete(key);
59436
59710
  }
59437
59711
  }
59438
59712
  }
59439
- } catch (e_1_1) {
59440
- e_1 = {
59441
- error: e_1_1
59713
+ } catch (e_2_1) {
59714
+ e_2 = {
59715
+ error: e_2_1
59442
59716
  };
59443
59717
  } finally {
59444
59718
  try {
59445
59719
  if (cacheKeys_1_1 && !cacheKeys_1_1.done && (_b = cacheKeys_1.return)) _b.call(cacheKeys_1);
59446
59720
  } finally {
59447
- if (e_1) throw e_1.error;
59721
+ if (e_2) throw e_2.error;
59448
59722
  }
59449
59723
  }
59450
59724
  finalComponent = [];
59451
59725
  fallbackComponent = [];
59452
- _loop_1 = function (i) {
59726
+ _loop_3 = function (i) {
59453
59727
  var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey;
59454
59728
  return __generator(this, function (_d) {
59455
59729
  switch (_d.label) {
@@ -59463,10 +59737,10 @@ function ReactAIRenderer(_a) {
59463
59737
  case 1:
59464
59738
  _result = _d.sent();
59465
59739
  finalComponent.push(_result);
59466
- return [3 /*break*/, 11];
59740
+ return [3 /*break*/, 12];
59467
59741
  case 2:
59468
59742
  componentNameMatch = item.value.match(/<([A-Z][A-Za-z0-9]*)/);
59469
- if (!componentNameMatch) return [3 /*break*/, 9];
59743
+ if (!componentNameMatch) return [3 /*break*/, 10];
59470
59744
  componentName_1 = componentNameMatch[1];
59471
59745
  componentHandler = allComponentHandlers.find(function (c) {
59472
59746
  return c.name === componentName_1;
@@ -59483,15 +59757,12 @@ function ReactAIRenderer(_a) {
59483
59757
  if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/, 6];
59484
59758
  cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
59485
59759
  if (!completedComponentsCacheRef.current.has(cacheKey)) return [3 /*break*/, 3];
59486
- // 使用缓存的组件
59487
59760
  _result = completedComponentsCacheRef.current.get(cacheKey);
59488
59761
  return [3 /*break*/, 5];
59489
59762
  case 3:
59490
59763
  return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59491
59764
  case 4:
59492
- // 缓存不存在,调用 renderMdx 并存入缓存
59493
59765
  _result = _d.sent();
59494
- // 为组件设置 key,确保 React 能正确识别
59495
59766
  if (/*#__PURE__*/React.isValidElement(_result)) {
59496
59767
  _result = /*#__PURE__*/React.cloneElement(_result, {
59497
59768
  key: cacheKey
@@ -59501,30 +59772,30 @@ function ReactAIRenderer(_a) {
59501
59772
  key: cacheKey
59502
59773
  }, _result);
59503
59774
  }
59504
- // 存入缓存
59505
59775
  completedComponentsCacheRef.current.set(cacheKey, _result);
59506
59776
  _d.label = 5;
59507
59777
  case 5:
59508
59778
  finalComponent.push(_result);
59509
- return [3 /*break*/, 8];
59779
+ return [3 /*break*/, 9];
59510
59780
  case 6:
59511
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59512
- case 7:
59513
- // 组件未完成,正常渲染
59514
- _result = _d.sent();
59781
+ if (!placeholderForFallback) return [3 /*break*/, 7];
59515
59782
  finalComponent.push(placeholderForFallback);
59516
- _d.label = 8;
59783
+ return [3 /*break*/, 9];
59784
+ case 7:
59785
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59517
59786
  case 8:
59518
- return [3 /*break*/, 11];
59787
+ _result = _d.sent();
59788
+ finalComponent.push(_result);
59789
+ _d.label = 9;
59519
59790
  case 9:
59520
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59791
+ return [3 /*break*/, 12];
59521
59792
  case 10:
59522
- // 没有匹配到组件名,正常渲染
59793
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59794
+ case 11:
59523
59795
  _result = _d.sent();
59524
59796
  finalComponent.push(_result);
59525
- _d.label = 11;
59526
- case 11:
59527
- // fallbackComponent 应该是 finalComponent 的前 i 个元素 + 当前 item 的 loader
59797
+ _d.label = 12;
59798
+ case 12:
59528
59799
  fallbackComponent.length = 0;
59529
59800
  fallbackComponent.push.apply(fallbackComponent, __spreadArray([], __read(finalComponent.slice(0, i)), false));
59530
59801
  if (placeholderForFallback) {
@@ -59538,7 +59809,7 @@ function ReactAIRenderer(_a) {
59538
59809
  _c.label = 4;
59539
59810
  case 4:
59540
59811
  if (!(i < parsedComponents.length)) return [3 /*break*/, 7];
59541
- return [5 /*yield**/, _loop_1(i)];
59812
+ return [5 /*yield**/, _loop_3(i)];
59542
59813
  case 5:
59543
59814
  _c.sent();
59544
59815
  _c.label = 6;
@@ -59561,13 +59832,13 @@ function ReactAIRenderer(_a) {
59561
59832
  MDXComponent = /*#__PURE__*/runtime.jsxs(React.Fragment, {
59562
59833
  children: [ThinkComponent, ResultComponent]
59563
59834
  });
59835
+ if (cancelled) return [2 /*return*/];
59564
59836
  if (!fallbackErrorRef.current.hasError) {
59565
59837
  setComponent(MDXComponent);
59566
59838
  } else {
59567
59839
  parsedDataLength = parsedData.length;
59568
59840
  if (parsedDataLength > 0) {
59569
59841
  lastItem = parsedData[parsedDataLength - 1];
59570
- // 如果最后一个组件是完整的,强制更新
59571
59842
  if (lastItem.isComplete === true) {
59572
59843
  setComponent(MDXComponent);
59573
59844
  } else if (lastItem.type === 'text') {
@@ -59581,7 +59852,13 @@ function ReactAIRenderer(_a) {
59581
59852
  });
59582
59853
  };
59583
59854
  parseMDX();
59584
- }, [content]);
59855
+ return function () {
59856
+ cancelled = true;
59857
+ };
59858
+ }, [content, theme, codeTheme]);
59859
+ if (!isBrowser) {
59860
+ return null;
59861
+ }
59585
59862
  return /*#__PURE__*/runtime.jsx(ErrorBoundary, {
59586
59863
  content: content,
59587
59864
  children: /*#__PURE__*/runtime.jsx(React.Fragment, {