@ant-design/agentic-ui 2.30.6 → 2.30.8

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.
Files changed (27) hide show
  1. package/dist/MarkdownEditor/editor/parser/parserMarkdownToSlateNode.js +1 -3
  2. package/dist/MarkdownEditor/editor/parser/remarkDirectiveContainersOnly.d.ts +14 -0
  3. package/dist/MarkdownEditor/editor/parser/remarkDirectiveContainersOnly.js +26 -0
  4. package/dist/MarkdownEditor/editor/parser/remarkParse.d.ts +1 -1
  5. package/dist/MarkdownEditor/editor/parser/remarkParse.js +2 -2
  6. package/dist/MarkdownEditor/editor/style.js +7 -5
  7. package/dist/MarkdownEditor/editor/utils/markdownToHtml.js +2 -2
  8. package/dist/MarkdownInputField/FileMapView/FileMapViewItem.js +54 -16
  9. package/dist/MarkdownInputField/FileMapView/index.js +8 -2
  10. package/dist/MarkdownInputField/FileMapView/style.js +5 -1
  11. package/dist/MarkdownRenderer/MarkdownRenderer.js +2 -1
  12. package/dist/MarkdownRenderer/index.d.ts +2 -0
  13. package/dist/MarkdownRenderer/index.js +1 -0
  14. package/dist/MarkdownRenderer/markdownReactShared.d.ts +93 -0
  15. package/dist/MarkdownRenderer/markdownReactShared.js +1159 -0
  16. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.d.ts +15 -0
  17. package/dist/MarkdownRenderer/streaming/MarkdownBlockPiece.js +61 -0
  18. package/dist/MarkdownRenderer/streaming/lastBlockThrottle.d.ts +4 -0
  19. package/dist/MarkdownRenderer/streaming/lastBlockThrottle.js +14 -0
  20. package/dist/MarkdownRenderer/streaming/revisionPolicy.d.ts +5 -0
  21. package/dist/MarkdownRenderer/streaming/revisionPolicy.js +10 -0
  22. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.d.ts +6 -0
  23. package/dist/MarkdownRenderer/streaming/useStreamingMarkdownReact.js +70 -0
  24. package/dist/MarkdownRenderer/useMarkdownToReact.d.ts +3 -22
  25. package/dist/MarkdownRenderer/useMarkdownToReact.js +3 -1286
  26. package/dist/Types/micromark-extension-directive-subpath.d.ts +8 -0
  27. package/package.json +4 -2
@@ -1,1292 +1,9 @@
1
- function _array_like_to_array(arr, len) {
2
- if (len == null || len > arr.length) len = arr.length;
3
- for(var i = 0, arr2 = new Array(len); i < len; i++)arr2[i] = arr[i];
4
- return arr2;
5
- }
6
- function _array_with_holes(arr) {
7
- if (Array.isArray(arr)) return arr;
8
- }
9
- function _array_without_holes(arr) {
10
- if (Array.isArray(arr)) return _array_like_to_array(arr);
11
- }
12
- function _define_property(obj, key, value) {
13
- if (key in obj) {
14
- Object.defineProperty(obj, key, {
15
- value: value,
16
- enumerable: true,
17
- configurable: true,
18
- writable: true
19
- });
20
- } else {
21
- obj[key] = value;
22
- }
23
- return obj;
24
- }
25
- function _iterable_to_array(iter) {
26
- if (typeof Symbol !== "undefined" && iter[Symbol.iterator] != null || iter["@@iterator"] != null) return Array.from(iter);
27
- }
28
- function _non_iterable_rest() {
29
- throw new TypeError("Invalid attempt to destructure non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
30
- }
31
- function _non_iterable_spread() {
32
- throw new TypeError("Invalid attempt to spread non-iterable instance.\\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.");
33
- }
34
- function _object_spread(target) {
35
- for(var i = 1; i < arguments.length; i++){
36
- var source = arguments[i] != null ? arguments[i] : {};
37
- var ownKeys = Object.keys(source);
38
- if (typeof Object.getOwnPropertySymbols === "function") {
39
- ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function(sym) {
40
- return Object.getOwnPropertyDescriptor(source, sym).enumerable;
41
- }));
42
- }
43
- ownKeys.forEach(function(key) {
44
- _define_property(target, key, source[key]);
45
- });
46
- }
47
- return target;
48
- }
49
- function ownKeys(object, enumerableOnly) {
50
- var keys = Object.keys(object);
51
- if (Object.getOwnPropertySymbols) {
52
- var symbols = Object.getOwnPropertySymbols(object);
53
- if (enumerableOnly) {
54
- symbols = symbols.filter(function(sym) {
55
- return Object.getOwnPropertyDescriptor(object, sym).enumerable;
56
- });
57
- }
58
- keys.push.apply(keys, symbols);
59
- }
60
- return keys;
61
- }
62
- function _object_spread_props(target, source) {
63
- source = source != null ? source : {};
64
- if (Object.getOwnPropertyDescriptors) {
65
- Object.defineProperties(target, Object.getOwnPropertyDescriptors(source));
66
- } else {
67
- ownKeys(Object(source)).forEach(function(key) {
68
- Object.defineProperty(target, key, Object.getOwnPropertyDescriptor(source, key));
69
- });
70
- }
71
- return target;
72
- }
73
- function _object_without_properties(source, excluded) {
74
- if (source == null) return {};
75
- var target = {}, sourceKeys, key, i;
76
- if (typeof Reflect !== "undefined" && Reflect.ownKeys) {
77
- sourceKeys = Reflect.ownKeys(source);
78
- for(i = 0; i < sourceKeys.length; i++){
79
- key = sourceKeys[i];
80
- if (excluded.indexOf(key) >= 0) continue;
81
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
82
- target[key] = source[key];
83
- }
84
- return target;
85
- }
86
- target = _object_without_properties_loose(source, excluded);
87
- if (Object.getOwnPropertySymbols) {
88
- sourceKeys = Object.getOwnPropertySymbols(source);
89
- for(i = 0; i < sourceKeys.length; i++){
90
- key = sourceKeys[i];
91
- if (excluded.indexOf(key) >= 0) continue;
92
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
93
- target[key] = source[key];
94
- }
95
- }
96
- return target;
97
- }
98
- function _object_without_properties_loose(source, excluded) {
99
- if (source == null) return {};
100
- var target = {}, sourceKeys = Object.getOwnPropertyNames(source), key, i;
101
- for(i = 0; i < sourceKeys.length; i++){
102
- key = sourceKeys[i];
103
- if (excluded.indexOf(key) >= 0) continue;
104
- if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue;
105
- target[key] = source[key];
106
- }
107
- return target;
108
- }
109
- function _to_array(arr) {
110
- return _array_with_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_rest();
111
- }
112
- function _to_consumable_array(arr) {
113
- return _array_without_holes(arr) || _iterable_to_array(arr) || _unsupported_iterable_to_array(arr) || _non_iterable_spread();
114
- }
115
- function _unsupported_iterable_to_array(o, minLen) {
116
- if (!o) return;
117
- if (typeof o === "string") return _array_like_to_array(o, minLen);
118
- var n = Object.prototype.toString.call(o).slice(8, -1);
119
- if (n === "Object" && o.constructor) n = o.constructor.name;
120
- if (n === "Map" || n === "Set") return Array.from(n);
121
- if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
122
- }
123
- import { Checkbox, Image } from "antd";
124
1
  import { toJsxRuntime } from "hast-util-to-jsx-runtime";
