react-terminal-viewer-cicd 2.0.4

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 (99) hide show
  1. package/README.md +181 -0
  2. package/dist/esm/Addon/EventEmiter.d.ts +18 -0
  3. package/dist/esm/Addon/EventEmiter.js +64 -0
  4. package/dist/esm/Addon/HighlightAddon.d.ts +26 -0
  5. package/dist/esm/Addon/HighlightAddon.js +188 -0
  6. package/dist/esm/Addon/SearchAddon.d.ts +140 -0
  7. package/dist/esm/Addon/SearchAddon.js +797 -0
  8. package/dist/esm/Addon/WorkerLog/GlobalContext.d.ts +10 -0
  9. package/dist/esm/Addon/WorkerLog/GlobalContext.js +37 -0
  10. package/dist/esm/Addon/WorkerLog/LimitMap.d.ts +14 -0
  11. package/dist/esm/Addon/WorkerLog/LimitMap.js +54 -0
  12. package/dist/esm/Addon/WorkerLog/LogWorker.d.ts +2 -0
  13. package/dist/esm/Addon/WorkerLog/LogWorker.js +13 -0
  14. package/dist/esm/Addon/WorkerLog/Logs.d.ts +21 -0
  15. package/dist/esm/Addon/WorkerLog/Logs.js +60 -0
  16. package/dist/esm/Addon/WorkerLog/Mark.d.ts +36 -0
  17. package/dist/esm/Addon/WorkerLog/Mark.js +155 -0
  18. package/dist/esm/Addon/WorkerLog/Searcher.d.ts +16 -0
  19. package/dist/esm/Addon/WorkerLog/Searcher.js +88 -0
  20. package/dist/esm/Addon/WorkerLog/WebWokerServer.d.ts +10 -0
  21. package/dist/esm/Addon/WorkerLog/WebWokerServer.js +57 -0
  22. package/dist/esm/Addon/WorkerLog/WebWorkerClient.d.ts +13 -0
  23. package/dist/esm/Addon/WorkerLog/WebWorkerClient.js +83 -0
  24. package/dist/esm/Addon/WorkerLog/log.worker.d.ts +1 -0
  25. package/dist/esm/Addon/WorkerLog/log.worker.js +63 -0
  26. package/dist/esm/Addon/WorkerLog/types.d.ts +18 -0
  27. package/dist/esm/Addon/WorkerLog/types.js +1 -0
  28. package/dist/esm/Addon/useAddon.d.ts +9 -0
  29. package/dist/esm/Addon/useAddon.js +33 -0
  30. package/dist/esm/Hooks/useBatchProcess.d.ts +2 -0
  31. package/dist/esm/Hooks/useBatchProcess.js +47 -0
  32. package/dist/esm/Hooks/useCache.d.ts +31 -0
  33. package/dist/esm/Hooks/useCache.js +206 -0
  34. package/dist/esm/Hooks/useDebounceInput.d.ts +3 -0
  35. package/dist/esm/Hooks/useDebounceInput.js +26 -0
  36. package/dist/esm/Hooks/useLocalStore.d.ts +2 -0
  37. package/dist/esm/Hooks/useLocalStore.js +9 -0
  38. package/dist/esm/Hooks/useRemote.d.ts +30 -0
  39. package/dist/esm/Hooks/useRemote.js +398 -0
  40. package/dist/esm/Hooks/useThrottle.d.ts +2 -0
  41. package/dist/esm/Hooks/useThrottle.js +13 -0
  42. package/dist/esm/Hooks/useWorkerLogs.d.ts +9 -0
  43. package/dist/esm/Hooks/useWorkerLogs.js +162 -0
  44. package/dist/esm/TerminalViewer/index.d.ts +185 -0
  45. package/dist/esm/TerminalViewer/index.js +292 -0
  46. package/dist/esm/TerminalViewer/index.less +17 -0
  47. package/dist/esm/TerminalViewerBody/index.d.ts +87 -0
  48. package/dist/esm/TerminalViewerBody/index.js +248 -0
  49. package/dist/esm/TerminalViewerBody/index.less +51 -0
  50. package/dist/esm/TerminalViewerHeader/index.d.ts +88 -0
  51. package/dist/esm/TerminalViewerHeader/index.js +129 -0
  52. package/dist/esm/TerminalViewerHeader/index.less +143 -0
  53. package/dist/esm/TerminalViewerToolBar/index.d.ts +46 -0
  54. package/dist/esm/TerminalViewerToolBar/index.js +28 -0
  55. package/dist/esm/TerminalViewerToolBar/index.less +32 -0
  56. package/dist/esm/TerminalViewerVirtualDom/index.d.ts +71 -0
  57. package/dist/esm/TerminalViewerVirtualDom/index.js +309 -0
  58. package/dist/esm/TerminalViewerVirtualDom/index.less +68 -0
  59. package/dist/esm/index.d.ts +9 -0
  60. package/dist/esm/index.js +9 -0
  61. package/dist/esm/mock/index.d.ts +12 -0
  62. package/dist/esm/mock/index.js +98 -0
  63. package/dist/esm/types.d.ts +30 -0
  64. package/dist/esm/types.js +1 -0
  65. package/dist/worker/Addon/EventEmiter.d.ts +18 -0
  66. package/dist/worker/Addon/HighlightAddon.d.ts +26 -0
  67. package/dist/worker/Addon/SearchAddon.d.ts +140 -0
  68. package/dist/worker/Addon/WorkerLog/GlobalContext.d.ts +10 -0
  69. package/dist/worker/Addon/WorkerLog/LimitMap.d.ts +14 -0
  70. package/dist/worker/Addon/WorkerLog/LogWorker.d.ts +2 -0
  71. package/dist/worker/Addon/WorkerLog/Logs.d.ts +21 -0
  72. package/dist/worker/Addon/WorkerLog/Mark.d.ts +36 -0
  73. package/dist/worker/Addon/WorkerLog/Searcher.d.ts +16 -0
  74. package/dist/worker/Addon/WorkerLog/WebWokerServer.d.ts +10 -0
  75. package/dist/worker/Addon/WorkerLog/WebWorkerClient.d.ts +13 -0
  76. package/dist/worker/Addon/WorkerLog/log.worker.d.ts +1 -0
  77. package/dist/worker/Addon/WorkerLog/types.d.ts +18 -0
  78. package/dist/worker/Addon/useAddon.d.ts +9 -0
  79. package/dist/worker/Hooks/useBatchProcess.d.ts +2 -0
  80. package/dist/worker/Hooks/useCache.d.ts +31 -0
  81. package/dist/worker/Hooks/useDebounceInput.d.ts +3 -0
  82. package/dist/worker/Hooks/useLocalStore.d.ts +2 -0
  83. package/dist/worker/Hooks/useRemote.d.ts +30 -0
  84. package/dist/worker/Hooks/useRemote.test.d.ts +1 -0
  85. package/dist/worker/Hooks/useThrottle.d.ts +2 -0
  86. package/dist/worker/Hooks/useWorkerLogs.d.ts +9 -0
  87. package/dist/worker/TerminalViewer/index.d.ts +185 -0
  88. package/dist/worker/TerminalViewer/index.test.d.ts +1 -0
  89. package/dist/worker/TerminalViewerBody/index.d.ts +87 -0
  90. package/dist/worker/TerminalViewerBody/index.test.d.ts +1 -0
  91. package/dist/worker/TerminalViewerHeader/index.d.ts +88 -0
  92. package/dist/worker/TerminalViewerToolBar/index.d.ts +46 -0
  93. package/dist/worker/TerminalViewerVirtualDom/index.d.ts +71 -0
  94. package/dist/worker/index.d.ts +9 -0
  95. package/dist/worker/log.worker.js +2 -0
  96. package/dist/worker/log.worker.js.map +1 -0
  97. package/dist/worker/mock/index.d.ts +12 -0
  98. package/dist/worker/types.d.ts +30 -0
  99. package/package.json +97 -0
