@lobehub/ui 1.168.16 → 1.168.18

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 (34) hide show
  1. package/es/Highlighter/SyntaxHighlighter/index.js +10 -9
  2. package/es/Hotkey/index.d.ts +2 -0
  3. package/es/Hotkey/index.js +3 -1
  4. package/es/Markdown/Typography.d.ts +5 -5
  5. package/es/Markdown/Typography.js +4 -3
  6. package/es/Markdown/index.d.ts +1 -1
  7. package/es/Markdown/index.js +166 -90
  8. package/es/Markdown/markdown.style.d.ts +1 -18
  9. package/es/Markdown/markdown.style.js +19 -19
  10. package/es/Markdown/style.d.ts +1 -6
  11. package/es/Markdown/style.js +4 -12
  12. package/es/Mermaid/{Controls.js → components/Controls.js} +1 -1
  13. package/es/Mermaid/components/MermaidContainer.d.ts +5 -0
  14. package/es/Mermaid/components/MermaidContainer.js +43 -0
  15. package/es/Mermaid/components/MermaidZoomableContainer.d.ts +5 -0
  16. package/es/Mermaid/components/MermaidZoomableContainer.js +21 -0
  17. package/es/Mermaid/components/style.d.ts +3 -0
  18. package/es/Mermaid/components/style.js +12 -0
  19. package/es/Mermaid/index.js +9 -7
  20. package/es/Swatches/index.d.ts +2 -1
  21. package/es/Swatches/index.js +34 -22
  22. package/es/Swatches/style.js +2 -2
  23. package/es/components.d.ts +2 -4
  24. package/es/components.js +2 -4
  25. package/es/hooks/useHighlight.d.ts +2 -1
  26. package/es/hooks/useHighlight.js +119 -40
  27. package/es/hooks/useMermaid.d.ts +9 -0
  28. package/es/{Mermaid → hooks}/useMermaid.js +137 -73
  29. package/es/mdx/Mdx/index.js +1 -1
  30. package/es/utils/genCdnUrl.d.ts +3 -0
  31. package/es/utils/genCdnUrl.js +3 -1
  32. package/package.json +6 -6
  33. package/es/Mermaid/useMermaid.d.ts +0 -3
  34. /package/es/Mermaid/{Controls.d.ts → components/Controls.d.ts} +0 -0
