react-terminal-viewer-cicd 3.0.0-beta.2 → 3.0.0-beta.20

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 (100) hide show
  1. package/README.md +4 -2
  2. package/dist/esm/Addon/WorkerLog/LogParser.d.ts +22 -0
  3. package/dist/esm/Addon/WorkerLog/LogParser.js +129 -0
  4. package/dist/esm/Addon/WorkerLog/LogWorker.js +1 -1
  5. package/dist/esm/Addon/WorkerLog/Logs.d.ts +29 -5
  6. package/dist/esm/Addon/WorkerLog/Logs.js +121 -13
  7. package/dist/esm/Addon/WorkerLog/Searcher.d.ts +9 -7
  8. package/dist/esm/Addon/WorkerLog/Searcher.js +20 -8
  9. package/dist/esm/Addon/WorkerLog/log.worker.js +29 -3
  10. package/dist/esm/Hooks/useRemote.d.ts +1 -1
  11. package/dist/esm/Hooks/useRemote.js +3 -2
  12. package/dist/esm/Hooks/useThrottle.js +1 -1
  13. package/dist/esm/Hooks/useWorkerLogs.d.ts +1 -1
  14. package/dist/esm/Hooks/useWorkerLogs.js +1 -1
  15. package/dist/esm/TerminalViewer/index.d.ts +16 -3
  16. package/dist/esm/TerminalViewer/index.js +22 -4
  17. package/dist/esm/TerminalViewerBody/index.d.ts +1 -1
  18. package/dist/esm/TerminalViewerHeader/index.d.ts +17 -3
  19. package/dist/esm/TerminalViewerHeader/index.js +13 -8
  20. package/dist/esm/TerminalViewerHeader/index.less +6 -4
  21. package/dist/esm/TerminalViewerToolBar/index.js +1 -1
  22. package/dist/esm/TerminalViewerVirtualDom/ChevronRight.d.ts +21 -0
  23. package/dist/esm/TerminalViewerVirtualDom/ChevronRight.js +35 -0
  24. package/dist/esm/TerminalViewerVirtualDom/HumenTime.d.ts +14 -0
  25. package/dist/esm/TerminalViewerVirtualDom/HumenTime.js +111 -0
  26. package/dist/esm/TerminalViewerVirtualDom/LogParser.d.ts +22 -0
  27. package/dist/esm/TerminalViewerVirtualDom/LogParser.js +107 -0
  28. package/dist/esm/TerminalViewerVirtualDom/index.d.ts +83 -2
  29. package/dist/esm/TerminalViewerVirtualDom/index.js +446 -3
  30. package/dist/esm/TerminalViewerVirtualDom/index.less +119 -0
  31. package/dist/esm/TerminalViewerVirtualDom/useStreamStepWorkerLogs.d.ts +24 -0
  32. package/dist/esm/TerminalViewerVirtualDom/useStreamStepWorkerLogs.js +301 -0
  33. package/dist/esm/TerminalViewerVirtualDom/watting.svg +1 -0
  34. package/dist/esm/mock/index.d.ts +2 -0
  35. package/dist/esm/mock/index.js +108 -1
  36. package/dist/esm/types.d.ts +21 -2
  37. package/dist/worker/log.worker.js +1 -1
  38. package/dist/worker/log.worker.js.map +1 -1
  39. package/dist/worker/src/Addon/WorkerLog/LogParser.d.ts +22 -0
  40. package/dist/worker/src/Addon/WorkerLog/Logs.d.ts +29 -5
  41. package/dist/worker/src/Addon/WorkerLog/Searcher.d.ts +9 -7
  42. package/dist/worker/src/Hooks/useRemote.d.ts +1 -1
  43. package/dist/worker/src/Hooks/useWorkerLogs.d.ts +1 -1
  44. package/dist/worker/src/TerminalViewer/index.d.ts +16 -3
  45. package/dist/worker/src/TerminalViewerBody/index.d.ts +1 -1
  46. package/dist/worker/src/TerminalViewerHeader/CollapseButton.d.ts +21 -0
  47. package/dist/worker/src/TerminalViewerHeader/index.d.ts +17 -3
  48. package/dist/worker/src/TerminalViewerVirtualDom/ChevronRight.d.ts +21 -0
  49. package/dist/worker/src/TerminalViewerVirtualDom/HumenTime.d.ts +14 -0
  50. package/dist/worker/src/TerminalViewerVirtualDom/LogParser.d.ts +22 -0
  51. package/dist/worker/src/TerminalViewerVirtualDom/index.d.ts +83 -2
  52. package/dist/worker/src/TerminalViewerVirtualDom/useStreamStepWorkerLogs.d.ts +24 -0
  53. package/dist/worker/src/mock/index.d.ts +2 -0
  54. package/dist/worker/src/types.d.ts +21 -2
  55. package/package.json +1 -1
  56. package/dist/esm/TerminalViewerVirtualDom/ReactVirtualized.d.ts +0 -71
  57. package/dist/esm/TerminalViewerVirtualDom/ReactVirtualized.js +0 -309
  58. package/dist/esm/TerminalViewerVirtualDom/ReactVirtuoso.d.ts +0 -67
  59. package/dist/esm/TerminalViewerVirtualDom/ReactVirtuoso.js +0 -271
  60. package/dist/esm/TerminalViewerVirtualDom/virtuoso.less +0 -67
  61. package/dist/worker/.dumi/tmp/core/exportStaticRuntimePlugin.d.ts +0 -1
  62. package/dist/worker/.dumi/tmp/core/helmet.d.ts +0 -3
  63. package/dist/worker/.dumi/tmp/core/helmetContext.d.ts +0 -1
  64. package/dist/worker/.dumi/tmp/dumi/locales/runtime.d.ts +0 -2
  65. package/dist/worker/.dumi/tmp/dumi/meta/runtime.d.ts +0 -3
  66. package/dist/worker/Addon/EventEmiter.d.ts +0 -18
  67. package/dist/worker/Addon/HighlightAddon.d.ts +0 -26
  68. package/dist/worker/Addon/SearchAddon.d.ts +0 -140
  69. package/dist/worker/Addon/WorkerLog/GlobalContext.d.ts +0 -10
  70. package/dist/worker/Addon/WorkerLog/LimitMap.d.ts +0 -14
  71. package/dist/worker/Addon/WorkerLog/LogWorker.d.ts +0 -2
  72. package/dist/worker/Addon/WorkerLog/Logs.d.ts +0 -21
  73. package/dist/worker/Addon/WorkerLog/Mark.d.ts +0 -36
  74. package/dist/worker/Addon/WorkerLog/Searcher.d.ts +0 -16
  75. package/dist/worker/Addon/WorkerLog/WebWokerServer.d.ts +0 -10
  76. package/dist/worker/Addon/WorkerLog/WebWorkerClient.d.ts +0 -13
  77. package/dist/worker/Addon/WorkerLog/log.worker.d.ts +0 -1
  78. package/dist/worker/Addon/WorkerLog/types.d.ts +0 -18
  79. package/dist/worker/Addon/useAddon.d.ts +0 -9
  80. package/dist/worker/Hooks/useBatchProcess.d.ts +0 -2
  81. package/dist/worker/Hooks/useCache.d.ts +0 -31
  82. package/dist/worker/Hooks/useDebounceInput.d.ts +0 -3
  83. package/dist/worker/Hooks/useLocalStore.d.ts +0 -2
  84. package/dist/worker/Hooks/useRemote.d.ts +0 -30
  85. package/dist/worker/Hooks/useRemote.test.d.ts +0 -1
  86. package/dist/worker/Hooks/useThrottle.d.ts +0 -2
  87. package/dist/worker/Hooks/useWorkerLogs.d.ts +0 -9
  88. package/dist/worker/TerminalViewer/index.d.ts +0 -185
  89. package/dist/worker/TerminalViewer/index.test.d.ts +0 -1
  90. package/dist/worker/TerminalViewerBody/index.d.ts +0 -87
  91. package/dist/worker/TerminalViewerBody/index.test.d.ts +0 -1
  92. package/dist/worker/TerminalViewerHeader/index.d.ts +0 -88
  93. package/dist/worker/TerminalViewerToolBar/index.d.ts +0 -46
  94. package/dist/worker/TerminalViewerVirtualDom/index.d.ts +0 -71
  95. package/dist/worker/index.d.ts +0 -9
  96. package/dist/worker/mock/index.d.ts +0 -15
  97. package/dist/worker/src/Addon/LineNumberAddon.d.ts +0 -39
  98. package/dist/worker/src/TerminalViewerVirtualDom/ReactVirtualized.d.ts +0 -71
  99. package/dist/worker/src/TerminalViewerVirtualDom/ReactVirtuoso.d.ts +0 -67
  100. package/dist/worker/types.d.ts +0 -30
