@ant-design/agentic-ui 2.11.2 → 2.12.0

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 (31) hide show
  1. package/dist/Bubble/MessagesContent/BubbleExtra.js +7 -1
  2. package/dist/MarkdownEditor/editor/types/Table.d.ts +1 -0
  3. package/dist/MarkdownEditor/editor/utils/ace.d.ts +22 -105
  4. package/dist/MarkdownEditor/editor/utils/ace.js +328 -106
  5. package/dist/MarkdownEditor/types.d.ts +1 -1
  6. package/dist/MarkdownInputField/AttachmentButton/index.js +5 -3
  7. package/dist/MarkdownInputField/MarkdownInputField.d.ts +32 -0
  8. package/dist/MarkdownInputField/MarkdownInputField.js +26 -8
  9. package/dist/Plugins/chart/ChartRender.js +75 -13
  10. package/dist/Plugins/chart/LineChart/index.js +10 -4
  11. package/dist/Plugins/chart/index.js +17 -5
  12. package/dist/Plugins/chart/utils.d.ts +40 -0
  13. package/dist/Plugins/chart/utils.js +116 -0
  14. package/dist/Plugins/code/CodeUI/Katex/Katex.d.ts +0 -1
  15. package/dist/Plugins/code/CodeUI/Katex/Katex.js +182 -6
  16. package/dist/Plugins/code/components/AceEditor.d.ts +4 -6
  17. package/dist/Plugins/code/components/AceEditor.js +362 -40
  18. package/dist/Plugins/code/loadAceEditor.d.ts +26 -0
  19. package/dist/Plugins/code/loadAceEditor.js +266 -0
  20. package/dist/Plugins/katex/InlineKatex.d.ts +0 -1
  21. package/dist/Plugins/katex/InlineKatex.js +183 -7
  22. package/dist/Plugins/katex/Katex.d.ts +0 -1
  23. package/dist/Plugins/katex/Katex.js +184 -6
  24. package/dist/Plugins/katex/loadKatex.d.ts +18 -0
  25. package/dist/Plugins/katex/loadKatex.js +181 -0
  26. package/dist/Plugins/mermaid/Mermaid.js +315 -113
  27. package/dist/Schema/SchemaEditor/AceEditorWrapper.d.ts +1 -1
  28. package/dist/Schema/SchemaEditor/AceEditorWrapper.js +342 -53
  29. package/dist/Utils/loadCSS.d.ts +31 -0
  30. package/dist/Utils/loadCSS.js +264 -0
  31. package/package.json +1 -1