@@ -0,0 +1,43 @@
1
+ import { kebabCase } from 'lodash-es';
2
+ import { Loader2 } from 'lucide-react';
3
+ import { memo, useId } from 'react';
4
+ import { Center, Flexbox } from 'react-layout-kit';
5
+ import Icon from "../../Icon";
6
+ import { useMermaid, useMermaidInit } from "../../hooks/useMermaid";
7
+ import { useStyles } from "./style";
8
+ import { jsx as _jsx } from "react/jsx-runtime";
9
+ import { Fragment as _Fragment } from "react/jsx-runtime";
10
+ import { jsxs as _jsxs } from "react/jsx-runtime";
11
+ var MermaidContainer = /*#__PURE__*/memo(function (_ref) {
12
+ var _ref$children = _ref.children,
13
+ children = _ref$children === void 0 ? '' : _ref$children;
14
+ var _useStyles = useStyles(),
15
+ styles = _useStyles.styles;
16
+ var id = useId();
17
+ var mermaidId = kebabCase("mermaid-".concat(id));
18
+ useMermaidInit();
19
+ var _useMermaid = useMermaid(mermaidId, children),
20
+ data = _useMermaid.data,
21
+ isLoading = _useMermaid.isLoading;
22
+ if (!data) return null;
23
+ return /*#__PURE__*/_jsxs(_Fragment, {
24
+ children: [/*#__PURE__*/_jsx(Center, {
25
+ as: 'pre',
26
+ dangerouslySetInnerHTML: {
27
+ __html: data
28
+ },
29
+ id: "mermaid-".concat(id)
30
+ }), isLoading && /*#__PURE__*/_jsx(Flexbox, {
31
+ align: 'center',
32
+ className: styles.loading,
33
+ gap: 8,
34
+ horizontal: true,
35
+ justify: 'center',
36
+ children: /*#__PURE__*/_jsx(Icon, {
37
+ icon: Loader2,
38
+ spin: true
39
+ })
40
+ })]
41
+ });
42
+ });
43
+ export default MermaidContainer;
@@ -0,0 +1,5 @@
1
+ /// <reference types="react" />
2
+ declare const MermaidZoomableContainer: import("react").NamedExoticComponent<{
3
+ children?: string | undefined;
4
+ }>;
5
+ export default MermaidZoomableContainer;
@@ -0,0 +1,21 @@
1
+ import { memo } from 'react';
2
+ import { TransformComponent, TransformWrapper } from 'react-zoom-pan-pinch';
3
+ import Controls from "./Controls";
4
+ import MermaidContainer from "./MermaidContainer";
5
+ import { jsx as _jsx } from "react/jsx-runtime";
6
+ import { jsxs as _jsxs } from "react/jsx-runtime";
7
+ var MermaidZoomableContainer = /*#__PURE__*/memo(function (_ref) {
8
+ var children = _ref.children;
9
+ return /*#__PURE__*/_jsxs(TransformWrapper, {
10
+ children: [/*#__PURE__*/_jsx(Controls, {}), /*#__PURE__*/_jsx(TransformComponent, {
11
+ wrapperStyle: {
12
+ minHeight: 240,
13
+ width: '100%'
14
+ },
15
+ children: /*#__PURE__*/_jsx(MermaidContainer, {
16
+ children: children
17
+ })
18
+ })]
19
+ });
20
+ });
21
+ export default MermaidZoomableContainer;
@@ -0,0 +1,3 @@
1
+ export declare const useStyles: (props?: unknown) => import("antd-style").ReturnStyles<{
2
+ loading: string;
3
+ }>;
@@ -0,0 +1,12 @@
1
+ var _templateObject;
2
+ function _taggedTemplateLiteral(strings, raw) { if (!raw) { raw = strings.slice(0); } return Object.freeze(Object.defineProperties(strings, { raw: { value: Object.freeze(raw) } })); }
3
+ import { createStyles } from 'antd-style';
4
+ export var useStyles = createStyles(function (_ref) {
5
+ var css = _ref.css,
6
+ token = _ref.token,
7
+ cx = _ref.cx,
8
+ stylish = _ref.stylish;
9
+ return {
10
+ loading: cx(stylish.blur, css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n position: absolute;\n z-index: 10;\n inset-block-start: 0;\n inset-inline-end: 0;\n\n height: 34px;\n padding-block: 0;\n padding-inline: 8px;\n\n font-family: ", ";\n color: ", ";\n\n border-radius: ", ";\n "])), token.fontFamilyCode, token.colorTextTertiary, token.borderRadius))
11
+ };
12
+ });
@@ -9,13 +9,15 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
9
9
  function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
10
  function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
11
11
  function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
12
+ import { isUndefined } from 'lodash-es';
12
13
  import { memo } from 'react';
13
14
  import { Flexbox } from 'react-layout-kit';
14
15
  import CopyButton from "../CopyButton";
15
16
  import Tag from "../Tag";
16
17
  import FullFeatured from "./FullFeatured";
18
+ import MermaidContainer from "./components/MermaidContainer";
19
+ import MermaidZoomableContainer from "./components/MermaidZoomableContainer";
17
20
  import { useStyles } from "./style";
18
- import { useMermaid } from "./useMermaid";
19
21
  import { jsx as _jsx } from "react/jsx-runtime";
20
22
  import { jsxs as _jsxs } from "react/jsx-runtime";
21
23
  var Mermaid = /*#__PURE__*/memo(function (_ref) {
@@ -39,11 +41,8 @@ var Mermaid = /*#__PURE__*/memo(function (_ref) {
39
41
  cx = _useStyles.cx,
40
42
  styles = _useStyles.styles;
41
43
  var tirmedChildren = children.trim();
42
- var MermaidRender = useMermaid(tirmedChildren, {
43
- enablePanZoom: fullFeatured ? true : enablePanZoom
44
- });
45
44
  var originalActions = copyable && /*#__PURE__*/_jsx(CopyButton, {
46
- content: children,
45
+ content: tirmedChildren,
47
46
  placement: "left",
48
47
  size: copyButtonSize
49
48
  });
@@ -52,7 +51,11 @@ var Mermaid = /*#__PURE__*/memo(function (_ref) {
52
51
  content: children,
53
52
  originalNode: originalActions
54
53
  }) : originalActions;
55
- var defaultBody = /*#__PURE__*/_jsx(MermaidRender, {});
54
+ var defaultBody = enablePanZoom || isUndefined(enablePanZoom) && fullFeatured ? /*#__PURE__*/_jsx(MermaidZoomableContainer, {
55
+ children: tirmedChildren
56
+ }) : /*#__PURE__*/_jsx(MermaidContainer, {
57
+ children: tirmedChildren
58
+ });
56
59
  var body = bodyRender ? bodyRender({
57
60
  content: tirmedChildren,
58
61
  originalNode: defaultBody
@@ -63,7 +66,6 @@ var Mermaid = /*#__PURE__*/memo(function (_ref) {
63
66
  className: className,
64
67
  content: tirmedChildren,
65
68
  copyable: copyable,
66
- enablePanZoom: enablePanZoom,
67
69
  showLanguage: showLanguage,
68
70
  style: style,
69
71
  type: type
@@ -1,5 +1,6 @@
1
1
  /// <reference types="react" />
2
- export interface SwatchesProps {
2
+ import { FlexboxProps } from 'react-layout-kit';
3
+ export interface SwatchesProps extends Omit<FlexboxProps, 'onSelect'> {
3
4
  /**
4
5
  * @description The currently active color
5
6
  * @default undefined
@@ -1,47 +1,59 @@
1
1
  'use client';
2
2
 
3
- import { useTheme } from 'antd-style';
3
+ function _typeof(o) { "@babel/helpers - typeof"; return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function (o) { return typeof o; } : function (o) { return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; }, _typeof(o); }
4
+ var _excluded = ["style", "colors", "activeColor", "onSelect", "size"];
5
+ function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
6
+ function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
7
+ function _defineProperty(obj, key, value) { key = _toPropertyKey(key); if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
8
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
9
+ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e = t[Symbol.toPrimitive]; if (void 0 !== e) { var i = e.call(t, r || "default"); if ("object" != _typeof(i)) return i; throw new TypeError("@@toPrimitive must return a primitive value."); } return ("string" === r ? String : Number)(t); }
10
+ function _objectWithoutProperties(source, excluded) { if (source == null) return {}; var target = _objectWithoutPropertiesLoose(source, excluded); var key, i; if (Object.getOwnPropertySymbols) { var sourceSymbolKeys = Object.getOwnPropertySymbols(source); for (i = 0; i < sourceSymbolKeys.length; i++) { key = sourceSymbolKeys[i]; if (excluded.indexOf(key) >= 0) continue; if (!Object.prototype.propertyIsEnumerable.call(source, key)) continue; target[key] = source[key]; } } return target; }
11
+ function _objectWithoutPropertiesLoose(source, excluded) { if (source == null) return {}; var target = {}; var sourceKeys = Object.keys(source); var key, i; for (i = 0; i < sourceKeys.length; i++) { key = sourceKeys[i]; if (excluded.indexOf(key) >= 0) continue; target[key] = source[key]; } return target; }
12
+ import { CheckIcon } from 'lucide-react';
13
+ import { darken } from 'polished';
4
14
  import { memo } from 'react';
5
- import { Flexbox } from 'react-layout-kit';
15
+ import { Center, Flexbox } from 'react-layout-kit';
16
+ import Icon from "../Icon";
6
17
  import { useStyles } from "./style";
7
18
  import { jsx as _jsx } from "react/jsx-runtime";
8
- import { jsxs as _jsxs } from "react/jsx-runtime";
9
19
  var Swatches = /*#__PURE__*/memo(function (_ref) {
10
- var colors = _ref.colors,
20
+ var style = _ref.style,
21
+ colors = _ref.colors,
11
22
  activeColor = _ref.activeColor,
12
23
  onSelect = _ref.onSelect,
13
24
  _ref$size = _ref.size,
14
- size = _ref$size === void 0 ? 24 : _ref$size;
15
- var theme = useTheme();
25
+ size = _ref$size === void 0 ? 24 : _ref$size,
26
+ rest = _objectWithoutProperties(_ref, _excluded);
16
27
  var _useStyles = useStyles(size),
17
28
  cx = _useStyles.cx,
18
29
  styles = _useStyles.styles;
19
- return /*#__PURE__*/_jsxs(Flexbox, {
30
+ return /*#__PURE__*/_jsx(Flexbox, _objectSpread(_objectSpread({
20
31
  gap: 8,
21
32
  horizontal: true,
22
- style: {
33
+ style: _objectSpread({
23
34
  flexWrap: 'wrap'
24
- },
25
- children: [/*#__PURE__*/_jsx(Flexbox, {
26
- className: cx(styles.container, !activeColor && styles.active),
27
- onClick: function onClick() {
28
- onSelect === null || onSelect === void 0 || onSelect();
29
- },
30
- style: {
31
- background: theme.colorBgContainer
32
- }
33
- }), colors.map(function (c, index) {
35
+ }, style)
36
+ }, rest), {}, {
37
+ children: colors.map(function (c, index) {
34
38
  var isActive = c === activeColor;
35
- return /*#__PURE__*/_jsx(Flexbox, {
39
+ return /*#__PURE__*/_jsx(Center, {
36
40
  className: cx(styles.container, isActive && styles.active),
37
41
  onClick: function onClick() {
38
42
  onSelect === null || onSelect === void 0 || onSelect(c);
39
43
  },
40
44
  style: {
41
45
  background: c
42
- }
46
+ },
47
+ children: isActive && /*#__PURE__*/_jsx(Icon, {
48
+ color: darken(0.3, c),
49
+ icon: CheckIcon,
50
+ size: {
51
+ fontSize: 14,
52
+ strokeWidth: 4
53
+ }
54
+ })
43
55
  }, "".concat(c, "_").concat(index));
44
- })]
45
- });
56
+ })
57
+ }));
46
58
  });
47
59
  export default Swatches;
@@ -5,7 +5,7 @@ export var useStyles = createStyles(function (_ref, size) {
5
5
  var css = _ref.css,
6
6
  token = _ref.token;
7
7
  return {
8
- active: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n box-shadow: 0 0 0 2px ", ";\n "])), token.colorTextTertiary),
9
- container: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n cursor: pointer;\n\n width: ", "px;\n height: ", "px;\n\n background: ", ";\n border-radius: 50%;\n box-shadow: inset 0 0 0 2px ", ";\n\n transition:\n scale 400ms ", ",\n box-shadow 100ms ", ";\n\n &:hover {\n box-shadow: 0 0 0 3px ", ";\n }\n\n &:active {\n scale: 0.8;\n }\n "])), size, size, token.colorBgContainer, token.colorSplit, token.motionEaseOut, token.motionEaseOut, token.colorText)
8
+ active: css(_templateObject || (_templateObject = _taggedTemplateLiteral(["\n box-shadow:\n inset 0 0 0 1px rgba(0, 0, 0, 20%),\n 0 0 0 2px ", ";\n "])), token.colorTextTertiary),
9
+ container: css(_templateObject2 || (_templateObject2 = _taggedTemplateLiteral(["\n cursor: pointer;\n\n width: ", "px;\n height: ", "px;\n\n background: ", ";\n border-radius: 50%;\n box-shadow: inset 0 0 0 1px rgba(0, 0, 0, 5%);\n\n &:hover {\n box-shadow:\n inset 0 0 0 1px rgba(0, 0, 0, 5%),\n 0 0 0 2px ", ";\n }\n "])), size, size, token.colorBgContainer, token.colorText)
10
10
  };
11
11
  });
@@ -31,9 +31,7 @@ export { default as Grid, type GridProps } from './Grid';
31
31
  export { default as Header, type HeaderProps } from './Header';
32
32
  export { default as Highlighter, type HighlighterProps, SyntaxHighlighter, type SyntaxHighlighterProps, } from './Highlighter';
33
33
  export { useChatListActionsBar } from './hooks/useChatListActionsBar';
34
- export { default as Hotkey, type HotkeyProps } from './Hotkey';
35
- export { KeyMapEnum } from './Hotkey/type';
36
- export { combineKeys } from './Hotkey/utils';
34
+ export { combineKeys, default as Hotkey, type HotkeyProps, KeyMapEnum } from './Hotkey';
37
35
  export { default as HotkeyInput, type HotkeyInputProps } from './HotkeyInput';
38
36
  export { default as Icon, type IconProps, type IconSize } from './Icon';
39
37
  export * from './Icon/icons';
@@ -43,7 +41,7 @@ export { Input, type InputProps, TextArea, type TextAreaProps } from './Input';
43
41
  export { default as Layout, LayoutFooter, type LayoutFooterProps, LayoutHeader, type LayoutHeaderProps, LayoutMain, type LayoutMainProps, type LayoutProps, LayoutSidebar, LayoutSidebarInner, type LayoutSidebarInnerProps, type LayoutSidebarProps, LayoutToc, type LayoutTocProps, } from './Layout';
44
42
  export { default as List, type ListItemProps } from './List';
45
43
  export { default as Markdown, type MarkdownProps } from './Markdown';
46
- export { Typography, type TypographyProps } from './Markdown/Typography';
44
+ export { default as Typography, type TypographyProps } from './Markdown/Typography';
47
45
  export { default as MaterialFileTypeIcon, type MaterialFileTypeIconProps, } from './MaterialFileTypeIcon';
48
46
  export { default as Mermaid, type MermaidProps } from './Mermaid';
49
47
  export { default as Modal, type ModalProps } from './Modal';
package/es/components.js CHANGED
@@ -31,9 +31,7 @@ export { default as Grid } from "./Grid";
31
31
  export { default as Header } from "./Header";
32
32
  export { default as Highlighter, SyntaxHighlighter } from "./Highlighter";
33
33
  export { useChatListActionsBar } from "./hooks/useChatListActionsBar";
34
- export { default as Hotkey } from "./Hotkey";
35
- export { KeyMapEnum } from "./Hotkey/type";
36
- export { combineKeys } from "./Hotkey/utils";
34
+ export { combineKeys, default as Hotkey, KeyMapEnum } from "./Hotkey";
37
35
  export { default as HotkeyInput } from "./HotkeyInput";
38
36
  export { default as Icon } from "./Icon";
39
37
  export * from "./Icon/icons";
@@ -43,7 +41,7 @@ export { Input, TextArea } from "./Input";
43
41
  export { default as Layout, LayoutFooter, LayoutHeader, LayoutMain, LayoutSidebar, LayoutSidebarInner, LayoutToc } from "./Layout";
44
42
  export { default as List } from "./List";
45
43
  export { default as Markdown } from "./Markdown";
46
- export { Typography } from "./Markdown/Typography";
44
+ export { default as Typography } from "./Markdown/Typography";
47
45
  export { default as MaterialFileTypeIcon } from "./MaterialFileTypeIcon";
48
46
  export { default as Mermaid } from "./Mermaid";
49
47
  export { default as Modal } from "./Modal";
@@ -1,3 +1,4 @@
1
+ import { SWRResponse } from 'swr';
1
2
  export declare const FALLBACK_LANG = "txt";
2
- export declare const useHighlight: (text: string, lang: string, enableTransformer?: boolean) => import("swr/dist/_internal/types").SWRResponse<string, any, any>;
3
+ export declare const useHighlight: (text: string, lang: string, enableTransformer?: boolean) => SWRResponse<string, Error>;
3
4
  export { default as languageMap } from './languageMap';
@@ -5,70 +5,149 @@ function _asyncToGenerator(fn) { return function () { var self = this, args = ar
5
5
  import { transformerNotationDiff, transformerNotationErrorLevel, transformerNotationFocus, transformerNotationHighlight, transformerNotationWordHighlight } from '@shikijs/transformers';
6
6
  import { useTheme, useThemeMode } from 'antd-style';
7
7
  import { useMemo } from 'react';
8
- import { codeToHtml } from 'shiki';
9
8
  import useSWR from 'swr';
10
9
  import { Md5 } from 'ts-md5';
11
10
  import languageMap from "./languageMap";
12
11
  export var FALLBACK_LANG = 'txt';
12
+
13
+ // 应用级缓存,避免重复计算
14
+ var highlightCache = new Map();
15
+ var MD5_LENGTH_THRESHOLD = 10000; // 超过该长度使用异步MD5
16
+
17
+ // 颜色替换映射类型
18
+
19
+ // 懒加载 shiki
20
+ var loadShiki = function loadShiki() {
21
+ return import('shiki').then(function (mod) {
22
+ return mod.codeToHtml;
23
+ });
24
+ };
25
+ var shikiPromise = loadShiki();
26
+
27
+ // 辅助函数:安全的HTML转义
28
+ var escapeHtml = function escapeHtml(str) {
29
+ return str.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;').replaceAll('"', '&quot;').replaceAll("'", '&#039;');
30
+ };
31
+
32
+ // 主高亮组件
13
33
  export var useHighlight = function useHighlight(text, lang, enableTransformer) {
14
34
  var _useThemeMode = useThemeMode(),
15
35
  isDarkMode = _useThemeMode.isDarkMode;
36
+ var theme = useTheme();
16
37
  var language = lang.toLowerCase();
38
+
39
+ // 匹配支持的语言
17
40
  var matchedLanguage = useMemo(function () {
18
41
  return languageMap.includes(language) ? language : FALLBACK_LANG;
19
42
  }, [language]);
20
- var theme = useTheme();
43
+
44
+ // 优化transformer创建
21
45
  var transformers = useMemo(function () {
22
46
  if (!enableTransformer) return;
23
47
  return [transformerNotationDiff(), transformerNotationHighlight(), transformerNotationWordHighlight(), transformerNotationFocus(), transformerNotationErrorLevel()];
24
48
  }, [enableTransformer]);
25
- var key = useMemo(function () {
26
- return Md5.hashStr(text);
27
- }, [text]);
28
- return useSWR([matchedLanguage, isDarkMode ? 'd' : 'l', key].join('-'), /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
49
+
50
+ // 优化颜色替换配置
51
+ var colorReplacements = useMemo(function () {
52
+ return {
53
+ 'slack-dark': {
54
+ '#4ec9b0': theme.yellow,
55
+ '#569cd6': theme.colorError,
56
+ '#6a9955': theme.gray,
57
+ '#9cdcfe': theme.colorText,
58
+ '#b5cea8': theme.purple10,
59
+ '#c586c0': theme.colorInfo,
60
+ '#ce9178': theme.colorSuccess,
61
+ '#dcdcaa': theme.colorWarning,
62
+ '#e6e6e6': theme.colorText
63
+ },
64
+ 'slack-ochin': {
65
+ '#002339': theme.colorText,
66
+ '#0991b6': theme.colorError,
67
+ '#174781': theme.purple10,
68
+ '#2f86d2': theme.colorText,
69
+ '#357b42': theme.gray,
70
+ '#7b30d0': theme.colorInfo,
71
+ '#7eb233': theme.colorWarningTextActive,
72
+ '#a44185': theme.colorSuccess,
73
+ '#dc3eb7': theme.yellow11
74
+ }
75
+ };
76
+ }, [theme]);
77
+
78
+ // 构建缓存键
79
+ var cacheKey = useMemo(function () {
80
+ // 长文本使用 hash
81
+ var hash = text.length < MD5_LENGTH_THRESHOLD ? text : Md5.hashStr(text);
82
+ return [matchedLanguage, isDarkMode ? 'd' : 'l', hash].join('-');
83
+ }, [matchedLanguage, isDarkMode]);
84
+
85
+ // 使用SWR获取高亮HTML
86
+ return useSWR(cacheKey, /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee() {
87
+ var codeToHtml, html, _codeToHtml, _html, fallbackHtml;
29
88
  return _regeneratorRuntime().wrap(function _callee$(_context) {
30
89
  while (1) switch (_context.prev = _context.next) {
31
90
  case 0:
32
- _context.prev = 0;
33
- return _context.abrupt("return", codeToHtml(text, {
34
- colorReplacements: {
35
- 'slack-dark': {
36
- '#4ec9b0': theme.yellow,
37
- '#569cd6': theme.colorError,
38
- '#6a9955': theme.gray,
39
- '#9cdcfe': theme.colorText,
40
- '#b5cea8': theme.purple10,
41
- '#c586c0': theme.colorInfo,
42
- '#ce9178': theme.colorSuccess,
43
- '#dcdcaa': theme.colorWarning,
44
- '#e6e6e6': theme.colorText
45
- },
46
- 'slack-ochin': {
47
- '#002339': theme.colorText,
48
- '#0991b6': theme.colorError,
49
- '#174781': theme.purple10,
50
- '#2f86d2': theme.colorText,
51
- '#357b42': theme.gray,
52
- '#7b30d0': theme.colorInfo,
53
- '#7eb233': theme.colorWarningTextActive,
54
- '#a44185': theme.colorSuccess,
55
- '#dc3eb7': theme.yellow11
56
- }
57
- },
91
+ if (!(cacheKey && highlightCache.has(cacheKey))) {
92
+ _context.next = 2;
93
+ break;
94
+ }
95
+ return _context.abrupt("return", highlightCache.get(cacheKey));
96
+ case 2:
97
+ _context.prev = 2;
98
+ _context.next = 5;
99
+ return shikiPromise;
100
+ case 5:
101
+ codeToHtml = _context.sent;
102
+ _context.next = 8;
103
+ return codeToHtml(text, {
104
+ colorReplacements: colorReplacements,
58
105
  lang: matchedLanguage,
59
106
  theme: isDarkMode ? 'slack-dark' : 'slack-ochin',
60
107
  transformers: transformers
61
- }));
62
- case 4:
63
- _context.prev = 4;
64
- _context.t0 = _context["catch"](0);
65
- console.error('shiki Highlight error:', _context.t0);
66
- return _context.abrupt("return", text);
108
+ });
67
109
  case 8:
110
+ html = _context.sent;
111
+ // 缓存结果
112
+ if (cacheKey) highlightCache.set(cacheKey, html);
113
+ return _context.abrupt("return", html);
114
+ case 13:
115
+ _context.prev = 13;
116
+ _context.t0 = _context["catch"](2);
117
+ console.error('高级渲染失败:', _context.t0);
118
+ _context.prev = 16;
119
+ _context.next = 19;
120
+ return shikiPromise;
121
+ case 19:
122
+ _codeToHtml = _context.sent;
123
+ _context.next = 22;
124
+ return _codeToHtml(text, {
125
+ lang: matchedLanguage,
126
+ theme: isDarkMode ? 'dark-plus' : 'light-plus'
127
+ });
128
+ case 22:
129
+ _html = _context.sent;
130
+ if (cacheKey) highlightCache.set(cacheKey, _html);
131
+ return _context.abrupt("return", _html);
132
+ case 27:
133
+ _context.prev = 27;
134
+ _context.t1 = _context["catch"](16);
135
+ // 最终降级到纯文本
136
+ fallbackHtml = "<pre class=\"fallback\"><code>".concat(escapeHtml(text), "</code></pre>");
137
+ if (cacheKey) highlightCache.set(cacheKey, fallbackHtml);
138
+ return _context.abrupt("return", fallbackHtml);
139
+ case 32:
68
140
  case "end":
69
141
  return _context.stop();
70
142
  }
71
- }, _callee, null, [[0, 4]]);
72
- })));
143
+ }, _callee, null, [[2, 13], [16, 27]]);
144
+ })), {
145
+ dedupingInterval: 3000,
146
+ // 3秒内相同请求只执行一次
147
+ errorRetryCount: 2,
148
+ // 最多重试2次
149
+ revalidateOnFocus: false,
150
+ revalidateOnReconnect: false
151
+ });
73
152
  };
74
153
  export { default as languageMap } from "./languageMap";
@@ -0,0 +1,9 @@
1
+ import { SWRResponse } from 'swr';
2
+ /**
3
+ * 验证并处理 Mermaid 图表内容
4
+ */
5
+ export declare const useMermaid: (id: string, content: string) => SWRResponse<string, Error>;
6
+ /**
7
+ * 初始化 Mermaid 配置
8
+ */
9
+ export declare const useMermaidInit: () => void;