package/README.md CHANGED
@@ -119,14 +119,16 @@ webpack 配置:
119
119
  ```
120
120
 
121
121
  ## 发布
122
+
122
123
  打标签后使用流水线发布或使用常规方式手动发布:
123
124
 
124
125
  ```bash
125
126
  npm version patch && npm publish
126
127
  ```
128
+
127
129
  ## 更新在线地址
128
130
 
129
- 合并代码后与打标签后使用流水线发布,使用常规方式合并代码与构建后,手动推送至deploy
131
+ 合并代码后与打标签后使用流水线发布,使用常规方式合并代码与构建后,手动推送至 deploy
130
132
 
131
133
  ## 修复已知问题
132
134
 
@@ -144,7 +146,7 @@ npm version patch && npm publish
144
146
  ## API
145
147
 
146
148
  | 属性名 | 描述 | 类型 | 默认值 |
147
- | --- | --- | --- | --- |
149
+ | --- | --- | --- | --- | --- | --- |
148
150
  | fit | 是否自动拉伸填充容器宽高 | boolean | true |
149
151
  | autoScroll | 是否开启自动滚动到底部 | boolean | true |
150
152
  | scrollToRow | 自动滚动到某一行,开启后自动滚动到底部失效 | number | -- |
@@ -0,0 +1,22 @@
1
+ export interface FlatLine {
2
+ type: 'start' | 'end' | 'log';
3
+ text: string;
4
+ }
5
+ export interface Stage {
6
+ stepId: string;
7
+ status: string;
8
+ startTime: string;
9
+ name: string;
10
+ startIndex: number;
11
+ endIndex?: number;
12
+ endStatus?: string;
13
+ endTime?: string;
14
+ logs: FlatLine[];
15
+ }
16
+ declare class LogParser {
17
+ stages: Stage[];
18
+ currentStage: Stage | null;
19
+ flatLines: FlatLine[];
20
+ parse(logs: string[]): void;
21
+ }
22
+ export default LogParser;
@@ -0,0 +1,129 @@
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 _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
3
+ 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."); }
4
+ 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); }
5
+ 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; }
6
+ 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; } }
7
+ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
8
+ function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
9
+ function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
10
+ function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
11
+ 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; }
12
+ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol" == _typeof(i) ? i : String(i); }
13
+ 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); }
14
+ /* eslint-disable no-continue */
15
+ /* eslint-disable no-plusplus */
16
+ // 阶段结构
17
+ var LogParser = /*#__PURE__*/function () {
18
+ function LogParser() {
19
+ _classCallCheck(this, LogParser);
20
+ _defineProperty(this, "stages", []);
21
+ // 所有阶段数据
22
+ _defineProperty(this, "currentStage", null);
23
+ // 当前正在解析入的阶段
24
+ _defineProperty(this, "flatLines", []);
25
+ }
26
+ _createClass(LogParser, [{
27
+ key: "parse",
28
+ value:
29
+ // 扁平化行数组(最终给 Virtuoso)
30
+
31
+ function parse(logs) {
32
+ if (!logs || !Array.isArray(logs)) {
33
+ return;
34
+ }
35
+
36
+ // 重置状态
37
+ this.stages = [];
38
+ this.currentStage = null;
39
+ this.flatLines = [];
40
+
41
+ // flatLines 中的实际索引(不包含 START/END 行)
42
+ var flatLineIndex = 0;
43
+ for (var i = 0; i < logs.length; i++) {
44
+ var line = logs[i];
45
+ // START_stepId_status_startTime_stepName
46
+ if (line.startsWith('START_')) {
47
+ // 如果需要解析 stepId 等,可以在这里 split 一次
48
+ var _line$split = line.split('_'),
49
+ _line$split2 = _slicedToArray(_line$split, 5),
50
+ stepId = _line$split2[1],
51
+ status = _line$split2[2],
52
+ startTime = _line$split2[3],
53
+ name = _line$split2[4];
54
+ this.currentStage = {
55
+ stepId: stepId,
56
+ status: status,
57
+ startTime: startTime,
58
+ name: name,
59
+ // startIndex 记录在 flatLines 中的位置(不包含 START 行本身)
60
+ startIndex: flatLineIndex,
61
+ endIndex: undefined,
62
+ logs: []
63
+ };
64
+
65
+ // 不将 START 行加入到 flatLines 中
66
+ // this.currentStage.logs.push({ type: 'start', text: line });
67
+ continue;
68
+ }
69
+
70
+ // END_stepId_status_endTime_stepName
71
+ if (line.startsWith('END_')) {
72
+ var _line$split3 = line.split('_'),
73
+ _line$split4 = _slicedToArray(_line$split3, 4),
74
+ endStatus = _line$split4[2],
75
+ endTime = _line$split4[3];
76
+ if (this.currentStage) {
77
+ // 不将 END 行加入到 flatLines 中
78
+ // 但保留在 stage.logs 中用于其他用途
79
+ // this.currentStage.logs.push({ type: 'end', text: line });
80
+ this.currentStage.endTime = endTime;
81
+ this.currentStage.endStatus = endStatus;
82
+ // endIndex 记录在 flatLines 中的位置(不包含 END 行本身)
83
+ // 如果当前阶段有日志行,endIndex 是最后一个日志行的索引(flatLineIndex - 1)
84
+ // 如果当前阶段没有日志行,endIndex 等于 startIndex - 1(表示阶段开始前的位置)
85
+ // 但如果 startIndex 为 0,则 endIndex 也为 0
86
+ if (flatLineIndex > this.currentStage.startIndex) {
87
+ // 阶段有日志行
88
+ this.currentStage.endIndex = flatLineIndex - 1;
89
+ } else {
90
+ // 阶段没有日志行
91
+ this.currentStage.endIndex = this.currentStage.startIndex > 0 ? this.currentStage.startIndex - 1 : this.currentStage.startIndex;
92
+ }
93
+ this.stages.push(this.currentStage);
94
+ this.currentStage = null;
95
+ }
96
+ continue;
97
+ }
98
+
99
+ // 普通日志行
100
+ this.flatLines.push({
101
+ type: 'log',
102
+ text: line
103
+ });
104
+ flatLineIndex++;
105
+ // 普通日志行
106
+ if (this.currentStage) {
107
+ this.currentStage.logs.push({
108
+ type: 'log',
109
+ text: line
110
+ });
111
+ }
112
+ }
113
+ if (this.currentStage) {
114
+ // 处理未结束的阶段
115
+ if (flatLineIndex > this.currentStage.startIndex) {
116
+ // 阶段有日志行
117
+ this.currentStage.endIndex = flatLineIndex - 1;
118
+ } else {
119
+ // 阶段没有日志行
120
+ this.currentStage.endIndex = this.currentStage.startIndex > 0 ? this.currentStage.startIndex - 1 : this.currentStage.startIndex;
121
+ }
122
+ this.stages.push(this.currentStage);
123
+ this.currentStage = null;
124
+ }
125
+ }
126
+ }]);
127
+ return LogParser;
128
+ }();
129
+ export default LogParser;
@@ -1,7 +1,7 @@
1
1
  function LogWorker() {
2
2
  var workerPath = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '/worker';
3
3
  var worker = null;
4
- var version = "3.0.0-beta.2" || '0.0.0';
4
+ var version = "3.0.0-beta.20" || '0.0.0';
5
5
  var path = workerPath.includes('http') ? "".concat(workerPath, "/log.worker.js") : "".concat(window.location.origin).concat(workerPath, "/log.worker.js");
6
6
  var blob = new Blob(["importScripts(\"".concat(path, "?v=").concat(version, "\")")], {
7
7
  type: 'application/javascript'
@@ -1,20 +1,44 @@
1
1
  import type { ISearchOptions } from '../SearchAddon';
2
+ import { type FlatLine, type Stage } from './LogParser';
2
3
  export default class Logs {
3
4
  private id;
4
5
  private string;
5
6
  private searcher;
6
- private logDataMap;
7
+ private parser;
8
+ private parserMap;
9
+ private ansiUp;
7
10
  constructor({ id, string }: {
8
11
  id: string;
9
12
  string: string;
10
13
  });
11
- convert(): string[];
12
- getArrayData(): any;
14
+ /**
15
+ * 更新字符串并重新解析
16
+ */
17
+ updateString(newString: string): void;
18
+ /**
19
+ * 解析原始字符串,识别 START/END 标记,构建 stages 和 flatLines
20
+ */
21
+ private parse;
22
+ /**
23
+ * 获取 HTML 转换后的数组数据(基于 parse 的结果,不包含 START/END 行)
24
+ */
25
+ getArrayData(): string[];
26
+ /**
27
+ * 获取解析后的 stages
28
+ */
29
+ getStages(): Stage[];
30
+ /**
31
+ * 获取解析后的 flatLines(已进行 HTML 转换)
32
+ */
33
+ getFlatLines(): FlatLine[];
34
+ /**
35
+ * 搜索功能,基于 flatLines 进行搜索
36
+ */
13
37
  mark(keyword: string, hlIndex?: number, options?: ISearchOptions | undefined): {
14
38
  count: number;
15
39
  map: {
16
- [key: string]: string;
17
- [key: number]: string;
40
+ [key: string]: string | Record<string, string>;
41
+ [key: number]: string | Record<string, string>;
18
42
  };
19
43
  markedKey: number;
20
44
  };
@@ -1,3 +1,5 @@
1
+ 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; }
2
+ 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; }
1
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); }
2
4
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3
5
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
@@ -7,6 +9,7 @@ function _toPropertyKey(t) { var i = _toPrimitive(t, "string"); return "symbol"
7
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); }
8
10
  import { default as AnsiUp } from 'ansi_up';
9
11
  import LimitMap from "./LimitMap";
12
+ import LogParser from "./LogParser";
10
13
  import Searcher from "./Searcher";
11
14
  var Logs = /*#__PURE__*/function () {
12
15
  function Logs(_ref) {
@@ -16,32 +19,136 @@ var Logs = /*#__PURE__*/function () {
16
19
  _defineProperty(this, "id", void 0);
17
20
  _defineProperty(this, "string", void 0);
18
21
  _defineProperty(this, "searcher", void 0);
19
- _defineProperty(this, "logDataMap", void 0);
22
+ _defineProperty(this, "parser", void 0);
23
+ _defineProperty(this, "parserMap", void 0);
24
+ _defineProperty(this, "ansiUp", void 0);
20
25
  this.id = id;
21
26
  this.string = string;
22
- this.searcher = new Searcher();
23
- this.logDataMap = new LimitMap({
27
+ this.searcher = new Searcher({
28
+ calculateSearchText: function calculateSearchText(line) {
29
+ // 处理 FlatLine 对象,提取 text 字段
30
+ if (line && _typeof(line) === 'object' && 'text' in line) {
31
+ return line.text || '';
32
+ }
33
+ return '';
34
+ }
35
+ });
36
+ this.parserMap = new LimitMap({
24
37
  limit: 1
25
38
  });
39
+ this.parser = new LogParser();
40
+ this.ansiUp = new AnsiUp();
41
+ // 初始化时进行解析
42
+ this.parse();
26
43
  }
44
+
45
+ /**
46
+ * 更新字符串并重新解析
47
+ */
27
48
  _createClass(Logs, [{
28
- key: "convert",
29
- value: function convert() {
49
+ key: "updateString",
50
+ value: function updateString(newString) {
51
+ if (this.string !== newString) {
52
+ this.string = newString;
53
+ // 清除缓存,强制重新解析
54
+ this.parserMap.delete(this.id);
55
+ this.parse();
56
+ }
57
+ }
58
+
59
+ /**
60
+ * 解析原始字符串,识别 START/END 标记,构建 stages 和 flatLines
61
+ */
62
+ }, {
63
+ key: "parse",
64
+ value: function parse() {
65
+ var _this = this;
30
66
  if (this.string.length === 0) {
31
- return [];
67
+ return;
68
+ }
69
+
70
+ // 如果已经解析过且缓存存在,直接使用缓存的解析结果
71
+ if (this.parserMap.has(this.id)) {
72
+ var cachedParser = this.parserMap.get(this.id);
73
+ if (cachedParser) {
74
+ this.parser = cachedParser;
75
+ return;
76
+ }
32
77
  }
33
- return this.string.split('\r\n').map(function (content) {
34
- return new AnsiUp().ansi_to_html(content);
78
+
79
+ // 创建新的解析器实例
80
+ var newParser = new LogParser();
81
+
82
+ // 分割原始字符串为行数组(不进行 HTML 转换)
83
+ var rawLines = this.string.split('\r\n');
84
+
85
+ // 解析日志结构
86
+ newParser.parse(rawLines);
87
+
88
+ // 对 flatLines 中的 text 进行 HTML 转换(用于展示)
89
+ newParser.flatLines = newParser.flatLines.map(function (line) {
90
+ // 只对普通日志行进行 HTML 转换,START/END 行已经在 flatLines 中被移除了
91
+ if (line.type === 'log') {
92
+ return _objectSpread(_objectSpread({}, line), {}, {
93
+ text: _this.ansiUp.ansi_to_html(line.text)
94
+ });
95
+ }
96
+ return line;
97
+ });
98
+
99
+ // 对 stages 中的 logs 也进行 HTML 转换(用于其他用途)
100
+ newParser.stages = newParser.stages.map(function (stage) {
101
+ return _objectSpread(_objectSpread({}, stage), {}, {
102
+ logs: stage.logs.map(function (log) {
103
+ if (log.type === 'log') {
104
+ return _objectSpread(_objectSpread({}, log), {}, {
105
+ text: _this.ansiUp.ansi_to_html(log.text)
106
+ });
107
+ }
108
+ return log;
109
+ })
110
+ });
35
111
  });
112
+
113
+ // 保存解析结果
114
+ this.parser = newParser;
115
+ // 缓存解析结果
116
+ this.parserMap.set(this.id, this.parser);
36
117
  }
118
+
119
+ /**
120
+ * 获取 HTML 转换后的数组数据(基于 parse 的结果,不包含 START/END 行)
121
+ */
37
122
  }, {
38
123
  key: "getArrayData",
39
124
  value: function getArrayData() {
40
- if (!this.logDataMap.has(this.id)) {
41
- this.logDataMap.set(this.id, this.convert());
42
- }
43
- return this.logDataMap.get(this.id) || [];
125
+ // 直接使用 parse 的结果,提取 flatLines 中的 text(已进行 HTML 转换)
126
+ return this.parser.flatLines.map(function (line) {
127
+ return line.text;
128
+ });
129
+ }
130
+
131
+ /**
132
+ * 获取解析后的 stages
133
+ */
134
+ }, {
135
+ key: "getStages",
136
+ value: function getStages() {
137
+ return this.parser.stages;
138
+ }
139
+
140
+ /**
141
+ * 获取解析后的 flatLines(已进行 HTML 转换)
142
+ */
143
+ }, {
144
+ key: "getFlatLines",
145
+ value: function getFlatLines() {
146
+ return this.parser.flatLines;
44
147
  }
148
+
149
+ /**
150
+ * 搜索功能,基于 flatLines 进行搜索
151
+ */
45
152
  }, {
46
153
  key: "mark",
47
154
  value: function mark(keyword) {
@@ -50,7 +157,8 @@ var Logs = /*#__PURE__*/function () {
50
157
  if (!keyword) {
51
158
  return this.searcher.search(keyword, []);
52
159
  }
53
- return this.searcher.search(keyword, this.getArrayData(), hlIndex, options);
160
+ // 基于 flatLines 进行搜索(不包含 START/END 行)
161
+ return this.searcher.search(keyword, this.parser.flatLines, hlIndex, options);
54
162
  }
55
163
  }]);
56
164
  return Logs;
@@ -1,15 +1,17 @@
1
1
  import { ISearchOptions } from '../SearchAddon';
2
+ export interface IOptions {
3
+ markClassName?: string;
4
+ markedClassName?: string;
5
+ calculateSearchText?: (line: Record<string, string>) => string;
6
+ }
2
7
  export default class Searcher {
3
8
  private options;
4
- constructor(options?: {
5
- markClassName: string;
6
- markedClassName: string;
7
- });
8
- search(keyword: string, logs: Array<string>, hlIndex?: number, options?: ISearchOptions | undefined): {
9
+ constructor(options?: IOptions);
10
+ search(keyword: string, logs: Array<string | Record<string, string>>, hlIndex?: number, options?: ISearchOptions | undefined): {
9
11
  count: number;
10
12
  map: {
11
- [key: string]: string;
12
- [key: number]: string;
13
+ [key: string]: string | Record<string, string>;
14
+ [key: number]: string | Record<string, string>;
13
15
  };
14
16
  markedKey: number;
15
17
  };
@@ -1,4 +1,6 @@
1
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; }
2
4
  function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
3
5
  function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, _toPropertyKey(descriptor.key), descriptor); } }
4
6
  function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); Object.defineProperty(Constructor, "prototype", { writable: false }); return Constructor; }
@@ -10,14 +12,13 @@ function _toPrimitive(t, r) { if ("object" != _typeof(t) || !t) return t; var e
10
12
  import Mark from "./Mark";
11
13
  var MAX_COUNT = 1000;
12
14
  var Searcher = /*#__PURE__*/function () {
13
- function Searcher() {
14
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {
15
- markClassName: 'terminal-viewer-hl-mark',
16
- markedClassName: 'terminal-viewer-hl-mark terminal-viewer-hl-marked'
17
- };
15
+ function Searcher(options) {
18
16
  _classCallCheck(this, Searcher);
19
17
  _defineProperty(this, "options", void 0);
20
- this.options = options;
18
+ this.options = _objectSpread({
19
+ markClassName: 'terminal-viewer-hl-mark',
20
+ markedClassName: 'terminal-viewer-hl-mark terminal-viewer-hl-marked'
21
+ }, options || {});
21
22
  }
22
23
  _createClass(Searcher, [{
23
24
  key: "search",
@@ -34,7 +35,8 @@ var Searcher = /*#__PURE__*/function () {
34
35
  }
35
36
  var _this$options = this.options,
36
37
  markClassName = _this$options.markClassName,
37
- markedClassName = _this$options.markedClassName;
38
+ markedClassName = _this$options.markedClassName,
39
+ calculateSearchText = _this$options.calculateSearchText;
38
40
  var style = {
39
41
  color: options === null || options === void 0 || (_options$decorations = options.decorations) === null || _options$decorations === void 0 ? void 0 : _options$decorations.matchForegroundColor,
40
42
  background: options === null || options === void 0 || (_options$decorations2 = options.decorations) === null || _options$decorations2 === void 0 ? void 0 : _options$decorations2.matchBackground,
@@ -51,7 +53,17 @@ var Searcher = /*#__PURE__*/function () {
51
53
  if (count >= MAX_COUNT) {
52
54
  break;
53
55
  }
54
- var text = logs[i] || '';
56
+ var _line = logs[i];
57
+ var text = '';
58
+ // 对象,用 calculateSearchText 取值
59
+ if (_typeof(_line) === 'object') {
60
+ text = (calculateSearchText === null || calculateSearchText === void 0 ? void 0 : calculateSearchText(_line)) || '';
61
+ }
62
+ // string,直接使用
63
+ if (typeof _line === 'string') {
64
+ text = _line;
65
+ }
66
+ // 执行匹配查询逻辑
55
67
  if (!text.toLowerCase().includes(keyword.toLowerCase())) {
56
68
  // eslint-disable-next-line no-continue
57
69
  continue;
@@ -1,7 +1,7 @@
1
1
  /* eslint-disable no-restricted-globals */
2
- import WebWorkerServer from "./WebWokerServer";
3
2
  import LimitMap from "./LimitMap";
4
3
  import Logs from "./Logs";
4
+ import WebWorkerServer from "./WebWokerServer";
5
5
  var server = new WebWorkerServer(self);
6
6
  var logsInstanceMap = new LimitMap({
7
7
  limit: 8
@@ -14,11 +14,20 @@ server.on('highlight-log', function (ctx, _ref) {
14
14
  id: id,
15
15
  string: string
16
16
  }));
17
+ } else {
18
+ // 如果实例已存在,检查 string 是否变化,如果变化了需要更新并重新解析
19
+ var existingInstance = logsInstanceMap.get(id);
20
+ existingInstance.updateString(string);
17
21
  }
18
22
  var instance = logsInstanceMap.get(id);
23
+ var logs = (instance === null || instance === void 0 ? void 0 : instance.getArrayData()) || [];
24
+ var stages = (instance === null || instance === void 0 ? void 0 : instance.getStages()) || [];
25
+ var flatLines = (instance === null || instance === void 0 ? void 0 : instance.getFlatLines()) || [];
19
26
  ctx.send('highlight-log-success', {
20
27
  id: id,
21
- logs: instance === null || instance === void 0 ? void 0 : instance.getArrayData()
28
+ logs: logs,
29
+ stages: stages,
30
+ flatLines: flatLines
22
31
  });
23
32
  });
24
33
  server.on('search-log', function (ctx, _ref2) {
@@ -42,18 +51,35 @@ server.on('search-log', function (ctx, _ref2) {
42
51
  });
43
52
  return;
44
53
  }
54
+ // 确保有 Logs 实例
45
55
  if (!logsInstanceMap.has(id)) {
46
56
  logsInstanceMap.set(id, new Logs({
47
57
  id: id,
48
58
  string: string
49
59
  }));
60
+ } else {
61
+ // 如果实例已存在,检查 string 是否变化,如果变化了需要更新并重新解析
62
+ var existingInstance = logsInstanceMap.get(id);
63
+ existingInstance.updateString(string);
50
64
  }
51
65
  var instance = logsInstanceMap.get(id);
52
66
  if (instance) {
67
+ // 使用 Logs 实例的 mark 方法进行搜索(基于 flatLines)
68
+ var result = instance.mark(keyword, hlIndex, options);
53
69
  ctx.send('search-log-success', {
54
70
  id: id,
55
71
  searchId: searchId,
56
- searcherResult: instance.mark(keyword, hlIndex, options) || {
72
+ searcherResult: result || {
73
+ map: {},
74
+ count: 0,
75
+ markedKey: 0
76
+ }
77
+ });
78
+ } else {
79
+ ctx.send('search-log-success', {
80
+ id: id,
81
+ searchId: searchId,
82
+ searcherResult: {
57
83
  map: {},
58
84
  count: 0,
59
85
  markedKey: 0
@@ -8,7 +8,7 @@ export interface IRemoteOptions {
8
8
  retry?: number;
9
9
  enableBatch?: boolean;
10
10
  }
11
- export type UseRemoteHooks = (defaultData: string, callback?: (string: string) => void, options?: IRemoteOptions | undefined, cacheOptions?: ICacheOptions) => {
11
+ export type UseRemoteHooks = (defaultData: string, callback?: (string: string) => void, options?: IRemoteOptions | undefined, cacheOptions?: ICacheOptions, incremental?: boolean) => {
12
12
  data: string;
13
13
  refresh: () => void;
14
14
  cacheStore: LocalForage;
@@ -312,7 +312,7 @@ export var useSequenceFetch = function useSequenceFetch(fetch, callback, options
312
312
  cacheStore: store
313
313
  };
314
314
  };
315
- var useRemote = function useRemote(defaultData, callback, options, cacheOptions) {
315
+ var useRemote = function useRemote(defaultData, callback, options, cacheOptions, incremental) {
316
316
  var _ref5 = options !== null && options !== void 0 ? options : {},
317
317
  fetch = _ref5.fetch,
318
318
  _ref5$timeout = _ref5.timeout,
@@ -334,7 +334,8 @@ var useRemote = function useRemote(defaultData, callback, options, cacheOptions)
334
334
  return _regeneratorRuntime().wrap(function _callee6$(_context6) {
335
335
  while (1) switch (_context6.prev = _context6.next) {
336
336
  case 0:
337
- setData(function (p) {
337
+ // 增量模式时,只返回当前结果
338
+ setData(incremental ? result : function (p) {
338
339
  return p + result;
339
340
  });
340
341
  incrementalRef.current = result;
@@ -1,5 +1,5 @@
1
- import { useRef, useCallback, useEffect } from 'react';
2
1
  import throttle from 'lodash.throttle';
2
+ import { useCallback, useEffect, useRef } from 'react';
3
3
  var useThrottle = function useThrottle(cb) {
4
4
  var delay = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1000;
5
5
  var cbRef = useRef(cb);
@@ -1,5 +1,5 @@
1
1
  /// <reference types="react" />
2
- import type { SearchResultCallback, SearcherRef, SearcherResult } from '../Addon/WorkerLog/types';
2
+ import type { SearcherRef, SearcherResult, SearchResultCallback } from '../Addon/WorkerLog/types';
3
3
  export declare const useWorkerLogs: (string: string, changeCallback?: SearchResultCallback) => {
4
4
  logs: string[];
5
5
  working: boolean;
@@ -7,9 +7,9 @@ function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; }
7
7
  /* eslint-disable @typescript-eslint/no-explicit-any */
8
8
  import { useEffect, useRef, useState } from 'react';
9
9
  import { v4 as uuidv4 } from 'uuid';
10
- import WebWorkerClient from "../Addon/WorkerLog/WebWorkerClient";
11
10
  import globalContext from "../Addon/WorkerLog/GlobalContext";
12
11
  import LogWorker from "../Addon/WorkerLog/LogWorker";
12
+ import WebWorkerClient from "../Addon/WorkerLog/WebWorkerClient";
13
13
  export var useWorkerLogs = function useWorkerLogs(string, changeCallback) {
14
14
  var prefixRef = useRef('prefix');
15
15
  var _useState = useState([]),
@@ -1,10 +1,10 @@
1
- import { ITerminalOptions } from '@xterm/xterm';
1
+ import { ITerminalOptions, Terminal } from '@xterm/xterm';
2
2
  import React from 'react';
3
3
  import type { IHighlightOptions } from '../Addon/HighlightAddon';
4
4
  import type { ISearchOptions } from '../Addon/SearchAddon';
5
5
  import type { ICacheOptions } from '../Hooks/useCache';
6
6
  import type { IRemoteOptions } from '../Hooks/useRemote';
7
- import { ExtraOptions, LogAfterProps, TerminalRef } from '../types';
7
+ import { ExtraOptions, LogAfterProps, TerminalRef, VirtualDomTerminal } from '../types';
8
8
  import './index.less';
9
9
  export interface TerminalViewerProps {
10
10
  /**
@@ -180,6 +180,19 @@ export interface TerminalViewerProps {
180
180
  * @description.zh-CN 刷新后的回调函数
181
181
  */
182
182
  onRefresh?: () => void;
183
+ /**
184
+ * @description.zh-CN 折叠状态变更后的回调
185
+ */
186
+ onCollapseStatusChange?: (allCollapsed: boolean) => void;
187
+ /**
188
+ * @description.zh-CN 折叠操作
189
+ */
190
+ collapseAction?: (terminal: Terminal | VirtualDomTerminal, allCollapsed: boolean) => React.ReactNode;
191
+ /**
192
+ * @description.zh-CN 日志分组默认折叠状态
193
+ * @default false
194
+ */
195
+ defaultGroupCollapsed?: boolean;
183
196
  }
184
- declare const TerminalViewer: React.ForwardRefExoticComponent<Omit<TerminalViewerProps, "ref"> & React.RefAttributes<TerminalRef | undefined>>;
197
+ declare const TerminalViewer: React.ForwardRefExoticComponent<Omit<TerminalViewerProps, "ref"> & React.RefAttributes<TerminalRef<VirtualDomTerminal | Terminal> | undefined>>;
185
198
  export default TerminalViewer;