@@ -383,6 +383,38 @@ export type MarkdownInputFieldProps = {
383
383
  * ```
384
384
  */
385
385
  isShowBackTo?: boolean;
386
+ /**
387
+ * 输入框的最大高度(像素)
388
+ * @description 设置输入框的最大高度,超出部分将显示滚动条。如果同时设置了 style.maxHeight,则以该属性优先
389
+ * @example
390
+ * ```tsx
391
+ * <MarkdownInputField maxHeight={300} />
392
+ * ```
393
+ */
394
+ maxHeight?: number | string;
395
+ /**
396
+ * 输入文本的最大字符数限制
397
+ * @description 限制输入文本的最大字符数,超出限制后将无法继续输入
398
+ * @example
399
+ * ```tsx
400
+ * <MarkdownInputField maxLength={500} />
401
+ * ```
402
+ */
403
+ maxLength?: number;
404
+ /**
405
+ * 当输入达到最大长度限制时的回调函数
406
+ * @description 当用户尝试输入超出最大长度限制的内容时触发
407
+ * @example
408
+ * ```tsx
409
+ * <MarkdownInputField
410
+ * maxLength={100}
411
+ * onMaxLengthExceeded={() => {
412
+ * message.warning('已达到最大字数限制');
413
+ * }}
414
+ * />
415
+ * ```
416
+ */
417
+ onMaxLengthExceeded?: (value: string) => void;
386
418
  };
387
419
  /**
388
420
  * MarkdownInputField 组件 - Markdown输入字段组件
@@ -314,7 +314,7 @@ import { useVoiceInputManager } from "./VoiceInputManager";
314
314
  "onFocus",
315
315
  "isShowTopOperatingArea"
316
316
  ]);
317
- var _props_style, _props_attachment, _props_style1, _props_attachment1, _props_attachment2, _props_attachment3, _props_enlargeable, _props_refinePrompt, _props_style2, _props_attachment4, _props_attachment5, _props_enlargeable1, _props_refinePrompt1, _props_enlargeable2, _props_enlargeable3;
317
+ var _props_style, _props_attachment, _props_attachment1, _props_attachment2, _props_attachment3, _props_enlargeable, _props_refinePrompt, _props_style1, _props_attachment4, _props_attachment5, _props_enlargeable1, _props_refinePrompt1, _props_enlargeable2, _props_enlargeable3;
318
318
  var getPrefixCls = useContext(ConfigProvider.ConfigContext).getPrefixCls;
319
319
  var baseCls = getPrefixCls('agentic-md-input-field');
320
320
  var _useStyle = useStyle(baseCls), wrapSSR = _useStyle.wrapSSR, hashId = _useStyle.hashId;
@@ -349,10 +349,13 @@ import { useVoiceInputManager } from "./VoiceInputManager";
349
349
  ]);
350
350
  var collapsedHeight = useMemo(function() {
351
351
  var _props_style;
352
- var mh = (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.maxHeight;
353
- var base = typeof mh === 'number' ? mh : mh ? parseFloat(String(mh)) || 114 : 114;
352
+ var _props_maxHeight;
353
+ // 优先使用 maxHeight prop,其次使用 style.maxHeight,最后使用默认值
354
+ var maxHeightValue = (_props_maxHeight = props.maxHeight) !== null && _props_maxHeight !== void 0 ? _props_maxHeight : (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.maxHeight;
355
+ var base = typeof maxHeightValue === 'number' ? maxHeightValue : maxHeightValue ? parseFloat(String(maxHeightValue)) || 114 : 114;
354
356
  return base;
355
357
  }, [
358
+ props.maxHeight,
356
359
  (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.maxHeight,
357
360
  (_props_attachment = props.attachment) === null || _props_attachment === void 0 ? void 0 : _props_attachment.enable
358
361
  ]);
@@ -361,7 +364,7 @@ import { useVoiceInputManager } from "./VoiceInputManager";
361
364
  var extra = ((_props_attachment = props.attachment) === null || _props_attachment === void 0 ? void 0 : _props_attachment.enable) ? 90 : 0;
362
365
  return collapsedHeight + extra;
363
366
  }, [
364
- (_props_style1 = props.style) === null || _props_style1 === void 0 ? void 0 : _props_style1.maxHeight,
367
+ collapsedHeight,
365
368
  (_props_attachment1 = props.attachment) === null || _props_attachment1 === void 0 ? void 0 : _props_attachment1.enable
366
369
  ]);
367
370
  var _useMergedState1 = _sliced_to_array(useMergedState(undefined, {
@@ -396,7 +399,7 @@ import { useVoiceInputManager } from "./VoiceInputManager";
396
399
  hasRefineAction,
397
400
  isMultiRowLayout,
398
401
  totalActionCount,
399
- (_props_style2 = props.style) === null || _props_style2 === void 0 ? void 0 : _props_style2.minHeight
402
+ (_props_style1 = props.style) === null || _props_style1 === void 0 ? void 0 : _props_style1.minHeight
400
403
  ]);
401
404
  // 文件上传管理
402
405
  var _useFileUploadManager = useFileUploadManager({
@@ -714,7 +717,7 @@ import { useVoiceInputManager } from "./VoiceInputManager";
714
717
  minHeight: computedMinHeight,
715
718
  cursor: isLoading || props.disabled ? 'not-allowed' : 'auto',
716
719
  opacity: props.disabled ? 0.5 : 1,
717
- maxHeight: isEnlarged ? 'none' : "min(".concat(collapsedHeightPx, "px,100%)"),
720
+ maxHeight: isEnlarged ? 'none' : props.maxHeight !== undefined ? typeof props.maxHeight === 'number' ? "".concat(props.maxHeight, "px") : props.maxHeight : "min(".concat(collapsedHeightPx, "px,100%)"),
718
721
  transition: 'height, max-height 0.3s,border-radius 0.3s,box-shadow 0.3s,transform 0.3s,opacity 0.3s,background 0.3s'
719
722
  }),
720
723
  tabIndex: 1,
@@ -733,8 +736,10 @@ import { useVoiceInputManager } from "./VoiceInputManager";
733
736
  borderTopRightRadius: 'inherit',
734
737
  maxHeight: isEnlarged ? 'none' : function() {
735
738
  var _props_style, _props_attachment;
736
- var mh = (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.maxHeight;
737
- var base = typeof mh === 'number' ? mh : mh ? parseFloat(String(mh)) || 400 : 400;
739
+ var _props_maxHeight;
740
+ // 优先使用 maxHeight prop,其次使用 style.maxHeight,最后使用默认值
741
+ var maxHeightValue = (_props_maxHeight = props.maxHeight) !== null && _props_maxHeight !== void 0 ? _props_maxHeight : (_props_style = props.style) === null || _props_style === void 0 ? void 0 : _props_style.maxHeight;
742
+ var base = typeof maxHeightValue === 'number' ? maxHeightValue : maxHeightValue ? parseFloat(String(maxHeightValue)) || 400 : 400;
738
743
  var extra = ((_props_attachment = props.attachment) === null || _props_attachment === void 0 ? void 0 : _props_attachment.enable) ? 90 : 0;
739
744
  return "min(".concat(base + extra, "px)");
740
745
  }(),
@@ -778,6 +783,19 @@ import { useVoiceInputManager } from "./VoiceInputManager";
778
783
  initValue: props.value,
779
784
  onChange: function(value) {
780
785
  var _props_onChange;
786
+ // 检查并限制字符数
787
+ if (props.maxLength !== undefined) {
788
+ if (value.length > props.maxLength) {
789
+ var _props_onChange1, _props_onMaxLengthExceeded, // 更新编辑器内容以反映截断后的值
790
+ _markdownEditorRef_current_store, _markdownEditorRef_current;
791
+ var truncatedValue = value.slice(0, props.maxLength);
792
+ setValue(truncatedValue);
793
+ (_props_onChange1 = props.onChange) === null || _props_onChange1 === void 0 ? void 0 : _props_onChange1.call(props, truncatedValue);
794
+ (_props_onMaxLengthExceeded = props.onMaxLengthExceeded) === null || _props_onMaxLengthExceeded === void 0 ? void 0 : _props_onMaxLengthExceeded.call(props, value);
795
+ (_markdownEditorRef_current = markdownEditorRef.current) === null || _markdownEditorRef_current === void 0 ? void 0 : (_markdownEditorRef_current_store = _markdownEditorRef_current.store) === null || _markdownEditorRef_current_store === void 0 ? void 0 : _markdownEditorRef_current_store.setMDContent(truncatedValue);
796
+ return;
797
+ }
798
+ }
781
799
  setValue(value);
782
800
  (_props_onChange = props.onChange) === null || _props_onChange === void 0 ? void 0 : _props_onChange.call(props, value);
783
801
  },
@@ -229,7 +229,7 @@ import { Loading } from "../../Components/Loading";
229
229
  import { useIntersectionOnce } from "../../Hooks/useIntersectionOnce";
230
230
  import { I18nContext } from "../../I18n";
231
231
  import { loadChartRuntime } from "./loadChartRuntime";
232
- import { isNotEmpty, toNumber } from "./utils";
232
+ import { debounce, getDataHash, isConfigEqual, isNotEmpty, toNumber } from "./utils";
233
233
  /**
234
234
  * @fileoverview 图表渲染组件文件
235
235
  *
@@ -624,6 +624,8 @@ import { isNotEmpty, toNumber } from "./utils";
624
624
  * - 提供图表属性工具栏
625
625
  * - 使用 React.lazy 和 Suspense 实现代码分割
626
626
  */ export var ChartRender = function(props) {
627
+ var // 对于 rest 对象,使用浅比较
628
+ _config_rest, _config_rest1, _config_rest2;
627
629
  var _useState = _sliced_to_array(useState(function() {
628
630
  return props.chartType;
629
631
  }), 2), chartType = _useState[0], setChartType = _useState[1];
@@ -635,6 +637,23 @@ import { isNotEmpty, toNumber } from "./utils";
635
637
  var _useState2 = _sliced_to_array(useState(0), 2), renderKey = _useState2[0], setRenderKey = _useState2[1];
636
638
  var containerRef = React.useRef(null);
637
639
  var isIntersecting = useIntersectionOnce(containerRef);
640
+ // 用于缓存上一次的数据和配置,避免不必要的重新计算
641
+ var prevDataRef = React.useRef({
642
+ dataHash: '',
643
+ config: null
644
+ });
645
+ // 计算数据哈希值,用于依赖项比较
646
+ var dataHash = React.useMemo(function() {
647
+ return getDataHash(chartData || []);
648
+ }, [
649
+ chartData
650
+ ]);
651
+ // 防抖更新 renderKey,避免流式数据频繁更新导致的性能问题
652
+ var debouncedUpdateRenderKeyRef = React.useRef(debounce(function() {
653
+ setRenderKey(function(k) {
654
+ return k + 1;
655
+ });
656
+ }, 300));
638
657
  var renderDescriptionsFallback = React.useMemo(function() {
639
658
  var _config_columns;
640
659
  var columnCount = (config === null || config === void 0 ? void 0 : (_config_columns = config.columns) === null || _config_columns === void 0 ? void 0 : _config_columns.length) || 0;
@@ -706,8 +725,15 @@ import { isNotEmpty, toNumber } from "./utils";
706
725
  } : {});
707
726
  });
708
727
  }, [
709
- JSON.stringify(chartData),
710
- JSON.stringify(config),
728
+ // 使用更高效的依赖项比较
729
+ dataHash,
730
+ config === null || config === void 0 ? void 0 : config.x,
731
+ config === null || config === void 0 ? void 0 : config.y,
732
+ config === null || config === void 0 ? void 0 : config.height,
733
+ config === null || config === void 0 ? void 0 : config.index,
734
+ config === null || config === void 0 ? void 0 : (_config_rest = config.rest) === null || _config_rest === void 0 ? void 0 : _config_rest.stacked,
735
+ config === null || config === void 0 ? void 0 : (_config_rest1 = config.rest) === null || _config_rest1 === void 0 ? void 0 : _config_rest1.showLegend,
736
+ config === null || config === void 0 ? void 0 : (_config_rest2 = config.rest) === null || _config_rest2 === void 0 ? void 0 : _config_rest2.showGrid,
711
737
  title,
712
738
  groupBy,
713
739
  colorLegend,
@@ -730,8 +756,12 @@ import { isNotEmpty, toNumber } from "./utils";
730
756
  } : {});
731
757
  });
732
758
  }, [
733
- JSON.stringify(chartData),
734
- JSON.stringify(config),
759
+ // 使用更高效的依赖项比较
760
+ dataHash,
761
+ config === null || config === void 0 ? void 0 : config.x,
762
+ config === null || config === void 0 ? void 0 : config.y,
763
+ config === null || config === void 0 ? void 0 : config.height,
764
+ config === null || config === void 0 ? void 0 : config.index,
735
765
  title,
736
766
  groupBy,
737
767
  filterBy
@@ -741,6 +771,39 @@ import { isNotEmpty, toNumber } from "./utils";
741
771
  }, [
742
772
  props.chartType
743
773
  ]);
774
+ // 监听数据变化,使用防抖更新渲染键
775
+ React.useEffect(function() {
776
+ var configChanged = !isConfigEqual(prevDataRef.current.config, config);
777
+ var groupByChanged = prevDataRef.current.groupBy !== groupBy;
778
+ var colorLegendChanged = prevDataRef.current.colorLegend !== colorLegend;
779
+ var filterByChanged = prevDataRef.current.filterBy !== filterBy;
780
+ var hasChanged = prevDataRef.current.dataHash !== dataHash || configChanged || groupByChanged || colorLegendChanged || filterByChanged;
781
+ if (hasChanged) {
782
+ // 更新缓存
783
+ prevDataRef.current = {
784
+ dataHash: dataHash,
785
+ config: config,
786
+ groupBy: groupBy,
787
+ colorLegend: colorLegend,
788
+ filterBy: filterBy
789
+ };
790
+ // 对于流式数据,使用防抖更新,避免频繁渲染
791
+ if (prevDataRef.current.dataHash !== dataHash) {
792
+ debouncedUpdateRenderKeyRef.current();
793
+ } else {
794
+ // 配置变化时立即更新
795
+ setRenderKey(function(k) {
796
+ return k + 1;
797
+ });
798
+ }
799
+ }
800
+ }, [
801
+ dataHash,
802
+ config,
803
+ groupBy,
804
+ colorLegend,
805
+ filterBy
806
+ ]);
744
807
  /**
745
808
  * 图表配置
746
809
  */ var getChartPopover = function() {
@@ -884,12 +947,7 @@ import { isNotEmpty, toNumber } from "./utils";
884
947
  })
885
948
  })))))
886
949
  }, /*#__PURE__*/ React.createElement(ActionIconBox, {
887
- title: (i18n === null || i18n === void 0 ? void 0 : (_i18n_locale3 = i18n.locale) === null || _i18n_locale3 === void 0 ? void 0 : _i18n_locale3.configChart) || '配置图表',
888
- onClick: function() {
889
- return setRenderKey(function(k) {
890
- return k + 1;
891
- });
892
- }
950
+ title: (i18n === null || i18n === void 0 ? void 0 : (_i18n_locale3 = i18n.locale) === null || _i18n_locale3 === void 0 ? void 0 : _i18n_locale3.configChart) || '配置图表'
893
951
  }, /*#__PURE__*/ React.createElement(SettingOutlined, {
894
952
  style: {
895
953
  color: 'rgba(0, 25, 61, 0.3255)'
@@ -992,8 +1050,12 @@ import { isNotEmpty, toNumber } from "./utils";
992
1050
  return null;
993
1051
  }, [
994
1052
  chartType,
995
- JSON.stringify(chartData),
996
- JSON.stringify(config),
1053
+ // 使用更高效的依赖项
1054
+ dataHash,
1055
+ config === null || config === void 0 ? void 0 : config.x,
1056
+ config === null || config === void 0 ? void 0 : config.y,
1057
+ config === null || config === void 0 ? void 0 : config.height,
1058
+ config === null || config === void 0 ? void 0 : config.index,
997
1059
  renderKey,
998
1060
  toolBar,
999
1061
  convertDonutData,
@@ -142,7 +142,7 @@ import React, { useContext, useEffect, useMemo, useRef, useState } from "react";
142
142
  import { Line } from "react-chartjs-2";
143
143
  import { ChartContainer, ChartFilter, ChartStatistic, ChartToolBar, downloadChart } from "../components";
144
144
  import { defaultColorList } from "../const";
145
- import { extractAndSortXValues, findDataPointByXValue } from "../utils";
145
+ import { extractAndSortXValues, findDataPointByXValue, getDataHash } from "../utils";
146
146
  import { useStyle } from "./style";
147
147
  var lineChartComponentsRegistered = false;
148
148
  var LineChart = function(_param) {
@@ -179,6 +179,12 @@ var LineChart = function(_param) {
179
179
  return undefined;
180
180
  }, []);
181
181
  var safeData = Array.isArray(data) ? data : [];
182
+ // 使用数据哈希来优化依赖项比较
183
+ var dataHash = useMemo(function() {
184
+ return getDataHash(safeData);
185
+ }, [
186
+ safeData
187
+ ]);
182
188
  // 响应式尺寸计算
183
189
  var _useState = _sliced_to_array(useState(typeof window !== 'undefined' ? window.innerWidth : 768), 2), windowWidth = _useState[0], setWindowWidth = _useState[1];
184
190
  var isMobile = windowWidth <= 768;
@@ -217,7 +223,7 @@ var LineChart = function(_param) {
217
223
  }))).filter(Boolean);
218
224
  return uniqueCategories;
219
225
  }, [
220
- safeData
226
+ dataHash
221
227
  ]);
222
228
  // 从数据中提取 filterLabel,过滤掉 undefined 值
223
229
  var validFilterLabels = useMemo(function() {
@@ -227,7 +233,7 @@ var LineChart = function(_param) {
227
233
  return filterLabel !== undefined;
228
234
  });
229
235
  }, [
230
- safeData
236
+ dataHash
231
237
  ]);
232
238
  var filterLabels = useMemo(function() {
233
239
  return validFilterLabels.length > 0 ? _to_consumable_array(new Set(validFilterLabels)) : undefined;
@@ -259,7 +265,7 @@ var LineChart = function(_param) {
259
265
  return item.x !== null && item.x !== undefined;
260
266
  });
261
267
  }, [
262
- safeData,
268
+ dataHash,
263
269
  selectedFilter,
264
270
  filterLabels,
265
271
  selectedFilterLabel
@@ -130,6 +130,7 @@ import { ErrorBoundary } from "../../MarkdownEditor/editor/elements/ErrorBoundar
130
130
  import { useEditorStore } from "../../MarkdownEditor/editor/store";
131
131
  import { DragHandle } from "../../MarkdownEditor/editor/tools/DragHandle";
132
132
  import { ChartRender } from "./ChartRender";
133
+ import { getDataHash } from "./utils";
133
134
  /**
134
135
  * @fileoverview 图表插件主入口文件
135
136
  *
@@ -269,10 +270,17 @@ export { ChartFilter, ChartToolBar, downloadChart } from "./components";
269
270
  * - 集成编辑器状态管理
270
271
  * - 提供响应式布局
271
272
  */ export var ChartElement = function(props) {
272
- var _node_otherProps, _node_otherProps1, _node_otherProps2;
273
+ var _node_otherProps, _node_otherProps1, _node_otherProps2, _node_otherProps3, _node_otherProps4, _node_otherProps_columns, _node_otherProps5;
273
274
  var _useEditorStore = useEditorStore(), store = _useEditorStore.store, readonly = _useEditorStore.readonly, markdownContainerRef = _useEditorStore.markdownContainerRef, rootContainer = _useEditorStore.rootContainer;
274
275
  var editor = useSlate();
275
276
  var node = props.element, attributes = props.attributes, children = props.children;
277
+ // 使用更高效的依赖项比较,避免 JSON.stringify 的性能开销
278
+ var dataSourceHash = useMemo(function() {
279
+ var _node_otherProps;
280
+ return getDataHash(((_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource) || []);
281
+ }, [
282
+ (_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource
283
+ ]);
276
284
  var chartData = useMemo(function() {
277
285
  var _node_otherProps_dataSource, _node_otherProps;
278
286
  return ((_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : (_node_otherProps_dataSource = _node_otherProps.dataSource) === null || _node_otherProps_dataSource === void 0 ? void 0 : _node_otherProps_dataSource.map(function(item) {
@@ -281,12 +289,13 @@ export { ChartFilter, ChartToolBar, downloadChart } from "./components";
281
289
  });
282
290
  })) || [];
283
291
  }, [
284
- (_node_otherProps = node.otherProps) === null || _node_otherProps === void 0 ? void 0 : _node_otherProps.dataSource
292
+ dataSourceHash,
293
+ (_node_otherProps1 = node.otherProps) === null || _node_otherProps1 === void 0 ? void 0 : _node_otherProps1.dataSource
285
294
  ]);
286
- var columns = ((_node_otherProps1 = node.otherProps) === null || _node_otherProps1 === void 0 ? void 0 : _node_otherProps1.columns) || [];
295
+ var columns = ((_node_otherProps2 = node.otherProps) === null || _node_otherProps2 === void 0 ? void 0 : _node_otherProps2.columns) || [];
287
296
  var _React_useState = _sliced_to_array(React.useState(2), 2), columnLength = _React_useState[0], setColumnLength = _React_useState[1];
288
297
  var config = [
289
- ((_node_otherProps2 = node.otherProps) === null || _node_otherProps2 === void 0 ? void 0 : _node_otherProps2.config) || node.otherProps
298
+ ((_node_otherProps3 = node.otherProps) === null || _node_otherProps3 === void 0 ? void 0 : _node_otherProps3.config) || node.otherProps
290
299
  ].flat(1);
291
300
  var htmlRef = React.useRef(null);
292
301
  var _React_useState1 = _sliced_to_array(React.useState(256), 2), minWidth = _React_useState1[0], setMinWidth = _React_useState1[1];
@@ -463,7 +472,10 @@ export { ChartFilter, ChartToolBar, downloadChart } from "./components";
463
472
  }))))));
464
473
  }, [
465
474
  attributes,
466
- JSON.stringify(node.otherProps),
475
+ // 使用更高效的依赖项比较
476
+ dataSourceHash,
477
+ (_node_otherProps4 = node.otherProps) === null || _node_otherProps4 === void 0 ? void 0 : _node_otherProps4.config,
478
+ (_node_otherProps5 = node.otherProps) === null || _node_otherProps5 === void 0 ? void 0 : (_node_otherProps_columns = _node_otherProps5.columns) === null || _node_otherProps_columns === void 0 ? void 0 : _node_otherProps_columns.length,
467
479
  editor,
468
480
  columnLength,
469
481
  readonly,
@@ -246,3 +246,43 @@ export declare const toNumber: (val: any, fallback: number) => number;
246
246
  * @since 1.0.0
247
247
  */
248
248
  export declare const isNotEmpty: (val: any) => boolean;
249
+ /**
250
+ * 生成数据数组的快速哈希值
251
+ *
252
+ * 用于优化 useMemo 的依赖项比较,避免使用 JSON.stringify 的性能开销。
253
+ * 通过比较数组长度和最后一个元素的引用来快速判断数据是否变化。
254
+ * 适用于流式数据场景,当数据频繁追加时性能更好。
255
+ *
256
+ * @param {any[]} data - 数据数组
257
+ * @returns {string} 哈希值字符串
258
+ *
259
+ * @example
260
+ * ```typescript
261
+ * const hash1 = getDataHash([{ x: 1, y: 2 }]);
262
+ * const hash2 = getDataHash([{ x: 1, y: 2 }, { x: 3, y: 4 }]);
263
+ * // hash1 !== hash2
264
+ * ```
265
+ *
266
+ * @since 1.0.0
267
+ */
268
+ export declare const getDataHash: (data: any[]) => string;
269
+ /**
270
+ * 深度比较两个配置对象的关键字段
271
+ *
272
+ * 用于优化 useMemo 的依赖项比较,只比较配置的关键字段,
273
+ * 避免对整个配置对象进行深度比较的性能开销。
274
+ *
275
+ * @param {any} config1 - 第一个配置对象
276
+ * @param {any} config2 - 第二个配置对象
277
+ * @returns {boolean} 是否相等
278
+ *
279
+ * @example
280
+ * ```typescript
281
+ * const config1 = { x: 'date', y: 'value', height: 400 };
282
+ * const config2 = { x: 'date', y: 'value', height: 400 };
283
+ * isConfigEqual(config1, config2); // true
284
+ * ```
285
+ *
286
+ * @since 1.0.0
287
+ */
288
+ export declare const isConfigEqual: (config1: any, config2: any) => boolean;
@@ -320,3 +320,119 @@ var intl = new Intl.NumberFormat('en-US', {
320
320
  */ export var isNotEmpty = function(val) {
321
321
  return val !== null && val !== undefined;
322
322
  };
323
+ /**
324
+ * 生成数据数组的快速哈希值
325
+ *
326
+ * 用于优化 useMemo 的依赖项比较,避免使用 JSON.stringify 的性能开销。
327
+ * 通过比较数组长度和最后一个元素的引用来快速判断数据是否变化。
328
+ * 适用于流式数据场景,当数据频繁追加时性能更好。
329
+ *
330
+ * @param {any[]} data - 数据数组
331
+ * @returns {string} 哈希值字符串
332
+ *
333
+ * @example
334
+ * ```typescript
335
+ * const hash1 = getDataHash([{ x: 1, y: 2 }]);
336
+ * const hash2 = getDataHash([{ x: 1, y: 2 }, { x: 3, y: 4 }]);
337
+ * // hash1 !== hash2
338
+ * ```
339
+ *
340
+ * @since 1.0.0
341
+ */ export var getDataHash = function(data) {
342
+ if (!Array.isArray(data) || data.length === 0) {
343
+ return "0-".concat((data === null || data === void 0 ? void 0 : data.length) || 0);
344
+ }
345
+ // 使用长度和最后一个元素的引用作为快速哈希
346
+ // 对于流式数据,通常只有新增,所以比较最后一个元素即可
347
+ var lastItem = data[data.length - 1];
348
+ var firstItem = data[0];
349
+ // 使用简单的哈希:长度 + 首尾元素的简单标识
350
+ var firstKey = firstItem ? Object.keys(firstItem).join(',') : '';
351
+ var lastKey = lastItem ? Object.keys(lastItem).join(',') : '';
352
+ return "".concat(data.length, "-").concat(firstKey, "-").concat(lastKey);
353
+ };
354
+ /**
355
+ * 深度比较两个配置对象的关键字段
356
+ *
357
+ * 用于优化 useMemo 的依赖项比较,只比较配置的关键字段,
358
+ * 避免对整个配置对象进行深度比较的性能开销。
359
+ *
360
+ * @param {any} config1 - 第一个配置对象
361
+ * @param {any} config2 - 第二个配置对象
362
+ * @returns {boolean} 是否相等
363
+ *
364
+ * @example
365
+ * ```typescript
366
+ * const config1 = { x: 'date', y: 'value', height: 400 };
367
+ * const config2 = { x: 'date', y: 'value', height: 400 };
368
+ * isConfigEqual(config1, config2); // true
369
+ * ```
370
+ *
371
+ * @since 1.0.0
372
+ */ export var isConfigEqual = function(config1, config2) {
373
+ if (config1 === config2) return true;
374
+ if (!config1 || !config2) return false;
375
+ var keys1 = Object.keys(config1);
376
+ var keys2 = Object.keys(config2);
377
+ if (keys1.length !== keys2.length) return false;
378
+ // 只比较关键字段
379
+ var keyFields = [
380
+ 'x',
381
+ 'y',
382
+ 'height',
383
+ 'index',
384
+ 'rest'
385
+ ];
386
+ var _iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
387
+ try {
388
+ for(var _iterator = keyFields[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
389
+ var key = _step.value;
390
+ if (config1[key] !== config2[key]) {
391
+ // 对于 rest 对象,进行浅比较
392
+ if (key === 'rest' && config1[key] && config2[key]) {
393
+ var rest1 = config1[key];
394
+ var rest2 = config2[key];
395
+ var restKeys1 = Object.keys(rest1);
396
+ var restKeys2 = Object.keys(rest2);
397
+ if (restKeys1.length !== restKeys2.length) return false;
398
+ var _iteratorNormalCompletion1 = true, _didIteratorError1 = false, _iteratorError1 = undefined;
399
+ try {
400
+ for(var _iterator1 = restKeys1[Symbol.iterator](), _step1; !(_iteratorNormalCompletion1 = (_step1 = _iterator1.next()).done); _iteratorNormalCompletion1 = true){
401
+ var restKey = _step1.value;
402
+ if (rest1[restKey] !== rest2[restKey]) return false;
403
+ }
404
+ } catch (err) {
405
+ _didIteratorError1 = true;
406
+ _iteratorError1 = err;
407
+ } finally{
408
+ try {
409
+ if (!_iteratorNormalCompletion1 && _iterator1.return != null) {
410
+ _iterator1.return();
411
+ }
412
+ } finally{
413
+ if (_didIteratorError1) {
414
+ throw _iteratorError1;
415
+ }
416
+ }
417
+ }
418
+ } else {
419
+ return false;
420
+ }
421
+ }
422
+ }
423
+ } catch (err) {
424
+ _didIteratorError = true;
425
+ _iteratorError = err;
426
+ } finally{
427
+ try {
428
+ if (!_iteratorNormalCompletion && _iterator.return != null) {
429
+ _iterator.return();
430
+ }
431
+ } finally{
432
+ if (_didIteratorError) {
433
+ throw _iteratorError;
434
+ }
435
+ }
436
+ }
437
+ return true;
438
+ };
@@ -1,6 +1,5 @@
1
1
  import React from 'react';
2
2
  import { CodeNode } from '../../../../MarkdownEditor/el';
3
- import './katex.min.css';
4
3
  export declare const Katex: (props: {
5
4
  el?: CodeNode;
6
5
  }) => React.JSX.Element;