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.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import * as React from 'react';
2
- import React__default, { useState, useEffect, useMemo, useRef, useCallback } from 'react';
2
+ import React__default, { useState, useMemo, useEffect, useRef, useCallback } from 'react';
3
3
  import * as runtime from 'react/jsx-runtime';
4
4
  import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
5
5
  import RemarkMath from 'remark-math';
@@ -9,58 +9,6 @@ import { run, compile } from '@mdx-js/mdx';
9
9
  import RehypeKatex from 'rehype-katex';
10
10
  import RehypeHighlight from 'rehype-highlight';
11
11
 
12
- // SSR 兼容性 polyfill
13
- // 这个文件确保在服务端渲染时不会因为访问 document 而报错
14
- // 在模块加载时就设置全局保护
15
- if (typeof globalThis !== 'undefined' && globalThis.document === undefined) {
16
- // 为 SSR 环境创建一个模拟的 document 对象
17
- var mockElement_1 = {
18
- innerHTML: '',
19
- textContent: '',
20
- appendChild: function () {
21
- return mockElement_1;
22
- },
23
- removeChild: function () {
24
- return mockElement_1;
25
- },
26
- remove: function () {},
27
- id: '',
28
- className: '',
29
- setAttribute: function () {},
30
- getAttribute: function () {
31
- return null;
32
- },
33
- removeAttribute: function () {},
34
- querySelector: function () {
35
- return null;
36
- },
37
- querySelectorAll: function () {
38
- return [];
39
- }
40
- };
41
- // 创建模拟的 document 对象
42
- var mockDocument = {
43
- createElement: function () {
44
- return mockElement_1;
45
- },
46
- getElementById: function () {
47
- return null;
48
- },
49
- querySelector: function () {
50
- return null;
51
- },
52
- querySelectorAll: function () {
53
- return [];
54
- },
55
- body: mockElement_1,
56
- head: mockElement_1,
57
- addEventListener: function () {},
58
- removeEventListener: function () {}
59
- };
60
- // 在 SSR 环境中提供全局的 document
61
- globalThis.document = mockDocument;
62
- }
63
-
64
12
  /******************************************************************************
65
13
  Copyright (c) Microsoft Corporation.
66
14
 
@@ -197,6 +145,165 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
197
145
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
198
146
  };
199
147
 
148
+ if (typeof globalThis !== 'undefined' && typeof globalThis.window === 'undefined') {
149
+ var mockElement_1 = {
150
+ innerHTML: '',
151
+ textContent: '',
152
+ nodeValue: '',
153
+ appendChild: function () {
154
+ return mockElement_1;
155
+ },
156
+ removeChild: function () {
157
+ return mockElement_1;
158
+ },
159
+ insertBefore: function () {
160
+ return mockElement_1;
161
+ },
162
+ replaceChild: function () {
163
+ return mockElement_1;
164
+ },
165
+ cloneNode: function () {
166
+ return mockElement_1;
167
+ },
168
+ remove: function () {},
169
+ id: '',
170
+ className: '',
171
+ classList: {
172
+ add: function () {},
173
+ remove: function () {},
174
+ contains: function () {
175
+ return false;
176
+ },
177
+ toggle: function () {
178
+ return false;
179
+ }
180
+ },
181
+ style: {},
182
+ setAttribute: function () {},
183
+ getAttribute: function () {
184
+ return null;
185
+ },
186
+ removeAttribute: function () {},
187
+ hasAttribute: function () {
188
+ return false;
189
+ },
190
+ querySelector: function () {
191
+ return null;
192
+ },
193
+ querySelectorAll: function () {
194
+ return [];
195
+ },
196
+ getElementsByTagName: function () {
197
+ return [];
198
+ },
199
+ getElementsByClassName: function () {
200
+ return [];
201
+ },
202
+ addEventListener: function () {},
203
+ removeEventListener: function () {},
204
+ dispatchEvent: function () {
205
+ return true;
206
+ },
207
+ parentNode: null,
208
+ parentElement: null,
209
+ childNodes: [],
210
+ children: [],
211
+ firstChild: null,
212
+ lastChild: null,
213
+ nextSibling: null,
214
+ previousSibling: null
215
+ };
216
+ var mockDocument = {
217
+ createElement: function () {
218
+ return mockElement_1;
219
+ },
220
+ createElementNS: function () {
221
+ return mockElement_1;
222
+ },
223
+ createTextNode: function (text) {
224
+ return __assign(__assign({}, mockElement_1), {
225
+ nodeValue: text,
226
+ textContent: text
227
+ });
228
+ },
229
+ createDocumentFragment: function () {
230
+ return mockElement_1;
231
+ },
232
+ getElementById: function () {
233
+ return null;
234
+ },
235
+ querySelector: function () {
236
+ return null;
237
+ },
238
+ querySelectorAll: function () {
239
+ return [];
240
+ },
241
+ getElementsByTagName: function () {
242
+ return [];
243
+ },
244
+ getElementsByClassName: function () {
245
+ return [];
246
+ },
247
+ body: mockElement_1,
248
+ head: mockElement_1,
249
+ documentElement: mockElement_1,
250
+ addEventListener: function () {},
251
+ removeEventListener: function () {},
252
+ createEvent: function () {
253
+ return {};
254
+ }
255
+ };
256
+ var mockWindow = {
257
+ document: mockDocument,
258
+ location: {
259
+ href: '',
260
+ origin: '',
261
+ protocol: 'https:',
262
+ host: '',
263
+ hostname: '',
264
+ port: '',
265
+ pathname: '/',
266
+ search: '',
267
+ hash: ''
268
+ },
269
+ navigator: {
270
+ userAgent: '',
271
+ language: 'en-US',
272
+ platform: ''
273
+ },
274
+ addEventListener: function () {},
275
+ removeEventListener: function () {},
276
+ getComputedStyle: function () {
277
+ return {};
278
+ },
279
+ matchMedia: function () {
280
+ return {
281
+ matches: false,
282
+ media: '',
283
+ addListener: function () {},
284
+ removeListener: function () {},
285
+ addEventListener: function () {},
286
+ removeEventListener: function () {},
287
+ dispatchEvent: function () {
288
+ return true;
289
+ }
290
+ };
291
+ },
292
+ requestAnimationFrame: function (cb) {
293
+ return setTimeout(cb, 16);
294
+ },
295
+ cancelAnimationFrame: function (id) {
296
+ return clearTimeout(id);
297
+ },
298
+ setTimeout: setTimeout,
299
+ clearTimeout: clearTimeout,
300
+ setInterval: setInterval,
301
+ clearInterval: clearInterval
302
+ };
303
+ globalThis.window = mockWindow;
304
+ globalThis.document = mockDocument;
305
+ }
306
+
200
307
  var MDXStreamingParser = /** @class */function () {
201
308
  function MDXStreamingParser(components) {
202
309
  // 将组件名称存储在Set中,而不是整个组件对象
@@ -209,22 +316,18 @@ var MDXStreamingParser = /** @class */function () {
209
316
  MDXStreamingParser.prototype.isComponentRegistered = function (name) {
210
317
  return this.registeredComponents.has(name);
211
318
  };
212
- MDXStreamingParser.prototype.parse = function (messageId, input) {
319
+ MDXStreamingParser.prototype.parse = function (_messageId, input) {
213
320
  var e_1, _a, e_2, _b, e_3, _c;
214
- // 获取或创建该消息的解析状态
215
- var state = this.messages.get(messageId);
216
- if (!state) {
217
- state = {
218
- position: 0,
219
- stack: [],
220
- buffer: '',
221
- pendingClosingTag: undefined,
222
- pendingOpeningTag: undefined
223
- };
224
- this.messages.set(messageId, state);
225
- }
321
+ // 每次对完整 content 从零解析,保证流式增量与组件 remount 后全量重解析结果一致
322
+ var state = {
323
+ position: 0,
324
+ stack: [],
325
+ buffer: '',
326
+ pendingClosingTag: undefined,
327
+ pendingOpeningTag: undefined
328
+ };
226
329
  var result = [];
227
- var i = state.position;
330
+ var i = 0;
228
331
  // 如果有暂存的不完整闭合标签,先尝试与当前输入合并处理
229
332
  if (state.pendingClosingTag) {
230
333
  var combinedInput = state.pendingClosingTag + input;
@@ -372,13 +475,11 @@ var MDXStreamingParser = /** @class */function () {
372
475
  // 如果部分标签是栈顶组件名的前缀,说明可能是不完整的闭合标签
373
476
  if (topComponentName.startsWith(partialTag) || partialTag.length === 0) {
374
477
  state.pendingClosingTag = input.slice(i);
375
- this.messages.set(messageId, state);
376
478
  break;
377
479
  }
378
480
  }
379
481
  // 否则,可能是其他不完整的标签,暂存起来
380
482
  state.pendingClosingTag = input.slice(i);
381
- this.messages.set(messageId, state);
382
483
  break;
383
484
  }
384
485
  var tagName = input.slice(i + 2, closeTagEnd);
@@ -424,7 +525,6 @@ var MDXStreamingParser = /** @class */function () {
424
525
  // 暂存起来,不添加到文本内容
425
526
  if (topComponentName.startsWith(tagName) && tagName.length < topComponentName.length) {
426
527
  state.pendingClosingTag = input.slice(i, closeTagEnd + 1);
427
- this.messages.set(messageId, state);
428
528
  break;
429
529
  }
430
530
  }
@@ -472,12 +572,10 @@ var MDXStreamingParser = /** @class */function () {
472
572
  // 找到了部分标签,暂存起来
473
573
  var partialTagEnd = i + tagEndMatch[0].length - 1;
474
574
  state.pendingOpeningTag = input.slice(i, partialTagEnd);
475
- this.messages.set(messageId, state);
476
575
  break;
477
576
  } else {
478
577
  // 标签完全不完整,暂存整个片段
479
578
  state.pendingOpeningTag = input.slice(i);
480
- this.messages.set(messageId, state);
481
579
  break;
482
580
  }
483
581
  } else {
@@ -515,18 +613,12 @@ var MDXStreamingParser = /** @class */function () {
515
613
  props = _k.props,
516
614
  endIndex = _k.endIndex,
517
615
  selfClosing = _k.selfClosing;
518
- // 检测组件是否完整:
519
- // 1. 自闭合组件一定是完整的
520
- // 2. 非自闭合组件:如果有 props 且不在 stack 中(已闭合),则是完整的
521
- // 对于流式渲染,如果 props 为空且不是自闭合,说明组件可能还在解析中
522
- var hasProps = props && Object.keys(props).length > 0;
523
- var isComplete = selfClosing || hasProps;
524
616
  var component = {
525
617
  type: "component",
526
618
  value: componentName,
527
619
  props: props || {},
528
620
  selfClosing: selfClosing,
529
- isComplete: isComplete // 自闭合一定完整,非自闭合取决于是否有 props
621
+ isComplete: selfClosing
530
622
  };
531
623
  if (!selfClosing) {
532
624
  state.stack.push(component);
@@ -594,9 +686,35 @@ var MDXStreamingParser = /** @class */function () {
594
686
  state.stack.forEach(function (component) {
595
687
  component.isComplete = false;
596
688
  });
597
- state.position = i;
598
- // 保存状态
599
- this.messages.set(messageId, state);
689
+ // 流式未闭合的根组件可能只在 stack 中,补进 result 供 loader 渲染
690
+ if (state.stack.length > 0) {
691
+ var root_1 = state.stack[0];
692
+ var already = result.some(function (item) {
693
+ return item.type === 'component' && item.value === root_1.value;
694
+ });
695
+ if (!already) {
696
+ result.push(root_1);
697
+ }
698
+ }
699
+ // 流式未闭合的开始标签(尚未入 stack)也产出占位组件,供 loader 渲染
700
+ if (state.pendingOpeningTag) {
701
+ var tagMatch = state.pendingOpeningTag.match(/^<([A-Z][A-Za-z0-9]*)/);
702
+ if (tagMatch && this.isComponentRegistered(tagMatch[1])) {
703
+ var name_1 = tagMatch[1];
704
+ var already = result.some(function (item) {
705
+ return item.type === 'component' && item.value === name_1;
706
+ });
707
+ if (!already) {
708
+ result.push({
709
+ type: 'component',
710
+ value: name_1,
711
+ props: {},
712
+ selfClosing: false,
713
+ isComplete: false
714
+ });
715
+ }
716
+ }
717
+ }
600
718
  return result;
601
719
  };
602
720
  MDXStreamingParser.prototype.findComponentClose = function (input, startIndex) {
@@ -39451,18 +39569,64 @@ function requireZTouch () {
39451
39569
  var _zTouch = _interopRequireDefault(requireZTouch());
39452
39570
  } (prism$1));
39453
39571
 
39454
- var themes = {
39572
+ var CODE_THEME_MAP = {
39573
+ github: "ghcolors",
39574
+ atom: "atom-dark",
39575
+ "atom-dark": "atom-dark",
39576
+ "atom-light": "atom-light",
39577
+ dracula: "dracula",
39578
+ "one-dark": "one-dark",
39579
+ "one-light": "one-light",
39580
+ nord: "nord",
39581
+ "material-dark": "material-dark",
39582
+ "material-light": "material-light",
39583
+ "solarized-light": "solarizedlight",
39584
+ "solarized-dark": "solarized-dark-atom",
39585
+ okaidia: "okaidia",
39586
+ tomorrow: "tomorrow",
39587
+ coy: "coy",
39588
+ "vsc-dark-plus": "vsc-dark-plus",
39589
+ vs: "vs",
39590
+ ghcolors: "ghcolors",
39591
+ prism: "prism",
39592
+ twilight: "twilight",
39593
+ "duotone-dark": "duotone-dark",
39594
+ "duotone-light": "duotone-light",
39595
+ "night-owl": "night-owl",
39596
+ darcula: "darcula",
39597
+ "gruvbox-dark": "gruvbox-dark",
39598
+ "gruvbox-light": "gruvbox-light"
39599
+ };
39600
+ // 预置的默认主题
39601
+ var DEFAULT_THEMES = {
39455
39602
  dark: prism$1.vscDarkPlus,
39456
39603
  light: prism$1.vs
39457
39604
  };
39605
+ /**
39606
+ * 根据 codeTheme 名称加载对应的 prism 样式
39607
+ */
39608
+ function loadCodeStyle(codeTheme) {
39609
+ // 先查映射表
39610
+ var moduleName = CODE_THEME_MAP[codeTheme] || codeTheme;
39611
+ try {
39612
+ // 使用 require 动态加载 prism 样式模块
39613
+ var styles = require("react-syntax-highlighter/dist/cjs/styles/prism/".concat(moduleName));
39614
+ return styles.default || styles;
39615
+ } catch (_a) {
39616
+ // 加载失败时回退到默认暗色主题
39617
+ return prism$1.vscDarkPlus;
39618
+ }
39619
+ }
39458
39620
  var CodeHighlight = function (_a) {
39459
39621
  var textContent = _a.textContent,
39460
39622
  _b = _a.language,
39461
39623
  language = _b === void 0 ? "txt" : _b,
39462
- darkMode = _a.darkMode;
39463
- var _c = __read(useState(false), 2),
39464
- showCopy = _c[0],
39465
- setShowCopy = _c[1];
39624
+ _c = _a.theme,
39625
+ theme = _c === void 0 ? "dark" : _c,
39626
+ codeTheme = _a.codeTheme;
39627
+ var _d = __read(useState(false), 2),
39628
+ showCopy = _d[0],
39629
+ setShowCopy = _d[1];
39466
39630
  var copyToClipboard = function (text) {
39467
39631
  return __awaiter(void 0, void 0, void 0, function () {
39468
39632
  var textarea;
@@ -39526,6 +39690,11 @@ var CodeHighlight = function (_a) {
39526
39690
  }, Date.now())
39527
39691
  });
39528
39692
  }
39693
+ // 根据 codeTheme / theme 计算最终的代码高亮样式
39694
+ var syntaxStyle = useMemo(function () {
39695
+ if (codeTheme) return loadCodeStyle(codeTheme);
39696
+ return DEFAULT_THEMES[theme] || DEFAULT_THEMES.dark;
39697
+ }, [codeTheme, theme]);
39529
39698
  return /*#__PURE__*/jsxs("div", {
39530
39699
  style: {
39531
39700
  position: "relative"
@@ -39536,7 +39705,7 @@ var CodeHighlight = function (_a) {
39536
39705
  right: "10px",
39537
39706
  top: "5px",
39538
39707
  zIndex: 1,
39539
- background: darkMode ? "#555" : "#333",
39708
+ background: theme === "light" ? "#e8e8e8" : "#555",
39540
39709
  color: "#fff",
39541
39710
  border: "none",
39542
39711
  padding: "4px 8px",
@@ -39556,7 +39725,7 @@ var CodeHighlight = function (_a) {
39556
39725
  },
39557
39726
  children: showCopy ? "点击复制" : "复制"
39558
39727
  }), /*#__PURE__*/jsx(SyntaxHighlighter, {
39559
- style: themes.dark,
39728
+ style: syntaxStyle,
39560
39729
  language: language,
39561
39730
  PreTag: "div",
39562
39731
  children: String(textContent).replace(/\n$/, "")
@@ -39682,44 +39851,48 @@ var AudioComponent = function (_a) {
39682
39851
  }), "\u4F60\u7684\u6D4F\u89C8\u5668\u4E0D\u652F\u6301 audio \u6807\u7B7E"]
39683
39852
  });
39684
39853
  };
39685
- // 代码组件
39686
- var CodeComponent = function (props) {
39687
- var children = props.children,
39688
- className = props.className;
39689
- props.node;
39690
- var rest = __rest(props, ["children", "className", "node"]);
39691
- var match = /language-(\w+)/.exec(className || "");
39692
- String(children).replace(/\n$/, '');
39693
- var extractText = function (children) {
39694
- return React__default.Children.toArray(children).reduce(function (acc, child) {
39695
- if (typeof child === 'string') {
39696
- return acc + child;
39697
- } else if (/*#__PURE__*/React__default.isValidElement(child) && child.props && child.props.children) {
39698
- return acc + extractText(child.props.children);
39854
+ // 代码组件(支持 theme 和 codeTheme 透传)
39855
+ var createCodeComponent = function (theme, codeTheme) {
39856
+ var CodeComponent = function (props) {
39857
+ var children = props.children,
39858
+ className = props.className;
39859
+ props.node;
39860
+ var rest = __rest(props, ["children", "className", "node"]);
39861
+ var match = /language-(\w+)/.exec(className || "");
39862
+ var extractText = function (children) {
39863
+ return React__default.Children.toArray(children).reduce(function (acc, child) {
39864
+ if (typeof child === 'string') {
39865
+ return acc + child;
39866
+ } else if (/*#__PURE__*/React__default.isValidElement(child) && child.props && child.props.children) {
39867
+ return acc + extractText(child.props.children);
39868
+ }
39869
+ return acc;
39870
+ }, '');
39871
+ };
39872
+ var content = extractText(children);
39873
+ // 增强语言检测逻辑,检查内容中是否包含mermaid特征
39874
+ var language = match ? match[1] : "txt";
39875
+ // 如果内容包含mermaid特征且语言未正确识别,则强制设置为mermaid
39876
+ if (!match || match[1] !== "mermaid") {
39877
+ var trimmedContent = content.trim();
39878
+ 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')) {
39879
+ language = "mermaid";
39699
39880
  }
39700
- return acc;
39701
- }, '');
39881
+ }
39882
+ return language !== "txt" ? /*#__PURE__*/jsx(CodeHighlight, {
39883
+ ...rest,
39884
+ language: language,
39885
+ textContent: content,
39886
+ theme: theme,
39887
+ codeTheme: codeTheme,
39888
+ children: content
39889
+ }) : /*#__PURE__*/jsx("code", {
39890
+ className: className,
39891
+ ...props,
39892
+ children: content
39893
+ });
39702
39894
  };
39703
- var content = extractText(children);
39704
- // 增强语言检测逻辑,检查内容中是否包含mermaid特征
39705
- var language = match ? match[1] : "txt";
39706
- // 如果内容包含mermaid特征且语言未正确识别,则强制设置为mermaid
39707
- if (!match || match[1] !== "mermaid") {
39708
- var trimmedContent = content.trim();
39709
- 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')) {
39710
- language = "mermaid";
39711
- }
39712
- }
39713
- return language !== "txt" ? /*#__PURE__*/jsx(CodeHighlight, {
39714
- ...rest,
39715
- language: language,
39716
- textContent: content,
39717
- children: content
39718
- }) : /*#__PURE__*/jsx("code", {
39719
- className: className,
39720
- ...props,
39721
- children: content
39722
- });
39895
+ return CodeComponent;
39723
39896
  };
39724
39897
  // 段落组件
39725
39898
  var PComponent = function (pProps) {
@@ -39747,16 +39920,23 @@ var PreComponent = function (props) {
39747
39920
  ...props
39748
39921
  });
39749
39922
  };
39750
- var BuiltInComponents = {
39751
- _THINK: Think,
39752
- // _TOOL_CALL: ToolCall,
39753
- pre: PreComponent,
39754
- code: CodeComponent,
39755
- p: PComponent,
39756
- a: AComponent,
39757
- video: VideoComponent,
39758
- audio: AudioComponent
39759
- };
39923
+ /**
39924
+ * 创建带主题配置的内置组件集合
39925
+ * @param theme 整体主题 (dark / light / 自定义)
39926
+ * @param codeTheme 代码语法主题 (github / atom / 自定义)
39927
+ */
39928
+ function createBuiltInComponents(theme, codeTheme) {
39929
+ var themedCode = createCodeComponent(theme, codeTheme);
39930
+ return {
39931
+ _THINK: Think,
39932
+ pre: PreComponent,
39933
+ code: themedCode,
39934
+ p: PComponent,
39935
+ a: AComponent,
39936
+ video: VideoComponent,
39937
+ audio: AudioComponent
39938
+ };
39939
+ }
39760
39940
 
39761
39941
  var ErrorBoundary = /** @class */function (_super) {
39762
39942
  __extends(ErrorBoundary, _super);
@@ -43136,8 +43316,6 @@ function decodeNamedCharacterReference(value) {
43136
43316
  // reference to decode was not a semicolon (`&semi;`), we can assume that the
43137
43317
  // matching was not complete.
43138
43318
  if (
43139
- // @ts-expect-error: TypeScript is wrong that `textContent` on elements can
43140
- // yield `null`.
43141
43319
  character.charCodeAt(character.length - 1) === 59 /* `;` */ &&
43142
43320
  value !== 'semi'
43143
43321
  ) {
@@ -43146,8 +43324,6 @@ function decodeNamedCharacterReference(value) {
43146
43324
 
43147
43325
  // If the decoded string is equal to the input, the character reference was
43148
43326
  // not valid.
43149
- // @ts-expect-error: TypeScript is wrong that `textContent` on elements can
43150
- // yield `null`.
43151
43327
  return character === characterReference ? false : character
43152
43328
  }
43153
43329
 
@@ -54876,9 +55052,8 @@ function toResult(value) {
54876
55052
  }
54877
55053
 
54878
55054
  /**
54879
- * @typedef {import('unist').Node} UnistNode
54880
- * @typedef {import('unist').Parent} UnistParent
54881
- * @typedef {import('unist-util-visit-parents').VisitorResult} VisitorResult
55055
+ * @import {Node as UnistNode, Parent as UnistParent} from 'unist'
55056
+ * @import {VisitorResult} from 'unist-util-visit-parents'
54882
55057
  */
54883
55058
 
54884
55059
 
@@ -58478,11 +58653,18 @@ function parseComponentRecursively(allComponentHandlers, item, scope) {
58478
58653
  }))];
58479
58654
  case 1:
58480
58655
  parsedChildren_1 = _a.sent();
58481
- item.children.map(function (item, index) {
58482
- if (item.type === 'text') {
58483
- childrenContent_1 += escapeContentForStream(parsedChildren_1[index].value); // encodeURIComponent(parsedChildren[index]);
58656
+ item.children.forEach(function (childItem, index) {
58657
+ var parsedChild = parsedChildren_1[index];
58658
+ if (!parsedChild) {
58659
+ return;
58660
+ }
58661
+ if (!parsedChild.value) {
58662
+ return;
58663
+ }
58664
+ if (childItem.type === 'text') {
58665
+ childrenContent_1 += escapeContentForStream(parsedChild.value);
58484
58666
  } else {
58485
- childrenContent_1 += parsedChildren_1[index].value;
58667
+ childrenContent_1 += parsedChild.value;
58486
58668
  }
58487
58669
  });
58488
58670
  _a.label = 2;
@@ -59281,46 +59463,110 @@ var FallbackView = /** @class */function (_super) {
59281
59463
  function isEnhancedComponentConfig(value) {
59282
59464
  return typeof value === 'object' && value !== null && 'value' in value && typeof value.value !== 'undefined';
59283
59465
  }
59284
- /**
59285
- * 从组件值中提取实际的组件
59286
- */
59287
59466
  function extractComponent(value) {
59288
59467
  return isEnhancedComponentConfig(value) ? value.value : value;
59289
59468
  }
59290
- /**
59291
- * 将 components 转换为 ComponentHandler 数组
59292
- */
59293
59469
  function convertComponentsToHandlers(components, componentHandlers) {
59294
- return Object.entries(components).filter(function (_a) {
59295
- var _b = __read(_a, 1),
59296
- name = _b[0];
59297
- return !componentHandlers.some(function (handler) {
59298
- return handler.name === name;
59299
- });
59300
- }).map(function (_a) {
59301
- var _b = __read(_a, 2),
59302
- name = _b[0],
59303
- componentValue = _b[1];
59470
+ var e_1, _a;
59471
+ var handlers = [];
59472
+ var _loop_1 = function (name_1, componentValue) {
59473
+ if (!componentValue) return "continue";
59474
+ if (componentHandlers.some(function (handler) {
59475
+ return handler.name === name_1;
59476
+ })) return "continue";
59304
59477
  if (isEnhancedComponentConfig(componentValue)) {
59305
59478
  var config = componentValue;
59306
- return {
59479
+ if (!config.value) {
59480
+ return "continue";
59481
+ }
59482
+ handlers.push({
59307
59483
  component: config.value,
59308
- name: name,
59484
+ name: name_1,
59309
59485
  selfClosing: config.selfClosing !== undefined ? config.selfClosing : isSelfClosingComponent(config.value),
59310
59486
  onRenderStart: config.onRenderStart,
59311
59487
  onRenderProcess: config.onRenderProcess,
59312
59488
  onRenderFinished: config.onRenderFinished,
59313
59489
  loader: config.loader,
59314
59490
  label: config.label
59315
- };
59491
+ });
59316
59492
  } else {
59317
- // 普通模式:直接使用组件
59318
- return {
59493
+ handlers.push({
59319
59494
  component: componentValue,
59320
- name: name,
59495
+ name: name_1,
59321
59496
  selfClosing: isSelfClosingComponent(componentValue)
59322
- };
59497
+ });
59323
59498
  }
59499
+ };
59500
+ try {
59501
+ for (var _b = __values(Object.entries(components)), _c = _b.next(); !_c.done; _c = _b.next()) {
59502
+ var _d = __read(_c.value, 2),
59503
+ name_1 = _d[0],
59504
+ componentValue = _d[1];
59505
+ _loop_1(name_1, componentValue);
59506
+ }
59507
+ } catch (e_1_1) {
59508
+ e_1 = {
59509
+ error: e_1_1
59510
+ };
59511
+ } finally {
59512
+ try {
59513
+ if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
59514
+ } finally {
59515
+ if (e_1) throw e_1.error;
59516
+ }
59517
+ }
59518
+ return handlers;
59519
+ }
59520
+ function buildLoaderShellFromParsed(parsedData, allComponentHandlers, layoutProps) {
59521
+ if (!parsedData.length) return null;
59522
+ var nodes = [];
59523
+ var _loop_2 = function (i) {
59524
+ var item = parsedData[i];
59525
+ if (item.type === 'text') {
59526
+ var t = String(item.value || '').trim();
59527
+ if (t) {
59528
+ nodes.push(/*#__PURE__*/React__default.createElement('div', {
59529
+ key: "sync-txt-".concat(i),
59530
+ style: {
59531
+ whiteSpace: 'pre-wrap'
59532
+ }
59533
+ }, t));
59534
+ }
59535
+ return "continue";
59536
+ }
59537
+ if (item.type !== 'component' || item.isComplete === true) return "continue";
59538
+ var handler = allComponentHandlers.find(function (c) {
59539
+ return c.name === item.value;
59540
+ });
59541
+ if (!(handler === null || handler === void 0 ? void 0 : handler.loader)) return "continue";
59542
+ var displayName = handler.label || item.value;
59543
+ nodes.push(/*#__PURE__*/React__default.createElement(ComponentPlaceholder, {
59544
+ key: "sync-loader-".concat(item.value, "-").concat(i),
59545
+ componentName: displayName,
59546
+ loader: handler.loader
59547
+ }));
59548
+ };
59549
+ for (var i = 0; i < parsedData.length; i++) {
59550
+ _loop_2(i);
59551
+ }
59552
+ if (!nodes.length) return null;
59553
+ return /*#__PURE__*/React__default.createElement(MdxLayout, __assign(__assign({}, layoutProps), {
59554
+ children: React__default.createElement.apply(React__default, __spreadArray([React__default.Fragment, null], __read(nodes), false))
59555
+ }));
59556
+ }
59557
+ function parsedStructureSignature(parsedData) {
59558
+ return parsedData.map(function (p) {
59559
+ if (p.type === 'text') return "t:".concat(String(p.value || '').length);
59560
+ return "c:".concat(p.value, ":").concat(p.isComplete === true ? '1' : '0');
59561
+ }).join('|');
59562
+ }
59563
+ function hasPendingLoaderComponents(parsedData, handlers) {
59564
+ return parsedData.some(function (item) {
59565
+ var _a;
59566
+ if (item.type !== 'component' || item.isComplete === true) return false;
59567
+ return Boolean((_a = handlers.find(function (h) {
59568
+ return h.name === item.value;
59569
+ })) === null || _a === void 0 ? void 0 : _a.loader);
59324
59570
  });
59325
59571
  }
59326
59572
  function ReactAIRenderer(_a) {
@@ -59335,38 +59581,52 @@ function ReactAIRenderer(_a) {
59335
59581
  componentHandlers = _d === void 0 ? [] : _d,
59336
59582
  useGithubStyles = _a.useGithubStyles,
59337
59583
  mdxLayoutClassName = _a.mdxLayoutClassName,
59338
- mdxLayoutStyle = _a.mdxLayoutStyle;
59339
- // 检查是否在浏览器环境中
59584
+ mdxLayoutStyle = _a.mdxLayoutStyle,
59585
+ _e = _a.theme,
59586
+ theme = _e === void 0 ? "dark" : _e,
59587
+ codeTheme = _a.codeTheme;
59588
+ var _f = __read(useState(null), 2),
59589
+ component = _f[0],
59590
+ setComponent = _f[1];
59591
+ var fallbackErrorRef = useRef({
59592
+ hasError: false
59593
+ });
59594
+ var completedComponentsCacheRef = useRef(new Map());
59595
+ var parserRef = useRef(null);
59596
+ var lastLoaderSigRef = useRef('');
59340
59597
  var isBrowser = typeof window !== 'undefined';
59341
- // 在服务端直接返回空内容,避免使用 hooks
59342
- if (!isBrowser) {
59343
- return /*#__PURE__*/jsx(React__default.Fragment, {
59344
- children: null
59345
- });
59346
- }
59347
59598
  content = content || children || '';
59348
- // 构建 allComponents:从增强配置中提取实际的组件
59349
- var normalizedComponents = components ? Object.fromEntries(Object.entries(components).map(function (_a) {
59599
+ var normalizedComponents = components ? Object.fromEntries(Object.entries(components).filter(function (_a) {
59600
+ var _b = __read(_a, 2);
59601
+ _b[0];
59602
+ var value = _b[1];
59603
+ return value != null;
59604
+ }).map(function (_a) {
59350
59605
  var _b = __read(_a, 2),
59351
59606
  name = _b[0],
59352
59607
  value = _b[1];
59353
59608
  return [name, extractComponent(value)];
59354
59609
  })) : {};
59355
- var allComponents = __assign(__assign({}, BuiltInComponents), normalizedComponents);
59356
- // 构建 allComponentHandlers:支持增强模式
59610
+ // 根据 theme / codeTheme 创建带主题配置的内置组件
59611
+ var themedBuiltInComponents = useMemo(function () {
59612
+ return createBuiltInComponents(theme, codeTheme);
59613
+ }, [theme, codeTheme]);
59614
+ var allComponents = __assign(__assign({}, themedBuiltInComponents), normalizedComponents);
59357
59615
  var allComponentHandlers = __spreadArray(__spreadArray([], __read(components ? convertComponentsToHandlers(components, componentHandlers) : []), false), __read(componentHandlers), false);
59358
- var _e = __read(useState(null), 2),
59359
- component = _e[0],
59360
- setComponent = _e[1];
59361
- // 用于跟踪 FallbackView 的错误状态
59362
- var fallbackErrorRef = useRef({
59363
- hasError: false
59364
- });
59365
- // 用于缓存已完成的组件,避免重复渲染
59366
- var completedComponentsCacheRef = useRef(new Map());
59367
- var parser = new MDXStreamingParser(allComponentHandlers);
59616
+ if (!parserRef.current) {
59617
+ parserRef.current = new MDXStreamingParser(allComponentHandlers);
59618
+ }
59619
+ var parser = parserRef.current;
59368
59620
  var mdxContent = content || '';
59369
- // FallbackView 错误状态变化时的回调
59621
+ var handlersRef = useRef(allComponentHandlers);
59622
+ handlersRef.current = allComponentHandlers;
59623
+ var layoutProps = useMemo(function () {
59624
+ return {
59625
+ useGithubStyles: useGithubStyles,
59626
+ className: mdxLayoutClassName,
59627
+ style: mdxLayoutStyle
59628
+ };
59629
+ }, [useGithubStyles, mdxLayoutClassName, mdxLayoutStyle]);
59370
59630
  var handleFallbackErrorChange = function (hasError, error) {
59371
59631
  fallbackErrorRef.current = {
59372
59632
  hasError: hasError,
@@ -59374,17 +59634,33 @@ function ReactAIRenderer(_a) {
59374
59634
  };
59375
59635
  };
59376
59636
  useEffect(function () {
59637
+ if (!isBrowser) return;
59638
+ var cancelled = false;
59377
59639
  var parseMDX = function () {
59378
59640
  return __awaiter(_this, void 0, void 0, function () {
59379
- 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;
59380
- var e_1, _b;
59641
+ 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;
59642
+ var e_2, _b;
59381
59643
  return __generator(this, function (_c) {
59382
59644
  switch (_c.label) {
59383
59645
  case 0:
59384
- ThinkComponent = null;
59385
- ResultComponent = null;
59386
59646
  protectedContent = protectSpecialSyntax(mdxContent);
59387
59647
  _a = remarkThinkUpdate(protectedContent), thinkContent = _a.thinkContent, resultContent = _a.resultContent;
59648
+ if (resultContent) {
59649
+ resultContent = fixMDXContent(resultContent);
59650
+ parsedData_1 = parser.parse('magic', resultContent);
59651
+ loaderSig = parsedStructureSignature(parsedData_1);
59652
+ if (hasPendingLoaderComponents(parsedData_1, handlersRef.current)) {
59653
+ if (loaderSig !== lastLoaderSigRef.current) {
59654
+ lastLoaderSigRef.current = loaderSig;
59655
+ shell = buildLoaderShellFromParsed(parsedData_1, handlersRef.current, layoutProps);
59656
+ if (shell && !cancelled) setComponent(shell);
59657
+ }
59658
+ return [2 /*return*/];
59659
+ }
59660
+ lastLoaderSigRef.current = '';
59661
+ }
59662
+ ThinkComponent = null;
59663
+ ResultComponent = null;
59388
59664
  if (!thinkContent) return [3 /*break*/, 2];
59389
59665
  return [4 /*yield*/, renderMdx(thinkContent, scope, allComponents)];
59390
59666
  case 1:
@@ -59393,7 +59669,6 @@ function ReactAIRenderer(_a) {
59393
59669
  case 2:
59394
59670
  parsedData = [];
59395
59671
  if (!resultContent) return [3 /*break*/, 8];
59396
- resultContent = fixMDXContent(resultContent);
59397
59672
  parsedData = parser.parse('magic', resultContent);
59398
59673
  return [4 /*yield*/, Promise.all(parsedData.map(function (item) {
59399
59674
  return parseComponentRecursively(allComponentHandlers, item, scope);
@@ -59409,25 +59684,24 @@ function ReactAIRenderer(_a) {
59409
59684
  if (indexMatch) {
59410
59685
  index = parseInt(indexMatch[1], 10);
59411
59686
  if (index >= currentComponentCount) {
59412
- // 如果索引超出当前组件数量,删除缓存
59413
59687
  completedComponentsCacheRef.current.delete(key);
59414
59688
  }
59415
59689
  }
59416
59690
  }
59417
- } catch (e_1_1) {
59418
- e_1 = {
59419
- error: e_1_1
59691
+ } catch (e_2_1) {
59692
+ e_2 = {
59693
+ error: e_2_1
59420
59694
  };
59421
59695
  } finally {
59422
59696
  try {
59423
59697
  if (cacheKeys_1_1 && !cacheKeys_1_1.done && (_b = cacheKeys_1.return)) _b.call(cacheKeys_1);
59424
59698
  } finally {
59425
- if (e_1) throw e_1.error;
59699
+ if (e_2) throw e_2.error;
59426
59700
  }
59427
59701
  }
59428
59702
  finalComponent = [];
59429
59703
  fallbackComponent = [];
59430
- _loop_1 = function (i) {
59704
+ _loop_3 = function (i) {
59431
59705
  var item, currentParsedItem, _result, placeholderForFallback, componentNameMatch, componentName_1, componentHandler, displayName, cacheKey;
59432
59706
  return __generator(this, function (_d) {
59433
59707
  switch (_d.label) {
@@ -59441,10 +59715,10 @@ function ReactAIRenderer(_a) {
59441
59715
  case 1:
59442
59716
  _result = _d.sent();
59443
59717
  finalComponent.push(_result);
59444
- return [3 /*break*/, 11];
59718
+ return [3 /*break*/, 12];
59445
59719
  case 2:
59446
59720
  componentNameMatch = item.value.match(/<([A-Z][A-Za-z0-9]*)/);
59447
- if (!componentNameMatch) return [3 /*break*/, 9];
59721
+ if (!componentNameMatch) return [3 /*break*/, 10];
59448
59722
  componentName_1 = componentNameMatch[1];
59449
59723
  componentHandler = allComponentHandlers.find(function (c) {
59450
59724
  return c.name === componentName_1;
@@ -59461,15 +59735,12 @@ function ReactAIRenderer(_a) {
59461
59735
  if (!(currentParsedItem.isComplete === true || !(componentHandler === null || componentHandler === void 0 ? void 0 : componentHandler.loader))) return [3 /*break*/, 6];
59462
59736
  cacheKey = "mdx-component-".concat(componentName_1, "-").concat(i);
59463
59737
  if (!completedComponentsCacheRef.current.has(cacheKey)) return [3 /*break*/, 3];
59464
- // 使用缓存的组件
59465
59738
  _result = completedComponentsCacheRef.current.get(cacheKey);
59466
59739
  return [3 /*break*/, 5];
59467
59740
  case 3:
59468
59741
  return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59469
59742
  case 4:
59470
- // 缓存不存在,调用 renderMdx 并存入缓存
59471
59743
  _result = _d.sent();
59472
- // 为组件设置 key,确保 React 能正确识别
59473
59744
  if (/*#__PURE__*/React__default.isValidElement(_result)) {
59474
59745
  _result = /*#__PURE__*/React__default.cloneElement(_result, {
59475
59746
  key: cacheKey
@@ -59479,30 +59750,30 @@ function ReactAIRenderer(_a) {
59479
59750
  key: cacheKey
59480
59751
  }, _result);
59481
59752
  }
59482
- // 存入缓存
59483
59753
  completedComponentsCacheRef.current.set(cacheKey, _result);
59484
59754
  _d.label = 5;
59485
59755
  case 5:
59486
59756
  finalComponent.push(_result);
59487
- return [3 /*break*/, 8];
59757
+ return [3 /*break*/, 9];
59488
59758
  case 6:
59489
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59490
- case 7:
59491
- // 组件未完成,正常渲染
59492
- _result = _d.sent();
59759
+ if (!placeholderForFallback) return [3 /*break*/, 7];
59493
59760
  finalComponent.push(placeholderForFallback);
59494
- _d.label = 8;
59761
+ return [3 /*break*/, 9];
59762
+ case 7:
59763
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59495
59764
  case 8:
59496
- return [3 /*break*/, 11];
59765
+ _result = _d.sent();
59766
+ finalComponent.push(_result);
59767
+ _d.label = 9;
59497
59768
  case 9:
59498
- return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59769
+ return [3 /*break*/, 12];
59499
59770
  case 10:
59500
- // 没有匹配到组件名,正常渲染
59771
+ return [4 /*yield*/, renderMdx(item.value, scope, allComponents)];
59772
+ case 11:
59501
59773
  _result = _d.sent();
59502
59774
  finalComponent.push(_result);
59503
- _d.label = 11;
59504
- case 11:
59505
- // fallbackComponent 应该是 finalComponent 的前 i 个元素 + 当前 item 的 loader
59775
+ _d.label = 12;
59776
+ case 12:
59506
59777
  fallbackComponent.length = 0;
59507
59778
  fallbackComponent.push.apply(fallbackComponent, __spreadArray([], __read(finalComponent.slice(0, i)), false));
59508
59779
  if (placeholderForFallback) {
@@ -59516,7 +59787,7 @@ function ReactAIRenderer(_a) {
59516
59787
  _c.label = 4;
59517
59788
  case 4:
59518
59789
  if (!(i < parsedComponents.length)) return [3 /*break*/, 7];
59519
- return [5 /*yield**/, _loop_1(i)];
59790
+ return [5 /*yield**/, _loop_3(i)];
59520
59791
  case 5:
59521
59792
  _c.sent();
59522
59793
  _c.label = 6;
@@ -59539,13 +59810,13 @@ function ReactAIRenderer(_a) {
59539
59810
  MDXComponent = /*#__PURE__*/jsxs(React__default.Fragment, {
59540
59811
  children: [ThinkComponent, ResultComponent]
59541
59812
  });
59813
+ if (cancelled) return [2 /*return*/];
59542
59814
  if (!fallbackErrorRef.current.hasError) {
59543
59815
  setComponent(MDXComponent);
59544
59816
  } else {
59545
59817
  parsedDataLength = parsedData.length;
59546
59818
  if (parsedDataLength > 0) {
59547
59819
  lastItem = parsedData[parsedDataLength - 1];
59548
- // 如果最后一个组件是完整的,强制更新
59549
59820
  if (lastItem.isComplete === true) {
59550
59821
  setComponent(MDXComponent);
59551
59822
  } else if (lastItem.type === 'text') {
@@ -59559,7 +59830,13 @@ function ReactAIRenderer(_a) {
59559
59830
  });
59560
59831
  };
59561
59832
  parseMDX();
59562
- }, [content]);
59833
+ return function () {
59834
+ cancelled = true;
59835
+ };
59836
+ }, [content, theme, codeTheme]);
59837
+ if (!isBrowser) {
59838
+ return null;
59839
+ }
59563
59840
  return /*#__PURE__*/jsx(ErrorBoundary, {
59564
59841
  content: content,
59565
59842
  children: /*#__PURE__*/jsx(React__default.Fragment, {