@@ -0,0 +1,185 @@
1
+ import React from 'react';
2
+ import { ITerminalOptions } from 'xterm';
3
+ import type { ISearchOptions } from '../Addon/SearchAddon';
4
+ import type { IRemoteOptions } from '../Hooks/useRemote';
5
+ import type { ICacheOptions } from '../Hooks/useCache';
6
+ import type { IHighlightOptions } from '../Addon/HighlightAddon';
7
+ import { ExtraOptions, TerminalRef, LogAfterProps } from '../types';
8
+ import './index.less';
9
+ export interface TerminalViewerProps {
10
+ /**
11
+ * @description.zh-CN 指定 TerminalViewer 挂载的节点,并在容器内展现,false 为挂载在当前位置
12
+ * @default 当前位置
13
+ */
14
+ ref?: TerminalRef;
15
+ /**
16
+ * @description.zh-CN 是否自动拉伸填充容器宽高
17
+ * @default true
18
+ */
19
+ fit?: boolean;
20
+ /**
21
+ *@description.zh-CN 是否开启自动滚动到底部
22
+ *@default true
23
+ */
24
+ autoScroll?: boolean;
25
+ /**
26
+ * @description.zh-CN 自动滚动到某一行,开启后自动滚动到底部失效
27
+ */
28
+ scrollToRow?: number;
29
+ /**
30
+ * @description.zh-CN 是否支持刷新
31
+ * @default true
32
+ */
33
+ refreshable?: boolean;
34
+ /**
35
+ * @description.zh-CN 搜索框 placeholder
36
+ */
37
+ searchPlaceholder?: string;
38
+ /**
39
+ * @description.zh-CN 默认全屏显示
40
+ * @default false
41
+ */
42
+ defaultFullScreen?: boolean;
43
+ /**
44
+ * @description.zh-CN 自定义日志头部, null 为不显示默认头部
45
+ */
46
+ header?: React.ReactNode;
47
+ /**
48
+ * @description.zh-CN 搜索框前的内容
49
+ */
50
+ inputAddonBefore?: React.ReactNode;
51
+ /**
52
+ * @description.zh-CN 搜索框后的内容
53
+ */
54
+ inputAddonAfter?: React.ReactNode;
55
+ /**
56
+ * @description.zh-CN toolbar 自定义工具栏
57
+ */
58
+ toolbar?: React.ReactNode;
59
+ /**
60
+ * @description.zh-CN 是否显示全屏图标
61
+ * @default true
62
+ */
63
+ showFullScreen?: boolean;
64
+ /**
65
+ * @description.zh-CN 自定义空文本显示
66
+ */
67
+ empty?: React.ReactNode;
68
+ /**
69
+ * @description.zh-CN 外层样式类名
70
+ */
71
+ className?: string;
72
+ /**
73
+ * @description.zh-CN 可用于设置外层容器样式
74
+ */
75
+ style?: object;
76
+ /**
77
+ * @description.zh-CN 用于渲染日志的默认数据,如 "echo 1\r\necho2"
78
+ * @default ''
79
+ */
80
+ defaultData?: string;
81
+ /**
82
+ * @description.zh-CN 默认打开的标签
83
+ * @default 0
84
+ */
85
+ defaultTabIndex?: number;
86
+ /**
87
+ * @description.zh-CN 激活的标签, 如果同时设置了 defaultTabIndex 则以此属性为准
88
+ * @default 0
89
+ */
90
+ activeTabIndex?: number;
91
+ /**
92
+ * @description.zh-CN 设置日志后置标签,仅在开启虚拟 DOM 生效
93
+ */
94
+ logAfter?: React.FunctionComponent<LogAfterProps> | React.ComponentClass<LogAfterProps>;
95
+ /**
96
+ * @description.zh-CN 多标签配置选项
97
+ */
98
+ tabs?: {
99
+ key: string | number;
100
+ title?: React.ReactNode;
101
+ defaultData?: string;
102
+ remoteOptions?: IRemoteOptions;
103
+ cacheOptions?: ICacheOptions;
104
+ }[];
105
+ /**
106
+ *@description.zh-CN 自定义图标
107
+ */
108
+ icons?: {
109
+ search?: React.ReactNode;
110
+ up?: React.ReactNode;
111
+ down?: React.ReactNode;
112
+ clear?: React.ReactNode;
113
+ top?: React.ReactNode;
114
+ bottom?: React.ReactNode;
115
+ fullScreen?: React.ReactNode;
116
+ fullScreenExit?: React.ReactNode;
117
+ refresh?: React.ReactNode;
118
+ loading?: React.ReactNode;
119
+ };
120
+ /**
121
+ * @description.zh-CN 是否支持渲染超链接
122
+ * @default true
123
+ */
124
+ webLinksSupport?: boolean;
125
+ /**
126
+ * @description.zh-CN 是否使用 canvas 渲染, 开启 canvas 会有更好的性能但可能会遇到更多的问题
127
+ * @default false
128
+ */
129
+ canvasSupport?: boolean;
130
+ /**
131
+ * @description.zh-CN 是否使用自研虚拟 DOM 内核,开启后 terminalOptions, canvasSupport, webLinksSupport 不可用
132
+ * @default false
133
+ */
134
+ virtualDomSupport?: boolean;
135
+ /**
136
+ * @description.zh-CN 日志 web worker 路径, 需配合 CopyPlugin 使用且仅在开启 virtualDomSupport 为 true 时有效
137
+
138
+ * @default "/worker"
139
+ */
140
+ workerPath?: string;
141
+ /**
142
+ * @description.zh-CN 远程加载配置
143
+ *
144
+ */
145
+ remoteOptions?: IRemoteOptions;
146
+ /**
147
+ * @description.zh-CN 缓存全局配置,仅在配置远程加载后有效,如 `expires: 60 * 1000` 表示自动清理已过期一分钟的缓存
148
+ */
149
+ cacheOptions?: ICacheOptions;
150
+ /**
151
+ * @description.zh-CN xterm 搜索选项
152
+ */
153
+ searchOptions?: ISearchOptions;
154
+ /**
155
+ * @description.zh-CN 高亮选项
156
+ */
157
+ highlightOptions?: IHighlightOptions[];
158
+ /**
159
+ * @description.zh-CN xtem.js 配置, https://github.com/xtermjs/xterm.js
160
+ */
161
+ terminalOptions?: ITerminalOptions;
162
+ /**
163
+ * @description.zh-CN 额外的功能选项 { showLineNumber 仅 虚拟 DOM 模式支持}
164
+ */
165
+ extraOptions?: ExtraOptions;
166
+ /**
167
+ * @description.zh-CN 指定 TerminalViewer 挂载的节点,并在容器内展现,开启全屏后无效, false 为挂载在当前位置
168
+ * @default 当前节点
169
+ */
170
+ getContainer?: string | HTMLElement | (() => HTMLElement | null);
171
+ /**
172
+ * @description.zh-CN 点击 tab 标题后回调函数
173
+ */
174
+ onTitleChange?: (index: number) => void;
175
+ /**
176
+ * @description.zh-CN 加载状态变更回调函数
177
+ */
178
+ onLoading?: (bool: boolean) => void;
179
+ /**
180
+ * @description.zh-CN 刷新后的回调函数
181
+ */
182
+ onRefresh?: () => void;
183
+ }
184
+ declare const TerminalViewer: React.ForwardRefExoticComponent<Omit<TerminalViewerProps, "ref"> & React.RefAttributes<TerminalRef | undefined>>;
185
+ export default TerminalViewer;
@@ -0,0 +1,292 @@
1
+ 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); }
2
+ 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; }
3
+ 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; }
4
+ 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; }
5
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
6
+ 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); }
7
+ function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
8
+ function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
9
+ function _unsupportedIterableToArray(o, minLen) { if (!o) return; if (typeof o === "string") return _arrayLikeToArray(o, minLen); var n = Object.prototype.toString.call(o).slice(8, -1); if (n === "Object" && o.constructor) n = o.constructor.name; if (n === "Map" || n === "Set") return Array.from(o); if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _arrayLikeToArray(o, minLen); }
10
+ function _arrayLikeToArray(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
11
+ function _iterableToArrayLimit(r, l) { var t = null == r ? null : "undefined" != typeof Symbol && r[Symbol.iterator] || r["@@iterator"]; if (null != t) { var e, n, i, u, a = [], f = !0, o = !1; try { if (i = (t = t.call(r)).next, 0 === l) { if (Object(t) !== t) return; f = !1; } else for (; !(f = (e = i.call(t)).done) && (a.push(e.value), a.length !== l); f = !0); } catch (r) { o = !0, n = r; } finally { try { if (!f && null != t.return && (u = t.return(), Object(u) !== u)) return; } finally { if (o) throw n; } } return a; } }
12
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
13
+ import React, { forwardRef, useCallback, useState, useImperativeHandle, useRef, useEffect, useMemo } from 'react';
14
+ import { createPortal } from 'react-dom';
15
+ import useDebounceInput from "../Hooks/useDebounceInput";
16
+ import TerminalViewerHeader from "../TerminalViewerHeader";
17
+ import TerminalViewerBody from "../TerminalViewerBody";
18
+ import TerminalViewerVirtualDom from "../TerminalViewerVirtualDom";
19
+ import TerminalViewerToolBar from "../TerminalViewerToolBar";
20
+ import globalContext from "../Addon/WorkerLog/GlobalContext";
21
+ import "./index.less";
22
+ var defaultSearchOptions = {
23
+ regex: false,
24
+ wholeWord: false,
25
+ caseSensitive: false,
26
+ incremental: false,
27
+ decorations: {
28
+ matchForegroundColor: '#000000',
29
+ matchBackground: '#ffff54',
30
+ matchBorder: 'none',
31
+ matchOverviewRuler: 'none',
32
+ activeMatchBackground: '#ff9540',
33
+ activeMatchBorder: 'none',
34
+ activeMatchColorOverviewRuler: 'none'
35
+ }
36
+ };
37
+
38
+ // eslint-disable-next-line react/display-name
39
+ var TerminalViewer = /*#__PURE__*/forwardRef(function (_ref, ref) {
40
+ var fit = _ref.fit,
41
+ autoScroll = _ref.autoScroll,
42
+ scrollToRow = _ref.scrollToRow,
43
+ refreshable = _ref.refreshable,
44
+ searchPlaceholder = _ref.searchPlaceholder,
45
+ header = _ref.header,
46
+ inputAddonBefore = _ref.inputAddonBefore,
47
+ inputAddonAfter = _ref.inputAddonAfter,
48
+ empty = _ref.empty,
49
+ icons = _ref.icons,
50
+ toolbar = _ref.toolbar,
51
+ showFullScreen = _ref.showFullScreen,
52
+ className = _ref.className,
53
+ style = _ref.style,
54
+ defaultFullScreen = _ref.defaultFullScreen,
55
+ defaultData = _ref.defaultData,
56
+ defaultTabIndex = _ref.defaultTabIndex,
57
+ activeTabIndexProp = _ref.activeTabIndex,
58
+ logAfter = _ref.logAfter,
59
+ tabs = _ref.tabs,
60
+ webLinksSupport = _ref.webLinksSupport,
61
+ canvasSupport = _ref.canvasSupport,
62
+ virtualDomSupport = _ref.virtualDomSupport,
63
+ workerPath = _ref.workerPath,
64
+ remoteOptions = _ref.remoteOptions,
65
+ cacheOptions = _ref.cacheOptions,
66
+ searchOptions = _ref.searchOptions,
67
+ highlightOptions = _ref.highlightOptions,
68
+ terminalOptions = _ref.terminalOptions,
69
+ extraOptions = _ref.extraOptions,
70
+ getContainer = _ref.getContainer,
71
+ onTitleChange = _ref.onTitleChange,
72
+ onLoading = _ref.onLoading,
73
+ onRefresh = _ref.onRefresh;
74
+ var localSearchOptions = searchOptions !== null && searchOptions !== void 0 ? searchOptions : {};
75
+ var instanceRef = useRef();
76
+ var searchValueRef = useRef('');
77
+ var _useState = useState(false),
78
+ _useState2 = _slicedToArray(_useState, 2),
79
+ loading = _useState2[0],
80
+ setLoading = _useState2[1];
81
+ var _useState3 = useState(defaultFullScreen),
82
+ _useState4 = _slicedToArray(_useState3, 2),
83
+ fullScreen = _useState4[0],
84
+ setFullScreen = _useState4[1];
85
+ var _useState5 = useState(activeTabIndexProp || defaultTabIndex || 0),
86
+ _useState6 = _slicedToArray(_useState5, 2),
87
+ activeTabIndex = _useState6[0],
88
+ setActiveTabIndex = _useState6[1];
89
+ var _useState7 = useState({
90
+ resultIndex: -1,
91
+ resultCount: 0
92
+ }),
93
+ _useState8 = _slicedToArray(_useState7, 2),
94
+ searchResult = _useState8[0],
95
+ setSearchResult = _useState8[1];
96
+ var searchOptionsRef = useRef(_objectSpread(_objectSpread({}, defaultSearchOptions), localSearchOptions));
97
+ useEffect(function () {
98
+ searchOptionsRef.current = _objectSpread(_objectSpread({}, defaultSearchOptions), localSearchOptions);
99
+ });
100
+ var cln = ['terminal-viewer', fullScreen && 'terminal-viewer--fullscreen', className].filter(Boolean).join(' ');
101
+ var ViewerBody = virtualDomSupport ? TerminalViewerVirtualDom : TerminalViewerBody;
102
+ var titles = useMemo(function () {
103
+ if (!Array.isArray(tabs)) {
104
+ return [];
105
+ }
106
+ return tabs.map(function (tab, index) {
107
+ return tab.title || index;
108
+ });
109
+ }, [tabs]);
110
+ var getQueryElement = useCallback(function (query) {
111
+ if (typeof query === 'string') {
112
+ return document.querySelector(query);
113
+ }
114
+ if (typeof query === 'function') {
115
+ return query();
116
+ }
117
+ return query;
118
+ }, []);
119
+ var mountElement = fullScreen ? document.body : getQueryElement(getContainer);
120
+ var handleLoading = useCallback(function (bool) {
121
+ setLoading(bool);
122
+ if (typeof onLoading === 'function') {
123
+ onLoading(bool);
124
+ }
125
+ }, [onLoading]);
126
+ var handleTitleChange = useCallback(function (index) {
127
+ setActiveTabIndex(index);
128
+ setSearchResult({
129
+ resultIndex: -1,
130
+ resultCount: 0
131
+ });
132
+ if (typeof onTitleChange === 'function') {
133
+ onTitleChange(index);
134
+ }
135
+ }, [onTitleChange]);
136
+ var handleSearchChange = useDebounceInput(function (value) {
137
+ var _instanceRef$current;
138
+ searchValueRef.current = value;
139
+ if ((_instanceRef$current = instanceRef.current) !== null && _instanceRef$current !== void 0 && (_instanceRef$current = _instanceRef$current.addons) !== null && _instanceRef$current !== void 0 && _instanceRef$current.search) {
140
+ var _instanceRef$current$;
141
+ (_instanceRef$current$ = instanceRef.current.addons.search()) === null || _instanceRef$current$ === void 0 || _instanceRef$current$.findNext(value, searchOptionsRef.current);
142
+ }
143
+ });
144
+ var handleSearchClear = useCallback(function () {
145
+ var _instanceRef$current2;
146
+ if ((_instanceRef$current2 = instanceRef.current) !== null && _instanceRef$current2 !== void 0 && (_instanceRef$current2 = _instanceRef$current2.addons) !== null && _instanceRef$current2 !== void 0 && _instanceRef$current2.search) {
147
+ var _instanceRef$current$2;
148
+ (_instanceRef$current$2 = instanceRef.current.addons.search()) === null || _instanceRef$current$2 === void 0 || _instanceRef$current$2.findNext('', searchOptionsRef.current);
149
+ }
150
+ }, []);
151
+ var handleSearchPrev = useCallback(function (value) {
152
+ var _instanceRef$current3;
153
+ if ((_instanceRef$current3 = instanceRef.current) !== null && _instanceRef$current3 !== void 0 && (_instanceRef$current3 = _instanceRef$current3.addons) !== null && _instanceRef$current3 !== void 0 && _instanceRef$current3.search) {
154
+ var _instanceRef$current4;
155
+ (_instanceRef$current4 = instanceRef.current) === null || _instanceRef$current4 === void 0 || (_instanceRef$current4 = _instanceRef$current4.addons.search()) === null || _instanceRef$current4 === void 0 || _instanceRef$current4.findPrevious(value, searchOptionsRef.current);
156
+ }
157
+ }, []);
158
+ var handleSearchNext = useCallback(function (value) {
159
+ var _instanceRef$current5;
160
+ if ((_instanceRef$current5 = instanceRef.current) !== null && _instanceRef$current5 !== void 0 && (_instanceRef$current5 = _instanceRef$current5.addons) !== null && _instanceRef$current5 !== void 0 && _instanceRef$current5.search) {
161
+ var _instanceRef$current$3;
162
+ (_instanceRef$current$3 = instanceRef.current.addons.search()) === null || _instanceRef$current$3 === void 0 || _instanceRef$current$3.findNext(value, searchOptionsRef.current);
163
+ }
164
+ }, []);
165
+ var handleAddonReady = useCallback(function (terminal, addon) {
166
+ var searchAddon = addon;
167
+ // 注意需配置 decorations 才会触发
168
+ if (searchAddon !== null && searchAddon !== void 0 && searchAddon.onDidChangeResults) {
169
+ searchAddon.onDidChangeResults(function (e) {
170
+ setSearchResult(e || {
171
+ resultIndex: -1,
172
+ resultCount: 0
173
+ });
174
+ });
175
+ }
176
+ }, []);
177
+ var handleScrollTop = useCallback(function () {
178
+ var _instanceRef$current6;
179
+ if ((_instanceRef$current6 = instanceRef.current) !== null && _instanceRef$current6 !== void 0 && _instanceRef$current6.terminal) {
180
+ var _instanceRef$current$4;
181
+ (_instanceRef$current$4 = instanceRef.current.terminal()) === null || _instanceRef$current$4 === void 0 || _instanceRef$current$4.scrollToTop();
182
+ }
183
+ }, []);
184
+ var handleScrollBottom = useCallback(function () {
185
+ var _instanceRef$current7;
186
+ if ((_instanceRef$current7 = instanceRef.current) !== null && _instanceRef$current7 !== void 0 && _instanceRef$current7.terminal) {
187
+ var _instanceRef$current$5;
188
+ (_instanceRef$current$5 = instanceRef.current.terminal()) === null || _instanceRef$current$5 === void 0 || _instanceRef$current$5.scrollToBottom();
189
+ }
190
+ }, []);
191
+ var handleFullScreen = useCallback(function () {
192
+ setFullScreen(function (p) {
193
+ return !p;
194
+ });
195
+ }, []);
196
+ var handleRefresh = useCallback(function () {
197
+ var _instanceRef$current8;
198
+ if (typeof onRefresh === 'function') {
199
+ onRefresh();
200
+ }
201
+ (_instanceRef$current8 = instanceRef.current) === null || _instanceRef$current8 === void 0 || _instanceRef$current8.refresh();
202
+ }, [onRefresh]);
203
+ useEffect(function () {
204
+ setActiveTabIndex(activeTabIndexProp || 0);
205
+ }, [activeTabIndexProp]);
206
+ useImperativeHandle(ref, function () {
207
+ return instanceRef.current;
208
+ });
209
+ if (virtualDomSupport) {
210
+ globalContext.setWorkerPath(workerPath || "" || '/worker');
211
+ }
212
+ useEffect(function () {
213
+ var worker = globalContext.getWorker();
214
+ return function () {
215
+ worker === null || worker === void 0 || worker.terminate();
216
+ globalContext.setWorker(undefined);
217
+ };
218
+ }, [virtualDomSupport]);
219
+ var render = /*#__PURE__*/React.createElement("div", {
220
+ className: cln,
221
+ style: style
222
+ }, header || /*#__PURE__*/React.createElement(TerminalViewerHeader, {
223
+ defaultValue: searchValueRef.current,
224
+ refreshable: refreshable,
225
+ icons: icons,
226
+ loading: loading,
227
+ activeTitleIndex: activeTabIndex,
228
+ titles: titles,
229
+ placeholder: searchPlaceholder,
230
+ searchResult: searchResult,
231
+ inputAddonBefore: inputAddonBefore,
232
+ inputAddonAfter: inputAddonAfter,
233
+ onSearchChange: handleSearchChange,
234
+ onSearchClear: handleSearchClear,
235
+ onSearchPrev: handleSearchPrev,
236
+ onSearchNext: handleSearchNext,
237
+ onTitleChange: handleTitleChange,
238
+ onRefresh: handleRefresh
239
+ }), Array.isArray(tabs) && tabs.map(function (tab, index) {
240
+ if (activeTabIndex === index) {
241
+ return /*#__PURE__*/React.createElement(ViewerBody, {
242
+ key: tab.key || index,
243
+ fit: fit,
244
+ empty: empty,
245
+ autoScroll: autoScroll,
246
+ scrollToRow: scrollToRow,
247
+ logAfter: logAfter,
248
+ webLinksSupport: webLinksSupport,
249
+ canvasSupport: canvasSupport,
250
+ ref: instanceRef,
251
+ defaultData: tab.defaultData,
252
+ cacheOptions: tab.cacheOptions || cacheOptions,
253
+ remoteOptions: tab.remoteOptions,
254
+ highlightOptions: highlightOptions,
255
+ terminalOptions: terminalOptions,
256
+ extraOptions: extraOptions,
257
+ onAddonReady: handleAddonReady,
258
+ onLoading: handleLoading
259
+ });
260
+ }
261
+ return null;
262
+ }).filter(Boolean), !Array.isArray(tabs) && /*#__PURE__*/React.createElement(ViewerBody, {
263
+ fit: fit,
264
+ empty: empty,
265
+ autoScroll: autoScroll,
266
+ scrollToRow: scrollToRow,
267
+ logAfter: logAfter,
268
+ webLinksSupport: webLinksSupport,
269
+ canvasSupport: canvasSupport,
270
+ ref: instanceRef,
271
+ defaultData: defaultData,
272
+ remoteOptions: remoteOptions,
273
+ cacheOptions: cacheOptions,
274
+ highlightOptions: highlightOptions,
275
+ terminalOptions: terminalOptions,
276
+ extraOptions: extraOptions,
277
+ onAddonReady: handleAddonReady,
278
+ onLoading: handleLoading
279
+ }), toolbar || /*#__PURE__*/React.createElement(TerminalViewerToolBar, {
280
+ icons: icons,
281
+ fullScreen: fullScreen,
282
+ showFullScreen: showFullScreen,
283
+ onScrollTop: handleScrollTop,
284
+ onScrollBottom: handleScrollBottom,
285
+ onFullScreen: handleFullScreen
286
+ }));
287
+ if (mountElement) {
288
+ return /*#__PURE__*/createPortal(render, mountElement);
289
+ }
290
+ return render;
291
+ });
292
+ export default TerminalViewer;
@@ -0,0 +1,17 @@
1
+ .terminal-viewer {
2
+ position: relative;
3
+ display: flex;
4
+ flex-direction: column;
5
+ width: 100%;
6
+ height: 100%;
7
+ overflow: hidden;
8
+ }
9
+
10
+ .terminal-viewer--fullscreen {
11
+ position: fixed;
12
+ top: 0;
13
+ left: 0;
14
+ z-index: 1800;
15
+ width: 100%;
16
+ height: 100%;
17
+ }
@@ -0,0 +1,87 @@
1
+ import React from 'react';
2
+ import { Terminal, ITerminalOptions } from 'xterm';
3
+ import 'xterm/css/xterm.css';
4
+ import { FitAddon } from 'xterm-addon-fit';
5
+ import { WebLinksAddon } from 'xterm-addon-web-links';
6
+ import { CanvasAddon } from 'xterm-addon-canvas';
7
+ import { SearchAddon } from '../Addon/SearchAddon';
8
+ import { HighlightAddon } from '../Addon/HighlightAddon';
9
+ import type { AddonType } from '../Addon/useAddon';
10
+ import type { IRemoteOptions } from '../Hooks/useRemote';
11
+ import type { ICacheOptions } from '../Hooks/useCache';
12
+ import type { IHighlightOptions } from '../Addon/HighlightAddon';
13
+ import { TerminalRef } from '../types';
14
+ import './index.less';
15
+ export interface TerminalExposedRef {
16
+ terminal?: Terminal | undefined;
17
+ addons?: {
18
+ search?: SearchAddon | undefined;
19
+ fit?: FitAddon | undefined;
20
+ webLinks?: WebLinksAddon | undefined;
21
+ highlight?: HighlightAddon | undefined;
22
+ canvas?: CanvasAddon | undefined;
23
+ };
24
+ refresh?: (() => void) | undefined;
25
+ }
26
+ export interface TerminalViewerBodyProps {
27
+ /**
28
+ * @description.zh-CN 是否自动拉伸填充容器宽高
29
+ * @default true
30
+ */
31
+ fit?: boolean;
32
+ /**
33
+ *@description.zh-CN 是否开启自动滚动到底部
34
+ *@default true
35
+ */
36
+ autoScroll?: boolean;
37
+ /**
38
+ * @description.zh-CN 外层样式类名
39
+ */
40
+ className?: string;
41
+ /**
42
+ * @description.zh-CN 自定义空文本显示
43
+ */
44
+ empty?: React.ReactNode;
45
+ /**
46
+ * @description.zh-CN 是否支持渲染超链接
47
+ * @default true
48
+ */
49
+ webLinksSupport?: boolean;
50
+ /**
51
+ * @description.zh-CN 是否使用 canvas 渲染
52
+ * @default false
53
+ */
54
+ canvasSupport?: boolean;
55
+ /**
56
+ * @description.zh-CN 远程搜索选配置
57
+ *
58
+ */
59
+ remoteOptions?: IRemoteOptions;
60
+ /**
61
+ * @description.zh-CN 缓存配置,仅在配置远程加载后有效,如 `expires: 60 * 1000` 表示自动清理已过期一分钟的缓存
62
+ */
63
+ cacheOptions?: ICacheOptions;
64
+ /**
65
+ * @description.zh-CN 高亮选项
66
+ */
67
+ highlightOptions?: IHighlightOptions[];
68
+ /**
69
+ * @description.zh-CN xtem.js 配置, https://github.com/xtermjs/xterm.js
70
+ */
71
+ terminalOptions?: ITerminalOptions;
72
+ /**
73
+ * @description.zh-CN 用于渲染日志的默认数据,如 "echo 1\r\necho2"
74
+ * @default '''
75
+ */
76
+ defaultData?: string;
77
+ /**
78
+ * @description.zh-CN 插件加载成功后的回调
79
+ */
80
+ onAddonReady?: (instance: Terminal, addon: AddonType) => void;
81
+ /**
82
+ * @description.zh-CN 加载状态变更后的回调
83
+ */
84
+ onLoading?: (loading: boolean) => void;
85
+ }
86
+ declare const TerminalViewerBody: React.ForwardRefExoticComponent<TerminalViewerBodyProps & React.RefAttributes<TerminalRef | undefined>>;
87
+ export default TerminalViewerBody;