125
- import React, { useContext, useMemo, useRef } from "react";
126
2
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
127
- import rehypeKatex from "rehype-katex";
128
- import rehypeRaw from "rehype-raw";
129
- import remarkDirective from "remark-directive";
130
- import remarkFrontmatter from "remark-frontmatter";
131
- import remarkGfm from "remark-gfm";
132
- import remarkMath from "remark-math";
133
- import remarkParse from "remark-parse";
134
- import remarkRehype from "remark-rehype";
135
- import { unified } from "unified";
136
- import { visit } from "unist-util-visit";
137
3
  import { JINJA_DOLLAR_PLACEHOLDER } from "../MarkdownEditor/editor/parser/constants";
138
- import { remarkDirectiveContainer } from "../MarkdownEditor/editor/parser/remarkDirectiveContainer";
139
- import { convertParagraphToImage, fixStrongWithSpecialChars, protectJinjaDollarInText } from "../MarkdownEditor/editor/parser/remarkParse";
140
- import { REMARK_REHYPE_DIRECTIVE_HANDLERS } from "../MarkdownEditor/editor/utils/markdownToHtml";
141
- import { parseChineseCurrencyToNumber } from "../Plugins/chart/utils";
142
- import { ToolUseBarThink } from "../ToolUseBarThink";
143
- import AnimationText from "./AnimationText";
144
- import { StreamingAnimationContext } from "./StreamingAnimationContext";
145
- var INLINE_MATH_WITH_SINGLE_DOLLAR = {
146
- singleDollarTextMath: true
147
- };
148
- var FRONTMATTER_LANGUAGES = [
149
- 'yaml'
150
- ];
151
- var REMARK_DIRECTIVE_CONTAINER_OPTIONS = {
152
- className: 'markdown-container',
153
- titleElement: {
154
- className: [
155
- 'markdown-container__title'
156
- ]
157
- }
158
- };
159
- var remarkRehypePlugin = remarkRehype;
160
- var FOOTNOTE_REF_PATTERN = /\[\^([^\]]+)\]/g;
161
- var CHART_COMMENT_PATTERN = /^<!--\s*(\[[\s\S]*\]|\{[\s\S]*\})\s*-->$/;
162
- var extractCellText = function extractCellText1(cell) {
163
- if (!(cell === null || cell === void 0 ? void 0 : cell.children)) return '';
164
- return cell.children.map(function(child) {
165
- if (child.type === 'text') return child.value || '';
166
- if (child.children) return extractCellText(child);
167
- return '';
168
- }).join('').trim();
169
- };
170
- /**
171
- * 从 mdast table 节点提取列名和数据
172
- */ var extractTableData = function extractTableData(tableNode) {
173
- var _loop = function(i) {
174
- var row = tableNode.children[i];
175
- if (!(row === null || row === void 0 ? void 0 : row.children)) return "continue";
176
- var record = {
177
- key: "row-".concat(i)
178
- };
179
- row.children.forEach(function(cell, j) {
180
- if (j < columns.length) {
181
- var val = extractCellText(cell);
182
- if (val === '') {
183
- record[columns[j].dataIndex] = val;
184
- } else {
185
- var num = Number(val);
186
- if (Number.isFinite(num)) {
187
- record[columns[j].dataIndex] = num;
188
- } else {
189
- var cn = parseChineseCurrencyToNumber(val);
190
- record[columns[j].dataIndex] = cn !== null ? cn : val;
191
- }
192
- }
193
- }
194
- });
195
- dataSource.push(record);
196
- };
197
- var _tableNode_children, _headerRow_children;
198
- if (!((_tableNode_children = tableNode.children) === null || _tableNode_children === void 0 ? void 0 : _tableNode_children.length)) return null;
199
- var headerRow = tableNode.children[0];
200
- if (!(headerRow === null || headerRow === void 0 ? void 0 : (_headerRow_children = headerRow.children) === null || _headerRow_children === void 0 ? void 0 : _headerRow_children.length)) return null;
201
- var columns = headerRow.children.map(function(cell) {
202
- var text = extractCellText(cell);
203
- return {
204
- title: text,
205
- dataIndex: text,
206
- key: text
207
- };
208
- });
209
- var dataSource = [];
210
- for(var i = 1; i < tableNode.children.length; i++)_loop(i);
211
- return {
212
- columns: columns,
213
- dataSource: dataSource
214
- };
215
- };
216
- /**
217
- * remark 插件:将 "HTML 注释(图表配置)+ 表格" 组合转为 chart 代码块。
218
- *
219
- * 在 MarkdownEditor 中,parseTableOrChart 负责此逻辑。
220
- * 在 MarkdownRenderer 中,此插件在 mdast 层面完成等价转换。
221
- *
222
- * 匹配模式:
223
- * ```
224
- * <!-- [{"chartType":"line","x":"month","y":"value",...}] -->
225
- * | month | value |
226
- * |-------|-------|
227
- * | 2024 | 100 |
228
- * ```
229
- */ var remarkChartFromComment = function remarkChartFromComment() {
230
- return function(tree) {
231
- var children = tree.children;
232
- if (!children || !Array.isArray(children)) return;
233
- var toRemove = [];
234
- for(var i = 0; i < children.length - 1; i++){
235
- var _node_value;
236
- var node = children[i];
237
- var next = children[i + 1];
238
- if (node.type !== 'html' || next.type !== 'table') continue;
239
- var match = (_node_value = node.value) === null || _node_value === void 0 ? void 0 : _node_value.match(CHART_COMMENT_PATTERN);
240
- if (!match) continue;
241
- var chartConfig = void 0;
242
- try {
243
- chartConfig = JSON.parse(match[1]);
244
- } catch (unused) {
245
- continue;
246
- }
247
- if (!Array.isArray(chartConfig)) chartConfig = [
248
- chartConfig
249
- ];
250
- var hasChartType = chartConfig.some(function(c) {
251
- return c.chartType && c.chartType !== 'table';
252
- });
253
- if (!hasChartType) continue;
254
- var tableData = extractTableData(next);
255
- if (!tableData) continue;
256
- var chartJson = JSON.stringify({
257
- config: chartConfig,
258
- columns: tableData.columns,
259
- dataSource: tableData.dataSource
260
- });
261
- children[i] = {
262
- type: 'code',
263
- lang: 'chart',
264
- value: chartJson
265
- };
266
- toRemove.push(i + 1);
267
- i++;
268
- }
269
- for(var j = toRemove.length - 1; j >= 0; j--){
270
- children.splice(toRemove[j], 1);
271
- }
272
- };
273
- };
274
- /**
275
- * rehype 插件:将文本中残留的 [^N] 模式转为 fnc 标记元素。
276
- *
277
- * remark-gfm 只在有对应 footnoteDefinition 时才会转换 footnoteReference,
278
- * 但 AI 对话场景中 [^1] 常用作内联引用(无底部定义)。
279
- * 此插件在 hast 层面补充处理这些"裸引用"。
280
- */ var rehypeFootnoteRef = function rehypeFootnoteRef() {
281
- return function(tree) {
282
- visit(tree, 'text', function(node, index, parent) {
283
- if (!parent || index === undefined) return;
284
- var value = node.value;
285
- if (!FOOTNOTE_REF_PATTERN.test(value)) return;
286
- FOOTNOTE_REF_PATTERN.lastIndex = 0;
287
- var children = [];
288
- var lastIndex = 0;
289
- var match;
290
- while((match = FOOTNOTE_REF_PATTERN.exec(value)) !== null){
291
- if (match.index > lastIndex) {
292
- children.push({
293
- type: 'text',
294
- value: value.slice(lastIndex, match.index)
295
- });
296
- }
297
- children.push({
298
- type: 'element',
299
- tagName: 'span',
300
- properties: {
301
- 'data-fnc': 'fnc',
302
- 'data-fnc-name': match[1]
303
- },
304
- children: [
305
- {
306
- type: 'text',
307
- value: match[1]
308
- }
309
- ]
310
- });
311
- lastIndex = match.index + match[0].length;
312
- }
313
- if (lastIndex < value.length) {
314
- children.push({
315
- type: 'text',
316
- value: value.slice(lastIndex)
317
- });
318
- }
319
- if (children.length > 0) {
320
- var _parent_children;
321
- (_parent_children = parent.children).splice.apply(_parent_children, [
322
- index,
323
- 1
324
- ].concat(_to_consumable_array(children)));
325
- return index + children.length;
326
- }
327
- });
328
- };
329
- };
330
- var createHastProcessor = function createHastProcessor(extraRemarkPlugins, config) {
331
- var processor = unified();
332
- processor.use(remarkParse).use(remarkGfm, {
333
- singleTilde: false
334
- }).use(fixStrongWithSpecialChars).use(convertParagraphToImage).use(protectJinjaDollarInText).use(remarkMath, INLINE_MATH_WITH_SINGLE_DOLLAR).use(remarkFrontmatter, FRONTMATTER_LANGUAGES).use(remarkDirective).use(remarkDirectiveContainer, REMARK_DIRECTIVE_CONTAINER_OPTIONS).use(remarkChartFromComment).use(remarkRehypePlugin, {
335
- allowDangerousHtml: true,
336
- handlers: REMARK_REHYPE_DIRECTIVE_HANDLERS
337
- }).use(rehypeRaw).use(rehypeKatex, {
338
- strict: 'ignore'
339
- }).use(rehypeFootnoteRef);
340
- if (extraRemarkPlugins) {
341
- extraRemarkPlugins.forEach(function(entry) {
342
- if (Array.isArray(entry)) {
343
- var _processor;
344
- var _entry = _to_array(entry), plugin = _entry[0], pluginOptions = _entry.slice(1);
345
- (_processor = processor).use.apply(_processor, [
346
- plugin
347
- ].concat(_to_consumable_array(pluginOptions)));
348
- } else {
349
- processor.use(entry);
350
- }
351
- });
352
- }
353
- if (config === null || config === void 0 ? void 0 : config.markedConfig) {
354
- config.markedConfig.forEach(function(entry) {
355
- if (Array.isArray(entry)) {
356
- var _processor;
357
- var _entry = _to_array(entry), plugin = _entry[0], pluginOptions = _entry.slice(1);
358
- (_processor = processor).use.apply(_processor, [
359
- plugin
360
- ].concat(_to_consumable_array(pluginOptions)));
361
- } else {
362
- processor.use(entry);
363
- }
364
- });
365
- }
366
- return processor;
367
- };
368
- var extractLanguageFromClassName = function extractLanguageFromClassName(className) {
369
- if (!className) return undefined;
370
- var flat = typeof className === 'string' ? className : className.map(String).join(' ');
371
- var classes = flat.split(/\s+/).filter(Boolean);
372
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
373
- try {
374
- for(var _iterator = classes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
375
- var cls = _step.value;
376
- var match = cls.match(/^language-(.+)$/);
377
- if (match) return match[1];
378
- }
379
- } catch (err) {
380
- _didIteratorError = true;
381
- _iteratorError = err;
382
- } finally{
383
- try {
384
- if (!_iteratorNormalCompletion && _iterator.return != null) {
385
- _iterator.return();
386
- }
387
- } finally{
388
- if (_didIteratorError) {
389
- throw _iteratorError;
390
- }
391
- }
392
- }
393
- return undefined;
394
- };
395
- /**
396
- * 提取 React children 的文本内容
397
- */ var extractChildrenText = function extractChildrenText1(children) {
398
- var _children_props;
399
- if (typeof children === 'string') return children;
400
- if (typeof children === 'number') return String(children);
401
- if (Array.isArray(children)) return children.map(extractChildrenText).join('');
402
- if (React.isValidElement(children) && ((_children_props = children.props) === null || _children_props === void 0 ? void 0 : _children_props.children)) {
403
- return extractChildrenText(children.props.children);
404
- }
405
- return '';
406
- };
407
- /**
408
- * <think> 标签渲染组件——使用 ToolUseBarThink 替代原生 DOM。
409
- * 在 MarkdownEditor 中,<think> 被预处理为 ```think 代码块,
410
- * 然后由 ThinkBlock 组件(依赖 Slate 上下文)渲染为 ToolUseBarThink。
411
- * 在 MarkdownRenderer 中,<think> 通过 rehypeRaw 保留为 hast 元素,
412
- * 这里直接渲染为 ToolUseBarThink,无需 Slate 上下文。
413
- */ var ThinkBlockRendererComponent = function ThinkBlockRendererComponent(props) {
414
- var children = props.children;
415
- var content = extractChildrenText(children);
416
- var isLoading = content.endsWith('...');
417
- return React.createElement(ToolUseBarThink, {
418
- testId: 'think-block-renderer',
419
- styles: {
420
- root: {
421
- boxSizing: 'border-box',
422
- maxWidth: '680px',
423
- marginTop: 8
424
- }
425
- },
426
- toolName: isLoading ? '深度思考...' : '深度思考',
427
- thinkContent: content,
428
- status: isLoading ? 'loading' : 'success'
429
- });
430
- };
431
- /**
432
- * 构建与 MarkdownEditor Readonly 组件对齐的 hast→React 组件映射。
433
- *
434
- * MarkdownEditor 的 Slate 元素使用 data-be 属性和 prefixCls 类名,
435
- * 这里为原生 HTML 标签添加相同的属性,使共用的 CSS 能正确命中。
436
- */ var buildEditorAlignedComponents = function buildEditorAlignedComponents(prefixCls, userComponents, streaming, linkConfig, streamingParagraphAnimation) {
437
- var listCls = "".concat(prefixCls, "-list");
438
- var tableCls = "".concat(prefixCls, "-content-table");
439
- var contentCls = prefixCls; // e.g. ant-agentic-md-editor-content
440
- /** 仅当 streaming、末块动画上下文允许且显式开启段落动画时包 AnimationText */ var StreamAnimWrap = function StreamAnimWrap(param) {
441
- var children = param.children;
442
- var _ref;
443
- var ctx = useContext(StreamingAnimationContext);
444
- var animateBlock = (_ref = ctx === null || ctx === void 0 ? void 0 : ctx.animateBlock) !== null && _ref !== void 0 ? _ref : true;
445
- var allow = !!streaming && animateBlock && !!streamingParagraphAnimation;
446
- if (!allow) return children;
447
- return jsx(AnimationText, {
448
- children: children
449
- });
450
- };
451
- StreamAnimWrap.displayName = 'StreamAnimWrap';
452
- var wrapAnimation = function wrapAnimation(children) {
453
- return jsx(StreamAnimWrap, {
454
- children: children
455
- });
456
- };
457
- return _object_spread({
458
- // ================================================================
459
- // Block 级别元素
460
- // ================================================================
461
- p: function p(props) {
462
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
463
- "node",
464
- "children"
465
- ]);
466
- return jsx('div', _object_spread_props(_object_spread({}, rest), {
467
- 'data-be': 'paragraph',
468
- 'data-testid': 'markdown-paragraph',
469
- children: wrapAnimation(children)
470
- }));
471
- },
472
- h1: function h1(props) {
473
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
474
- "node",
475
- "children"
476
- ]);
477
- return jsx('h1', _object_spread_props(_object_spread({}, rest), {
478
- 'data-be': 'head',
479
- 'data-testid': 'markdown-heading-1',
480
- children: children
481
- }));
482
- },
483
- h2: function h2(props) {
484
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
485
- "node",
486
- "children"
487
- ]);
488
- return jsx('h2', _object_spread_props(_object_spread({}, rest), {
489
- 'data-be': 'head',
490
- 'data-testid': 'markdown-heading-2',
491
- children: children
492
- }));
493
- },
494
- h3: function h3(props) {
495
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
496
- "node",
497
- "children"
498
- ]);
499
- return jsx('h3', _object_spread_props(_object_spread({}, rest), {
500
- 'data-be': 'head',
501
- 'data-testid': 'markdown-heading-3',
502
- children: children
503
- }));
504
- },
505
- h4: function h4(props) {
506
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
507
- "node",
508
- "children"
509
- ]);
510
- return jsx('h4', _object_spread_props(_object_spread({}, rest), {
511
- 'data-be': 'head',
512
- 'data-testid': 'markdown-heading-4',
513
- children: children
514
- }));
515
- },
516
- h5: function h5(props) {
517
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
518
- "node",
519
- "children"
520
- ]);
521
- return jsx('h5', _object_spread_props(_object_spread({}, rest), {
522
- 'data-be': 'head',
523
- 'data-testid': 'markdown-heading-5',
524
- children: children
525
- }));
526
- },
527
- h6: function h6(props) {
528
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
529
- "node",
530
- "children"
531
- ]);
532
- return jsx('h6', _object_spread_props(_object_spread({}, rest), {
533
- 'data-be': 'head',
534
- 'data-testid': 'markdown-heading-6',
535
- children: children
536
- }));
537
- },
538
- blockquote: function blockquote(props) {
539
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
540
- "node",
541
- "children"
542
- ]);
543
- return jsx('blockquote', _object_spread_props(_object_spread({}, rest), {
544
- 'data-be': 'blockquote',
545
- 'data-testid': 'markdown-blockquote',
546
- children: children
547
- }));
548
- },
549
- ul: function ul(props) {
550
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
551
- "node",
552
- "children"
553
- ]);
554
- return jsx('div', {
555
- className: "".concat(listCls, "-container"),
556
- 'data-be': 'list',
557
- 'data-testid': 'markdown-unordered-list',
558
- children: jsx('ul', _object_spread_props(_object_spread({}, rest), {
559
- className: "".concat(listCls, " ul"),
560
- children: children
561
- }))
562
- });
563
- },
564
- ol: function ol(props) {
565
- var _node = props.node, children = props.children, start = props.start, rest = _object_without_properties(props, [
566
- "node",
567
- "children",
568
- "start"
569
- ]);
570
- return jsx('div', {
571
- className: "".concat(listCls, "-container"),
572
- 'data-be': 'list',
573
- 'data-testid': 'markdown-ordered-list',
574
- children: jsx('ol', _object_spread_props(_object_spread({}, rest), {
575
- className: "".concat(listCls, " ol"),
576
- start: start,
577
- children: children
578
- }))
579
- });
580
- },
581
- li: function li(props) {
582
- var _node = props.node, children = props.children, className = props.className, rest = _object_without_properties(props, [
583
- "node",
584
- "children",
585
- "className"
586
- ]);
587
- var isTask = className === 'task-list-item' || Array.isArray(className) && className.includes('task-list-item');
588
- if (isTask) {
589
- var childArray = Array.isArray(children) ? children : [
590
- children
591
- ];
592
- var checked = false;
593
- var filteredChildren = childArray.filter(function(child) {
594
- var _child_props;
595
- if (React.isValidElement(child) && ((_child_props = child.props) === null || _child_props === void 0 ? void 0 : _child_props.type) === 'checkbox') {
596
- var _child_props1;
597
- checked = !!((_child_props1 = child.props) === null || _child_props1 === void 0 ? void 0 : _child_props1.checked);
598
- return false;
599
- }
600
- return true;
601
- });
602
- return jsxs('li', _object_spread_props(_object_spread({}, rest), {
603
- className: "".concat(listCls, "-item ").concat(listCls, "-task"),
604
- 'data-be': 'list-item',
605
- 'data-testid': 'markdown-task-item',
606
- children: [
607
- jsx('span', {
608
- className: "".concat(listCls, "-check-item"),
609
- contentEditable: false,
610
- 'data-check-item': true,
611
- children: jsx(Checkbox, {
612
- checked: checked,
613
- disabled: true
614
- })
615
- })
616
- ].concat(_to_consumable_array(filteredChildren))
617
- }));
618
- }
619
- return jsx('li', _object_spread_props(_object_spread({}, rest), {
620
- className: "".concat(listCls, "-item"),
621
- 'data-be': 'list-item',
622
- 'data-testid': 'markdown-list-item',
623
- children: children
624
- }));
625
- },
626
- table: function table(props) {
627
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
628
- "node",
629
- "children"
630
- ]);
631
- return jsx('div', {
632
- className: tableCls,
633
- 'data-testid': 'markdown-table',
634
- children: jsx('div', {
635
- className: "".concat(tableCls, "-container"),
636
- children: jsx('table', _object_spread_props(_object_spread({}, rest), {
637
- className: "".concat(tableCls, "-readonly-table"),
638
- style: {
639
- tableLayout: 'auto',
640
- width: '100%'
641
- },
642
- children: children
643
- }))
644
- })
645
- });
646
- },
647
- thead: function thead(props) {
648
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
649
- "node",
650
- "children"
651
- ]);
652
- return jsx('thead', _object_spread_props(_object_spread({}, rest), {
653
- 'data-testid': 'markdown-thead',
654
- children: children
655
- }));
656
- },
657
- tbody: function tbody(props) {
658
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
659
- "node",
660
- "children"
661
- ]);
662
- return jsx('tbody', _object_spread_props(_object_spread({}, rest), {
663
- 'data-testid': 'markdown-tbody',
664
- children: children
665
- }));
666
- },
667
- tr: function tr(props) {
668
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
669
- "node",
670
- "children"
671
- ]);
672
- return jsx('tr', _object_spread_props(_object_spread({}, rest), {
673
- 'data-testid': 'markdown-tr',
674
- children: children
675
- }));
676
- },
677
- th: function th(props) {
678
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
679
- "node",
680
- "children"
681
- ]);
682
- return jsx('th', _object_spread_props(_object_spread({}, rest), {
683
- 'data-testid': 'markdown-th',
684
- style: {
685
- whiteSpace: 'normal',
686
- maxWidth: '20%'
687
- },
688
- children: children
689
- }));
690
- },
691
- td: function td(props) {
692
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
693
- "node",
694
- "children"
695
- ]);
696
- return jsx('td', _object_spread_props(_object_spread({}, rest), {
697
- 'data-testid': 'markdown-td',
698
- style: {
699
- whiteSpace: 'normal',
700
- maxWidth: '20%'
701
- },
702
- children: children
703
- }));
704
- },
705
- // input[type=checkbox]:task list 的 checkbox(兜底,主逻辑在 li 中)
706
- input: function input(props) {
707
- var _node = props.node, type = props.type, checked = props.checked, disabled = props.disabled, rest = _object_without_properties(props, [
708
- "node",
709
- "type",
710
- "checked",
711
- "disabled"
712
- ]);
713
- if (type === 'checkbox') {
714
- return jsx(Checkbox, {
715
- checked: !!checked,
716
- disabled: true,
717
- 'data-testid': 'markdown-checkbox'
718
- });
719
- }
720
- return jsx('input', _object_spread_props(_object_spread({}, rest), {
721
- type: type,
722
- checked: checked,
723
- disabled: disabled
724
- }));
725
- },
726
- // ================================================================
727
- // Leaf 级别(行内元素)
728
- // ================================================================
729
- a: function a(props) {
730
- var _node = props.node, href = props.href, _origOnClick = props.onClick, rest = _object_without_properties(props, [
731
- "node",
732
- "href",
733
- "onClick"
734
- ]);
735
- var openInNewTab = (linkConfig === null || linkConfig === void 0 ? void 0 : linkConfig.openInNewTab) !== false;
736
- return jsx('a', _object_spread_props(_object_spread({}, rest), {
737
- href: href,
738
- 'data-be': 'text',
739
- 'data-url': 'url',
740
- 'data-testid': 'markdown-link',
741
- target: openInNewTab ? '_blank' : undefined,
742
- rel: openInNewTab ? 'noopener noreferrer' : undefined,
743
- onClick: function onClick(e) {
744
- if (linkConfig === null || linkConfig === void 0 ? void 0 : linkConfig.onClick) {
745
- var res = linkConfig.onClick(href);
746
- if (res === false) {
747
- e.preventDefault();
748
- return;
749
- }
750
- }
751
- }
752
- }));
753
- },
754
- strong: function strong(props) {
755
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
756
- "node",
757
- "children"
758
- ]);
759
- return jsx('strong', _object_spread_props(_object_spread({}, rest), {
760
- 'data-testid': 'markdown-bold',
761
- style: {
762
- fontWeight: 'bold'
763
- },
764
- children: children
765
- }));
766
- },
767
- em: function em(props) {
768
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
769
- "node",
770
- "children"
771
- ]);
772
- return jsx('em', _object_spread_props(_object_spread({}, rest), {
773
- 'data-testid': 'markdown-italic',
774
- style: {
775
- fontStyle: 'italic'
776
- },
777
- children: children
778
- }));
779
- },
780
- del: function del(props) {
781
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
782
- "node",
783
- "children"
784
- ]);
785
- return jsx('del', _object_spread_props(_object_spread({}, rest), {
786
- 'data-testid': 'markdown-strikethrough',
787
- children: children
788
- }));
789
- },
790
- code: function code(props) {
791
- var _node = props.node, children = props.children, className = props.className, rest = _object_without_properties(props, [
792
- "node",
793
- "children",
794
- "className"
795
- ]);
796
- var fenceLang = extractLanguageFromClassName(className);
797
- return jsx('code', _object_spread_props(_object_spread({}, rest), {
798
- 'data-testid': fenceLang ? 'markdown-fenced-code' : 'markdown-inline-code',
799
- className: fenceLang ? className : "".concat(contentCls, "-inline-code"),
800
- children: children
801
- }));
802
- },
803
- mark: function mark(props) {
804
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
805
- "node",
806
- "children"
807
- ]);
808
- return jsx('mark', _object_spread_props(_object_spread({}, rest), {
809
- 'data-testid': 'markdown-mark',
810
- style: {
811
- background: '#f59e0b',
812
- padding: '0.1em 0.2em',
813
- borderRadius: 2
814
- },
815
- children: children
816
- }));
817
- },
818
- kbd: function kbd(props) {
819
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
820
- "node",
821
- "children"
822
- ]);
823
- return jsx('kbd', _object_spread_props(_object_spread({}, rest), {
824
- 'data-testid': 'markdown-kbd',
825
- style: {
826
- padding: '0.1em 0.4em',
827
- fontSize: '0.85em',
828
- border: '1px solid var(--color-gray-border-light, #d9d9d9)',
829
- borderRadius: 3,
830
- boxShadow: '0 1px 0 var(--color-gray-border-light, #d9d9d9)',
831
- fontFamily: 'Consolas, Monaco, "Courier New", monospace'
832
- },
833
- children: children
834
- }));
835
- },
836
- sub: function sub(props) {
837
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
838
- "node",
839
- "children"
840
- ]);
841
- return jsx('sub', _object_spread_props(_object_spread({}, rest), {
842
- 'data-testid': 'markdown-sub',
843
- children: children
844
- }));
845
- },
846
- // ================================================================
847
- // 代码块 pre > code → 路由到自定义渲染器
848
- pre: function pre(props) {
849
- var _hastPreNode_children_, _hastPreNode_children, _hastPreNode_children__properties;
850
- var hastPreNode = props.node, children = props.children, rest = _object_without_properties(props, [
851
- "node",
852
- "children"
853
- ]);
854
- var codeChild = Array.isArray(children) ? children[0] : children;
855
- var codeProps = (codeChild === null || codeChild === void 0 ? void 0 : codeChild.props) || {};
856
- var codeHastClass = (hastPreNode === null || hastPreNode === void 0 ? void 0 : (_hastPreNode_children = hastPreNode.children) === null || _hastPreNode_children === void 0 ? void 0 : (_hastPreNode_children_ = _hastPreNode_children[0]) === null || _hastPreNode_children_ === void 0 ? void 0 : _hastPreNode_children_.type) === 'element' && hastPreNode.children[0].tagName === 'code' ? (_hastPreNode_children__properties = hastPreNode.children[0].properties) === null || _hastPreNode_children__properties === void 0 ? void 0 : _hastPreNode_children__properties.className : undefined;
857
- var language = extractLanguageFromClassName(codeProps.className);
858
- if (!language) {
859
- language = extractLanguageFromClassName(codeHastClass);
860
- }
861
- var CodeBlockComponent = userComponents.__codeBlock || userComponents.code;
862
- if (CodeBlockComponent) {
863
- return jsx(CodeBlockComponent, _object_spread_props(_object_spread({}, rest), {
864
- language: language,
865
- children: codeProps.children,
866
- node: hastPreNode
867
- }));
868
- }
869
- return jsxs('pre', _object_spread_props(_object_spread({}, rest), {
870
- children: [
871
- children
872
- ]
873
- }));
874
- },
875
- img: function img(props) {
876
- var _node = props.node, src = props.src, alt = props.alt, width = props.width, height = props.height, _rest = _object_without_properties(props, [
877
- "node",
878
- "src",
879
- "alt",
880
- "width",
881
- "height"
882
- ]);
883
- var imgWidth = width ? Number(width) || width : 400;
884
- return jsx('div', {
885
- 'data-be': 'image',
886
- 'data-testid': 'markdown-image',
887
- style: {
888
- position: 'relative',
889
- userSelect: 'none',
890
- width: '100%',
891
- maxWidth: '100%',
892
- boxSizing: 'border-box'
893
- },
894
- children: jsx('div', {
895
- style: {
896
- padding: 4,
897
- userSelect: 'none',
898
- display: 'flex',
899
- flexDirection: 'column',
900
- width: '100%',
901
- maxWidth: '100%',
902
- boxSizing: 'border-box'
903
- },
904
- 'data-testid': 'image-container',
905
- 'data-be': 'image-container',
906
- children: jsx(Image, {
907
- src: src,
908
- alt: alt || 'image',
909
- width: imgWidth,
910
- height: height,
911
- preview: {
912
- getContainer: function getContainer() {
913
- return document.body;
914
- }
915
- },
916
- referrerPolicy: 'no-referrer',
917
- draggable: false,
918
- style: {
919
- maxWidth: '100%',
920
- height: 'auto',
921
- display: 'block'
922
- }
923
- })
924
- })
925
- });
926
- },
927
- // 视频:对齐 ReadonlyMedia 的 video 处理
928
- video: function video(props) {
929
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
930
- "node",
931
- "children"
932
- ]);
933
- return jsx('div', {
934
- 'data-be': 'media',
935
- 'data-testid': 'markdown-video',
936
- style: {
937
- position: 'relative',
938
- width: '100%',
939
- maxWidth: '100%',
940
- margin: '0.5em 0'
941
- },
942
- children: jsx('video', _object_spread_props(_object_spread({}, rest), {
943
- controls: true,
944
- style: {
945
- maxWidth: '100%',
946
- borderRadius: 8
947
- },
948
- children: children
949
- }))
950
- });
951
- },
952
- // 音频:对齐 ReadonlyMedia 的 audio 处理
953
- audio: function audio(props) {
954
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
955
- "node",
956
- "children"
957
- ]);
958
- return jsx('div', {
959
- 'data-be': 'media',
960
- 'data-testid': 'markdown-audio',
961
- style: {
962
- position: 'relative',
963
- width: '100%',
964
- margin: '0.5em 0'
965
- },
966
- children: jsx('audio', _object_spread_props(_object_spread({}, rest), {
967
- controls: true,
968
- style: {
969
- width: '100%'
970
- },
971
- children: children
972
- }))
973
- });
974
- },
975
- // iframe
976
- iframe: function iframe(props) {
977
- var _node = props.node, rest = _object_without_properties(props, [
978
- "node"
979
- ]);
980
- return jsx('div', {
981
- 'data-testid': 'markdown-iframe',
982
- style: {
983
- position: 'relative',
984
- width: '100%',
985
- margin: '0.5em 0'
986
- },
987
- children: jsx('iframe', _object_spread_props(_object_spread({}, rest), {
988
- style: {
989
- width: '100%',
990
- minHeight: 300,
991
- border: '1px solid var(--color-gray-border-light, #e8e8e8)',
992
- borderRadius: 8
993
- }
994
- }))
995
- });
996
- },
997
- hr: function hr(props) {
998
- var _node = props.node, rest = _object_without_properties(props, [
999
- "node"
1000
- ]);
1001
- return jsx('hr', _object_spread_props(_object_spread({}, rest), {
1002
- 'data-be': 'hr',
1003
- 'data-testid': 'markdown-hr'
1004
- }));
1005
- },
1006
- // 脚注引用 sup > a(remark-gfm 有定义时生成)
1007
- sup: function sup(props) {
1008
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
1009
- "node",
1010
- "children"
1011
- ]);
1012
- return jsx('span', _object_spread_props(_object_spread({}, rest), {
1013
- 'data-fnc': 'fnc',
1014
- 'data-testid': 'markdown-footnote-ref',
1015
- className: "".concat(contentCls, "-fnc"),
1016
- style: {
1017
- fontSize: 12,
1018
- cursor: 'pointer'
1019
- },
1020
- children: children
1021
- }));
1022
- },
1023
- span: function span(props) {
1024
- var _node = props.node, children = props.children, rest = _object_without_properties(props, [
1025
- "node",
1026
- "children"
1027
- ]);
1028
- if (rest['data-fnc'] === 'fnc') {
1029
- return jsx('span', _object_spread_props(_object_spread({}, rest), {
1030
- 'data-testid': 'markdown-footnote-ref',
1031
- className: "".concat(contentCls, "-fnc"),
1032
- style: {
1033
- fontSize: 12,
1034
- cursor: 'pointer'
1035
- },
1036
- children: children
1037
- }));
1038
- }
1039
- return jsx('span', _object_spread_props(_object_spread({}, rest), {
1040
- children: children
1041
- }));
1042
- },
1043
- section: function section(props) {
1044
- var _node = props.node, children = props.children, className = props.className, rest = _object_without_properties(props, [
1045
- "node",
1046
- "children",
1047
- "className"
1048
- ]);
1049
- var isFootnotes = className === 'footnotes' || typeof (rest === null || rest === void 0 ? void 0 : rest['data-footnotes']) !== 'undefined';
1050
- if (isFootnotes) {
1051
- return jsx('div', _object_spread_props(_object_spread({}, rest), {
1052
- 'data-be': 'footnoteDefinition',
1053
- 'data-testid': 'markdown-footnote-section',
1054
- style: {
1055
- fontSize: 12,
1056
- borderTop: '1px solid var(--color-gray-border-light, #e8e8e8)',
1057
- marginTop: 16,
1058
- paddingTop: 8
1059
- },
1060
- children: children
1061
- }));
1062
- }
1063
- return jsx('section', _object_spread_props(_object_spread({}, rest), {
1064
- className: className,
1065
- children: children
1066
- }));
1067
- },
1068
- think: ThinkBlockRendererComponent,
1069
- answer: function answer(props) {
1070
- var _node = props.node, children = props.children;
1071
- return jsx(Fragment, {
1072
- children: children
1073
- });
1074
- }
1075
- }, userComponents);
1076
- };
1077
- /**
1078
- * 在 hast 上标记「最后一个 p」,用于流式时仅该段落播放入场(单块长文时避免全页 p 一起闪)
1079
- */ var markLastParagraphStreamingTail = function markLastParagraphStreamingTail(hast) {
1080
- var paragraphs = [];
1081
- visit(hast, 'element', function(node) {
1082
- if (node.tagName === 'p') {
1083
- paragraphs.push(node);
1084
- }
1085
- });
1086
- var last = paragraphs[paragraphs.length - 1];
1087
- if (last) {
1088
- last.properties = last.properties || {};
1089
- last.properties.dataStreamingTail = true;
1090
- }
1091
- };
1092
- /**
1093
- * 将单个 markdown 片段转为 React 元素(内部函数)
1094
- */ var renderMarkdownBlock = function renderMarkdownBlock(blockContent, processor, components, blockOpts) {
1095
- if (!blockContent.trim()) return null;
1096
- try {
1097
- var mdast = processor.parse(blockContent);
1098
- var hast = processor.runSync(mdast);
1099
- if (blockOpts === null || blockOpts === void 0 ? void 0 : blockOpts.markStreamingTailParagraph) {
1100
- markLastParagraphStreamingTail(hast);
1101
- }
1102
- return toJsxRuntime(hast, {
1103
- Fragment: Fragment,
1104
- jsx: jsx,
1105
- jsxs: jsxs,
1106
- components: components,
1107
- passNode: true
1108
- });
1109
- } catch (unused) {
1110
- return null;
1111
- }
1112
- };
1113
- /**
1114
- * 将 markdown 按块(双换行)拆分,尊重代码围栏边界。
1115
- * 返回的每个块是一个独立的 markdown 片段,可单独解析。
1116
- */ var splitMarkdownBlocks = function splitMarkdownBlocks(content) {
1117
- var lines = content.split('\n');
1118
- var blocks = [];
1119
- var current = [];
1120
- var inFence = false;
1121
- var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
1122
- try {
1123
- for(var _iterator = lines[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
1124
- var line = _step.value;
1125
- var trimmed = line.trimStart();
1126
- if (trimmed.startsWith('```') || trimmed.startsWith('~~~')) {
1127
- inFence = !inFence;
1128
- }
1129
- if (!inFence && line === '' && current.length > 0) {
1130
- var prev = current[current.length - 1];
1131
- if (prev === '') {
1132
- // 触发分割的是「第二个连续空行」,不应并入上一块末尾,否则与单块解析结果字符串不一致、缓存失效
1133
- var withoutTrailingBlank = current.slice(0, -1);
1134
- blocks.push(withoutTrailingBlank.join('\n'));
1135
- current = [];
1136
- continue;
1137
- }
1138
- }
1139
- current.push(line);
1140
- }
1141
- } catch (err) {
1142
- _didIteratorError = true;
1143
- _iteratorError = err;
1144
- } finally{
1145
- try {
1146
- if (!_iteratorNormalCompletion && _iterator.return != null) {
1147
- _iterator.return();
1148
- }
1149
- } finally{
1150
- if (_didIteratorError) {
1151
- throw _iteratorError;
1152
- }
1153
- }
1154
- }
1155
- if (current.length > 0) {
1156
- blocks.push(current.join('\n'));
1157
- }
1158
- return blocks;
1159
- };
1160
- var _BLOCK_CACHE_KEY = Symbol('blockCache');
1161
- /**
1162
- * 将 markdown 字符串转换为 React 元素树的 hook。
1163
- *
1164
- * 性能优化:分块缓存
1165
- * - markdown 按双换行拆分为独立块
1166
- * - 已完成的块(非最后一个)通过内容哈希缓存 React 输出
1167
- * - 每次更新只重新解析变化的块(通常仅最后一个)
1168
- * - 稳定块的 React 元素直接复用,跳过 parse → hast → jsx 全链路
1169
- */ /**
1170
- * 流式场景下,最后一个块每个字符都变化,但大部分变化只是尾部追加。
1171
- * 对最后一个块做节流:只在新增了换行、块级标记、或超过一定字符数时才重新解析。
1172
- */ var LAST_BLOCK_THROTTLE_CHARS = 20;
1173
- var BLOCK_BOUNDARY_TRIGGERS = /[\n`|#>*\-!$[\]]/;
1174
- var shouldReparseLastBlock = function shouldReparseLastBlock(prevSource, newSource, streaming) {
1175
- if (!streaming) return true;
1176
- if (!prevSource) return true;
1177
- if (newSource.length < prevSource.length) return true;
1178
- if (!newSource.startsWith(prevSource)) return true;
1179
- var added = newSource.slice(prevSource.length);
1180
- if (added.length >= LAST_BLOCK_THROTTLE_CHARS) return true;
1181
- if (BLOCK_BOUNDARY_TRIGGERS.test(added)) return true;
1182
- return false;
1183
- };
1184
- export var useMarkdownToReact = function useMarkdownToReact(content, options) {
1185
- var processorRef = useRef(null);
1186
- var blockCacheRef = useRef(new Map());
1187
- var lastBlockRef = useRef(null);
1188
- var prevContentRef = useRef('');
1189
- var processor = useMemo(function() {
1190
- var p = createHastProcessor(options === null || options === void 0 ? void 0 : options.remarkPlugins, options === null || options === void 0 ? void 0 : options.htmlConfig);
1191
- processorRef.current = p;
1192
- return p;
1193
- }, [
1194
- options === null || options === void 0 ? void 0 : options.remarkPlugins,
1195
- options === null || options === void 0 ? void 0 : options.htmlConfig
1196
- ]);
1197
- var prefixCls = (options === null || options === void 0 ? void 0 : options.prefixCls) || 'ant-agentic-md-editor';
1198
- var components = useMemo(function() {
1199
- var userComponents = (options === null || options === void 0 ? void 0 : options.components) || {};
1200
- return buildEditorAlignedComponents(prefixCls, userComponents, options === null || options === void 0 ? void 0 : options.streaming, options === null || options === void 0 ? void 0 : options.linkConfig, options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation);
1201
- }, [
1202
- prefixCls,
1203
- options === null || options === void 0 ? void 0 : options.components,
1204
- options === null || options === void 0 ? void 0 : options.streaming,
1205
- options === null || options === void 0 ? void 0 : options.linkConfig,
1206
- options === null || options === void 0 ? void 0 : options.streamingParagraphAnimation
1207
- ]);
1208
- return useMemo(function() {
1209
- if (!content) {
1210
- prevContentRef.current = '';
1211
- return null;
1212
- }
1213
- var prevContent = prevContentRef.current;
1214
- if (prevContent && content !== prevContent && !content.startsWith(prevContent)) {
1215
- blockCacheRef.current = new Map();
1216
- lastBlockRef.current = null;
1217
- }
1218
- prevContentRef.current = content;
1219
- try {
1220
- var preprocessed = content.replace(new RegExp(JINJA_DOLLAR_PLACEHOLDER, 'g'), '$');
1221
- var blocks = splitMarkdownBlocks(preprocessed);
1222
- if (blocks.length === 0) return null;
1223
- var cache = blockCacheRef.current;
1224
- var newCache = new Map();
1225
- var elements = [];
1226
- var wrapBlockScope = function wrapBlockScope(node, key, animateBlock) {
1227
- return jsx(StreamingAnimationContext.Provider, {
1228
- key: key,
1229
- value: {
1230
- animateBlock: animateBlock
1231
- },
1232
- children: node
1233
- });
1234
- };
1235
- var KEY_PREFIX_LEN = 64;
1236
- for(var i = 0; i < blocks.length; i++){
1237
- var block = blocks[i];
1238
- var isLast = i === blocks.length - 1;
1239
- // 用 index + 内容前 64 字符作 key,保持稳定性:
1240
- // - 末块在流式中节流时,用 lastBlockRef.source 的切片作 key,避免每次追加字符导致 key 变化
1241
- // - 末块变为非末块时,必须与先前 key 一致,否则 ChartBlockRenderer 等会 unmount/remount 闪烁
1242
- // - 因此统一用「实际展示内容」的 slice 作 key,节流时用 lastBlockRef.source
1243
- var contentForKey = isLast && (options === null || options === void 0 ? void 0 : options.streaming) && lastBlockRef.current && !shouldReparseLastBlock(lastBlockRef.current.source, block, options === null || options === void 0 ? void 0 : options.streaming) ? lastBlockRef.current.source.slice(0, KEY_PREFIX_LEN) : block.slice(0, KEY_PREFIX_LEN);
1244
- var stableKey = "b".concat(i, "-").concat(contentForKey);
1245
- if (!isLast) {
1246
- var cached = cache.get(block);
1247
- if (cached && cached.source === block) {
1248
- newCache.set(block, cached);
1249
- elements.push(wrapBlockScope(cached.element, stableKey, false));
1250
- continue;
1251
- }
1252
- }
1253
- // 最后一个块:节流——仅在有意义的变化时重新解析
1254
- if (isLast && lastBlockRef.current) {
1255
- if (!shouldReparseLastBlock(lastBlockRef.current.source, block, options === null || options === void 0 ? void 0 : options.streaming)) {
1256
- newCache.set(block, {
1257
- source: lastBlockRef.current.source,
1258
- element: lastBlockRef.current.element
1259
- });
1260
- elements.push(wrapBlockScope(lastBlockRef.current.element, stableKey, !!(options === null || options === void 0 ? void 0 : options.streaming)));
1261
- continue;
1262
- }
1263
- }
1264
- var element = renderMarkdownBlock(block, processor, components, {
1265
- markStreamingTailParagraph: isLast && !!(options === null || options === void 0 ? void 0 : options.streaming)
1266
- });
1267
- var entry = {
1268
- source: block,
1269
- element: element
1270
- };
1271
- newCache.set(block, entry);
1272
- if (isLast) lastBlockRef.current = entry;
1273
- elements.push(wrapBlockScope(element, stableKey, isLast && !!(options === null || options === void 0 ? void 0 : options.streaming)));
1274
- }
1275
- blockCacheRef.current = newCache;
1276
- return jsxs(Fragment, {
1277
- children: elements
1278
- });
1279
- } catch (error) {
1280
- console.error('Failed to render markdown:', error);
1281
- return null;
1282
- }
1283
- }, [
1284
- content,
1285
- processor,
1286
- components,
1287
- options === null || options === void 0 ? void 0 : options.streaming
1288
- ]);
1289
- };
4
+ import { buildEditorAlignedComponents, createHastProcessor } from "./markdownReactShared";
5
+ import { useStreamingMarkdownReact } from "./streaming/useStreamingMarkdownReact";
6
+ export var useMarkdownToReact = useStreamingMarkdownReact;
1290
7
  /**
1291
8
  * 同步将 markdown 转为 React 元素(非 hook 版本,用于测试或一次性转换)
1292
9
  */ export var markdownToReactSync = function markdownToReactSync(content, components, remarkPlugins, htmlConfig) {