@rsdoctor/components 0.3.12-alpha.0 → 0.4.1

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.
@@ -1,5 +1,4 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
- import { createElement } from "react";
3
2
  import React, { useState } from "react";
4
3
  import {
5
4
  Space,
@@ -25,63 +24,60 @@ import { TextDrawer } from "../TextDrawer";
25
24
  import { Title } from "../Title";
26
25
  import { Size, Color } from "../../constants";
27
26
  import { Badge as Bdg } from "../Badge";
28
- import { FileHightLightViewer } from "../CodeViewer";
29
27
  import { withServerAPI } from "../Manifest";
30
- const PackageRelationReasons = ({ data, cwd }) => {
28
+ const TextDrawerWidth = "60%";
29
+ const PackageRelationReasons = ({ data }) => {
31
30
  const [index, setIndex] = useState(0);
32
31
  const { t } = useI18n();
33
- return /* @__PURE__ */ jsxs(Row, { gutter: Size.BasePadding, wrap: false, align: "top", children: [
34
- /* @__PURE__ */ jsx(Col, { span: 12, style: { height: "100%" }, children: /* @__PURE__ */ jsx(
35
- Card,
36
- {
37
- title: `The reasons for importing this version`,
38
- style: { height: "100%" },
39
- extra: /* @__PURE__ */ jsx(
40
- Popover,
41
- {
42
- content: /* @__PURE__ */ jsx(Typography.Text, { children: t("DuplicatePakCodeExplain") }),
43
- children: /* @__PURE__ */ jsx("a", { href: "#", children: "Explain" })
44
- }
45
- ),
46
- bodyStyle: { overflow: "scroll" },
47
- children: data.length ? /* @__PURE__ */ jsxs(React.Fragment, { children: [
48
- /* @__PURE__ */ jsx("div", { style: { marginBottom: Size.BasePadding }, children: /* @__PURE__ */ jsx(Typography.Text, { type: "secondary", strong: true, children: "Click the file path below to show the reason in code viewer." }) }),
49
- /* @__PURE__ */ jsx(Timeline, { children: data.map((e, i) => {
50
- const { dependency, module, relativePath } = e;
51
- const { statements } = dependency;
52
- const { start } = statements?.[0]?.position ? module.isPreferSource ? statements[0].position.source : statements[0].position.transformed : { start: { line: 0, column: 0 } };
53
- const text = `${relativePath}:${start.line}:${start.column || 1}`;
54
- return /* @__PURE__ */ jsx(
55
- Timeline.Item,
56
- {
57
- style: { cursor: "pointer" },
58
- dot: i === data.length - 1 ? void 0 : "⬇️",
59
- children: /* @__PURE__ */ jsx(
60
- Typography.Text,
61
- {
62
- copyable: { text: relativePath },
63
- onClick: (e2) => {
64
- e2.preventDefault();
65
- e2.stopPropagation();
66
- setIndex(i);
67
- },
68
- strong: i === index,
69
- style: {
70
- color: i === index ? Color.Blue : "inherit",
71
- display: "block"
72
- },
73
- children: text
74
- }
75
- )
76
- },
77
- text
78
- );
79
- }) })
80
- ] }) : /* @__PURE__ */ jsx(Empty, { description: "This package no dependencies" })
81
- }
82
- ) }),
83
- /* @__PURE__ */ jsx(Col, { span: 12, style: { height: "100%" }, children: /* @__PURE__ */ createElement(FileHightLightViewer, { ...data[index], key: index, cwd }) })
84
- ] });
32
+ return /* @__PURE__ */ jsx(Row, { gutter: Size.BasePadding, wrap: false, align: "top", children: /* @__PURE__ */ jsx(Col, { span: 20, style: { height: "100%" }, children: /* @__PURE__ */ jsx(
33
+ Card,
34
+ {
35
+ title: `The reasons for importing this version`,
36
+ style: { height: "100%" },
37
+ extra: /* @__PURE__ */ jsx(
38
+ Popover,
39
+ {
40
+ content: /* @__PURE__ */ jsx(Typography.Text, { children: t("DuplicatePakCodeExplain") }),
41
+ children: /* @__PURE__ */ jsx("a", { href: "#", children: "Explain" })
42
+ }
43
+ ),
44
+ bodyStyle: { overflow: "scroll" },
45
+ children: data.length ? /* @__PURE__ */ jsxs(React.Fragment, { children: [
46
+ /* @__PURE__ */ jsx("div", { style: { marginBottom: Size.BasePadding }, children: /* @__PURE__ */ jsx(Typography.Text, { type: "secondary", strong: true, children: "Click the file path below to show the reason in code viewer." }) }),
47
+ /* @__PURE__ */ jsx(Timeline, { children: data.map((e, i) => {
48
+ const { dependency, module, relativePath } = e;
49
+ const { statements } = dependency;
50
+ const { start } = statements?.[0]?.position ? module.isPreferSource ? statements[0].position.source : statements[0].position.transformed : { start: { line: 0, column: 0 } };
51
+ const text = `${relativePath}:${start.line}:${start.column || 1}`;
52
+ return /* @__PURE__ */ jsx(
53
+ Timeline.Item,
54
+ {
55
+ style: { cursor: "pointer" },
56
+ dot: i === data.length - 1 ? void 0 : "⬇️",
57
+ children: /* @__PURE__ */ jsx(
58
+ Typography.Text,
59
+ {
60
+ copyable: { text: relativePath },
61
+ onClick: (e2) => {
62
+ e2.preventDefault();
63
+ e2.stopPropagation();
64
+ setIndex(i);
65
+ },
66
+ strong: i === index,
67
+ style: {
68
+ color: i === index ? Color.Blue : "inherit",
69
+ display: "block"
70
+ },
71
+ children: text
72
+ }
73
+ )
74
+ },
75
+ text
76
+ );
77
+ }) })
78
+ ] }) : /* @__PURE__ */ jsx(Empty, { description: "This package no dependencies" })
79
+ }
80
+ ) }) });
85
81
  };
86
82
  const PackageRelationReasonsWithServer = withServerAPI({
87
83
  Component: PackageRelationReasons,
@@ -226,7 +222,7 @@ const PackageRelationAlert = ({
226
222
  {
227
223
  text: "Show Relations",
228
224
  buttonProps: { size: "small" },
229
- drawerProps: { title: data.title },
225
+ drawerProps: { title: data.title, width: TextDrawerWidth },
230
226
  children: /* @__PURE__ */ jsxs(Space, { direction: "vertical", className: "alert-space", children: [
231
227
  /* @__PURE__ */ jsxs(Space, { style: { marginBottom: Size.BasePadding / 2 }, children: [
232
228
  /* @__PURE__ */ jsx(Title, { text: name, upperFisrt: false }),
@@ -7,6 +7,7 @@ interface CodeViewerProps {
7
7
  defaultLine?: number;
8
8
  ranges?: SDK.SourceRange[];
9
9
  editorConfig?: editor.IStandaloneEditorConstructionOptions;
10
+ emptyReason?: string;
10
11
  }
11
12
  export declare const CodeViewer: React.FC<CodeViewerProps>;
12
13
  export declare const CodeViewerWithDrawer: React.FC<CodeViewerProps>;
@@ -5,7 +5,15 @@ import { CodepenCircleOutlined } from "@ant-design/icons";
5
5
  import { getOriginalLanguage, getSelectionRange } from "../../utils";
6
6
  import { DefaultEditorConfig } from "./config";
7
7
  import { TextDrawer } from "../TextDrawer";
8
- const CodeViewer = ({ content, ranges, path, defaultLine, editorConfig = {} }) => {
8
+ import { Empty } from "antd";
9
+ const CodeViewer = ({
10
+ content,
11
+ ranges,
12
+ path,
13
+ defaultLine,
14
+ editorConfig = {},
15
+ emptyReason
16
+ }) => {
9
17
  const handleEditorDidMount = (editor, monaco) => {
10
18
  if (isNumber(defaultLine)) {
11
19
  editor.revealLine(defaultLine);
@@ -22,7 +30,7 @@ const CodeViewer = ({ content, ranges, path, defaultLine, editorConfig = {} }) =
22
30
  );
23
31
  }
24
32
  };
25
- return /* @__PURE__ */ jsx(
33
+ return content ? /* @__PURE__ */ jsx(
26
34
  Editor,
27
35
  {
28
36
  theme: "vs-dark",
@@ -33,7 +41,7 @@ const CodeViewer = ({ content, ranges, path, defaultLine, editorConfig = {} }) =
33
41
  options: { ...DefaultEditorConfig, ...editorConfig },
34
42
  onMount: handleEditorDidMount
35
43
  }
36
- );
44
+ ) : /* @__PURE__ */ jsx(Empty, { description: emptyReason });
37
45
  };
38
46
  const CodeViewerWithDrawer = (props) => {
39
47
  return /* @__PURE__ */ jsx(
@@ -1,12 +1,29 @@
1
1
  import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import React, { useCallback, useMemo, useRef, useState } from "react";
3
3
  import { endsWith, get, sumBy } from "lodash-es";
4
- import { Card, Col, Descriptions, Divider, Drawer, Row, Space, Table, Tooltip, Typography } from "antd";
4
+ import {
5
+ Card,
6
+ Col,
7
+ Descriptions,
8
+ Divider,
9
+ Drawer,
10
+ Row,
11
+ Space,
12
+ Table,
13
+ Tooltip,
14
+ Typography
15
+ } from "antd";
5
16
  import { CloseCircleOutlined } from "@ant-design/icons";
6
17
  import { Constants, SDK } from "@rsdoctor/types";
7
18
  import { ServerAPIProvider } from "../../Manifest";
8
19
  import { drawerWidth, Size } from "../../../constants";
9
- import { createFileStructures, formatCosts, mapFileKey, filterLoader, useMonacoEditor } from "../../../utils";
20
+ import {
21
+ createFileStructures,
22
+ formatCosts,
23
+ mapFileKey,
24
+ filterLoader,
25
+ useMonacoEditor
26
+ } from "../../../utils";
10
27
  import { LoaderExecutions } from "../executions";
11
28
  import { FileTree } from "../../FileTree";
12
29
  import { Keyword } from "../../Keyword";
@@ -22,9 +39,13 @@ const LoaderFiles = (props) => {
22
39
  const init = useCallback(async () => {
23
40
  await initMonaco(monacoRef);
24
41
  }, []);
25
- const maxHeight = 700;
42
+ const maxHeight = 800;
26
43
  const filteredFiles = useMemo(
27
- () => filetree.filter((e) => e.loaders.some((l) => filterLoader(e.path, l.loader, props.filename, props.loaders))),
44
+ () => filetree.filter(
45
+ (e) => e.loaders.some(
46
+ (l) => filterLoader(e.path, l.loader, props.filename, props.loaders)
47
+ )
48
+ ),
28
49
  [props.filename, props.loaders]
29
50
  );
30
51
  const inlinedResourcePathKey = "__RESOURCEPATH__";
@@ -69,7 +90,14 @@ const LoaderFiles = (props) => {
69
90
  setDrawerVisible(true);
70
91
  },
71
92
  children: [
72
- /* @__PURE__ */ jsx(Typography.Text, { style: { maxWidth: 135, color: "inherit" }, ellipsis: true, children: e.loader }),
93
+ /* @__PURE__ */ jsx(
94
+ Typography.Text,
95
+ {
96
+ style: { maxWidth: 135, color: "inherit" },
97
+ ellipsis: true,
98
+ children: e.loader
99
+ }
100
+ ),
73
101
  /* @__PURE__ */ jsx(Divider, { type: "vertical" }),
74
102
  isError ? /* @__PURE__ */ jsx(CloseCircleOutlined, {}) : /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: formatCosts(e.costs) })
75
103
  ]
@@ -93,16 +121,20 @@ const LoaderFiles = (props) => {
93
121
  "Total Files: ",
94
122
  filteredFiles.length
95
123
  ] }),
96
- bodyStyle: { overflow: "scroll", maxHeight },
124
+ bodyStyle: { overflow: "scroll", maxHeight, height: "40rem" },
97
125
  children: [
98
126
  /* @__PURE__ */ jsx(
99
127
  FileTree,
100
128
  {
101
- defaultExpandedKeys: mapFileKey(files, filteredFiles.length >= 100 ? 3 : 4, (node) => {
102
- const resourcePath2 = get(node, inlinedResourcePathKey);
103
- const isNodeModules = resourcePath2.indexOf("/node_modules/") > -1;
104
- return !isNodeModules;
105
- }),
129
+ defaultExpandedKeys: mapFileKey(
130
+ files,
131
+ filteredFiles.length >= 100 ? 3 : 4,
132
+ (node) => {
133
+ const resourcePath2 = get(node, inlinedResourcePathKey);
134
+ const isNodeModules = resourcePath2.indexOf("/node_modules/") > -1;
135
+ return !isNodeModules;
136
+ }
137
+ ),
106
138
  treeData: files,
107
139
  onSelect: (_e, info) => {
108
140
  init();
@@ -124,7 +156,14 @@ const LoaderFiles = (props) => {
124
156
  width: drawerWidth,
125
157
  zIndex: 999,
126
158
  bodyStyle: { padding: 0 },
127
- children: drawerVisible ? /* @__PURE__ */ jsx(ServerAPIProvider, { api: SDK.ServerAPI.API.GetLoaderFileDetails, body: { path: resourcePath }, children: (data) => /* @__PURE__ */ jsx(LoaderExecutions, { data, cwd, index: loaderIndex }) }) : null
159
+ children: drawerVisible ? /* @__PURE__ */ jsx(
160
+ ServerAPIProvider,
161
+ {
162
+ api: SDK.ServerAPI.API.GetLoaderFileDetails,
163
+ body: { path: resourcePath },
164
+ children: (data) => /* @__PURE__ */ jsx(LoaderExecutions, { data, cwd, index: loaderIndex })
165
+ }
166
+ ) : null
128
167
  }
129
168
  )
130
169
  ]
@@ -136,7 +175,10 @@ const LoaderFiles = (props) => {
136
175
  title: /* @__PURE__ */ jsx(
137
176
  Tooltip,
138
177
  {
139
- title: React.cloneElement(selectedNode.title, { style: { color: "#fff" } }),
178
+ title: React.cloneElement(
179
+ selectedNode.title,
180
+ { style: { color: "#fff" } }
181
+ ),
140
182
  children: /* @__PURE__ */ jsxs(Typography.Text, { children: [
141
183
  'Statistics of "',
142
184
  selectedNode.title,
@@ -152,7 +194,13 @@ const LoaderFiles = (props) => {
152
194
  children: (tableData) => /* @__PURE__ */ jsx(
153
195
  Table,
154
196
  {
155
- style: { width: "100%", maxHeight, overflowY: "scroll", wordBreak: "break-all" },
197
+ style: {
198
+ width: "100%",
199
+ maxHeight,
200
+ height: "40rem",
201
+ overflowY: "scroll",
202
+ wordBreak: "break-all"
203
+ },
156
204
  pagination: false,
157
205
  bordered: true,
158
206
  rowKey: (e) => e.loader,
@@ -175,11 +223,20 @@ const LoaderFiles = (props) => {
175
223
  }
176
224
  ],
177
225
  dataSource: tableData,
178
- footer: () => /* @__PURE__ */ jsxs(Descriptions, { title: "Total", bordered: true, layout: "vertical", size: "small", children: [
179
- /* @__PURE__ */ jsx(Descriptions.Item, { label: "loaders", children: tableData.length }),
180
- /* @__PURE__ */ jsx(Descriptions.Item, { label: "files", children: sumBy(tableData, (e) => e.files) }),
181
- /* @__PURE__ */ jsx(Descriptions.Item, { label: "duration", children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: formatCosts(sumBy(tableData, (e) => e.costs)) }) })
182
- ] })
226
+ footer: () => /* @__PURE__ */ jsxs(
227
+ Descriptions,
228
+ {
229
+ title: "Total",
230
+ bordered: true,
231
+ layout: "vertical",
232
+ size: "small",
233
+ children: [
234
+ /* @__PURE__ */ jsx(Descriptions.Item, { label: "loaders", children: tableData.length }),
235
+ /* @__PURE__ */ jsx(Descriptions.Item, { label: "files", children: sumBy(tableData, (e) => e.files) }),
236
+ /* @__PURE__ */ jsx(Descriptions.Item, { label: "duration", children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: formatCosts(sumBy(tableData, (e) => e.costs)) }) })
237
+ ]
238
+ }
239
+ )
183
240
  }
184
241
  )
185
242
  }
@@ -7,8 +7,22 @@ import { LoaderCommonSelect } from "../../Select";
7
7
  const LoaderAnalysisBase = ({ cwd }) => {
8
8
  const [store, setStore] = useState({ filename: "", loaders: [] });
9
9
  return /* @__PURE__ */ jsxs("div", { children: [
10
- /* @__PURE__ */ jsx(ServerAPIProvider, { api: SDK.ServerAPI.API.GetLoaderNames, children: (loaderNames) => /* @__PURE__ */ jsx(LoaderCommonSelect, { onChange: (e) => setStore(e), loaderNames }) }),
11
- /* @__PURE__ */ jsx(ServerAPIProvider, { api: SDK.ServerAPI.API.GetLoaderFileTree, children: (filetree) => /* @__PURE__ */ jsx(LoaderFiles, { filename: store.filename, filetree, loaders: store.loaders, cwd }) })
10
+ /* @__PURE__ */ jsx(ServerAPIProvider, { api: SDK.ServerAPI.API.GetLoaderNames, children: (loaderNames) => /* @__PURE__ */ jsx(
11
+ LoaderCommonSelect,
12
+ {
13
+ onChange: (e) => setStore(e),
14
+ loaderNames
15
+ }
16
+ ) }),
17
+ /* @__PURE__ */ jsx(ServerAPIProvider, { api: SDK.ServerAPI.API.GetLoaderFileTree, children: (filetree) => /* @__PURE__ */ jsx(
18
+ LoaderFiles,
19
+ {
20
+ filename: store.filename,
21
+ filetree,
22
+ loaders: store.loaders,
23
+ cwd
24
+ }
25
+ ) })
12
26
  ] });
13
27
  };
14
28
  const LoaderAnalysis = withServerAPI({
@@ -5,5 +5,5 @@ interface LoaderExecutionsProps {
5
5
  data: SDK.ServerAPI.InferResponseType<SDK.ServerAPI.API.GetLoaderFileDetails>;
6
6
  index?: number;
7
7
  }
8
- export declare const LoaderExecutions: ({ data, cwd, index }: PropsWithChildren<LoaderExecutionsProps>) => JSX.Element;
8
+ export declare const LoaderExecutions: ({ data, cwd, index, }: PropsWithChildren<LoaderExecutionsProps>) => JSX.Element;
9
9
  export {};
@@ -2,12 +2,30 @@ import { jsx, jsxs } from "react/jsx-runtime";
2
2
  import { ClockCircleOutlined } from "@ant-design/icons";
3
3
  import Editor from "@monaco-editor/react";
4
4
  import { Constants } from "@rsdoctor/types";
5
- import { Badge, Button, Col, Divider, Empty, Row, Space, Tag, Timeline, Tooltip, Typography } from "antd";
5
+ import {
6
+ Badge,
7
+ Button,
8
+ Col,
9
+ Divider,
10
+ Empty,
11
+ Row,
12
+ Space,
13
+ Tag,
14
+ Timeline,
15
+ Tooltip,
16
+ Typography,
17
+ Tabs
18
+ } from "antd";
6
19
  import dayjs from "dayjs";
7
20
  import { endsWith } from "lodash-es";
8
- import { useState } from "react";
21
+ import { useCallback, useState } from "react";
9
22
  import { Size } from "../../constants";
10
- import { beautifyPath, formatCosts, getModifiedLanguage, useTheme } from "../../utils";
23
+ import {
24
+ beautifyPath,
25
+ formatCosts,
26
+ getModifiedLanguage,
27
+ useTheme
28
+ } from "../../utils";
11
29
  import { Card } from "../Card";
12
30
  import { DiffViewer } from "../CodeViewer";
13
31
  import { CodeOpener } from "../Opener";
@@ -28,7 +46,92 @@ const LoaderInfoItem = ({
28
46
  /* @__PURE__ */ jsx(Col, { span: 18, children: /* @__PURE__ */ jsx(Typography.Paragraph, { ellipsis, strong: true, ...textProps, children: value }) })
29
47
  ] });
30
48
  };
31
- const LoaderExecutions = ({ data, cwd, index }) => {
49
+ const LoaderPropsItem = ({
50
+ loader,
51
+ hasError,
52
+ resource,
53
+ before,
54
+ cwd
55
+ }) => {
56
+ return /* @__PURE__ */ jsxs(
57
+ Card,
58
+ {
59
+ title: "Loader Details",
60
+ style: { border: "none" },
61
+ extra: /* @__PURE__ */ jsx(Tag, { icon: /* @__PURE__ */ jsx(ClockCircleOutlined, {}), color: "default", children: dayjs(loader.startAt).format("YYYY-MM-DD HH:mm:ss") }),
62
+ children: [
63
+ loader.isPitch ? /* @__PURE__ */ jsx(Typography.Text, { code: true, children: "pitch" }) : null,
64
+ loader.isPitch || hasError || !endsWith(resource.path, Constants.JSExtension) ? null : /* @__PURE__ */ jsx(JSIsEqualTag, { input: before, output: loader.result || "" }),
65
+ /* @__PURE__ */ jsxs(
66
+ Space,
67
+ {
68
+ direction: "vertical",
69
+ style: { padding: Size.BasePadding, wordBreak: "break-all" },
70
+ children: [
71
+ /* @__PURE__ */ jsx(
72
+ LoaderInfoItem,
73
+ {
74
+ label: "file path",
75
+ value: beautifyPath(resource.path, cwd),
76
+ code: true
77
+ }
78
+ ),
79
+ /* @__PURE__ */ jsx(
80
+ LoaderInfoItem,
81
+ {
82
+ label: "resource path",
83
+ value: /* @__PURE__ */ jsx(CodeOpener, { cwd, url: resource.path, loc: "", disabled: true })
84
+ }
85
+ ),
86
+ /* @__PURE__ */ jsx(
87
+ LoaderInfoItem,
88
+ {
89
+ label: "resource query",
90
+ value: resource.queryRaw || "-"
91
+ }
92
+ ),
93
+ /* @__PURE__ */ jsx(
94
+ LoaderInfoItem,
95
+ {
96
+ label: "duration",
97
+ value: formatCosts(loader.costs),
98
+ mark: true
99
+ }
100
+ ),
101
+ /* @__PURE__ */ jsx(LoaderInfoItem, { label: "loader name", value: loader.loader, code: true }),
102
+ /* @__PURE__ */ jsx(LoaderInfoItem, { label: "loader index", value: `${loader.loaderIndex}` }),
103
+ /* @__PURE__ */ jsx(
104
+ LoaderInfoItem,
105
+ {
106
+ label: "loader path",
107
+ value: /* @__PURE__ */ jsx(CodeOpener, { cwd, url: loader.path, loc: "", disabled: true })
108
+ }
109
+ ),
110
+ /* @__PURE__ */ jsx(
111
+ LoaderInfoItem,
112
+ {
113
+ label: "options",
114
+ value: JSON.stringify(loader.options || "-"),
115
+ copyable: true,
116
+ ellipsis: {
117
+ rows: 2,
118
+ expandable: true,
119
+ symbol: "more"
120
+ }
121
+ }
122
+ )
123
+ ]
124
+ }
125
+ )
126
+ ]
127
+ }
128
+ );
129
+ };
130
+ const LoaderExecutions = ({
131
+ data,
132
+ cwd,
133
+ index
134
+ }) => {
32
135
  const { loaders, resource } = data;
33
136
  const [currentIndex, setCurrentIndex] = useState(index || 0);
34
137
  const { theme } = useTheme();
@@ -37,12 +140,19 @@ const LoaderExecutions = ({ data, cwd, index }) => {
37
140
  const before = loader.input || "";
38
141
  const leftSpan = 5;
39
142
  const hasError = loader.errors && loader.errors.length;
143
+ const [activeKey, setActiveKey] = useState("loaderDetails");
144
+ const onChange = useCallback((key) => {
145
+ setActiveKey(key);
146
+ }, []);
40
147
  return /* @__PURE__ */ jsxs(Row, { style: { height: "100%" }, children: [
41
148
  /* @__PURE__ */ jsx(
42
149
  Col,
43
150
  {
44
151
  span: leftSpan,
45
- style: { borderRight: isLight ? `1px solid #f0f0f0` : void 0, padding: Size.BasePadding },
152
+ style: {
153
+ borderRight: isLight ? `1px solid #f0f0f0` : void 0,
154
+ padding: Size.BasePadding
155
+ },
46
156
  children: /* @__PURE__ */ jsxs(Space, { direction: "vertical", style: { width: "100%" }, children: [
47
157
  /* @__PURE__ */ jsx(Title, { text: "Executions" }),
48
158
  /* @__PURE__ */ jsx(Timeline, { mode: "left", style: { marginTop: Size.BasePadding }, children: loaders.map((e, i, arr) => {
@@ -62,11 +172,25 @@ const LoaderExecutions = ({ data, cwd, index }) => {
62
172
  setCurrentIndex(i);
63
173
  },
64
174
  style: { textAlign: "left" },
65
- children: /* @__PURE__ */ jsxs(Typography.Text, { ellipsis: true, style: { color: "inherit" }, children: [
66
- /* @__PURE__ */ jsx(Typography.Text, { strong: true, style: { color: "inherit" }, children: formatCosts(e.costs) }),
67
- /* @__PURE__ */ jsx(Divider, { type: "vertical" }),
68
- loader2
69
- ] })
175
+ children: /* @__PURE__ */ jsxs(
176
+ Typography.Text,
177
+ {
178
+ ellipsis: true,
179
+ style: { color: "inherit" },
180
+ children: [
181
+ /* @__PURE__ */ jsx(
182
+ Typography.Text,
183
+ {
184
+ strong: true,
185
+ style: { color: "inherit" },
186
+ children: formatCosts(e.costs)
187
+ }
188
+ ),
189
+ /* @__PURE__ */ jsx(Divider, { type: "vertical" }),
190
+ loader2
191
+ ]
192
+ }
193
+ )
70
194
  }
71
195
  ) }) }) }),
72
196
  i === arr.length - 1 ? null : /* @__PURE__ */ jsx("div", { style: { paddingTop: 10 }, children: /* @__PURE__ */ jsx(Typography.Text, { children: "⬇️" }) })
@@ -78,120 +202,141 @@ const LoaderExecutions = ({ data, cwd, index }) => {
78
202
  ] })
79
203
  }
80
204
  ),
81
- /* @__PURE__ */ jsxs(Col, { span: 24 - leftSpan, style: { height: "100%" }, children: [
82
- /* @__PURE__ */ jsx(Col, { span: 24, children: /* @__PURE__ */ jsxs(
83
- Card,
84
- {
85
- title: "Loader Details",
86
- style: { border: "none" },
87
- collapsable: true,
88
- defaultCollapsed: true,
89
- extra: /* @__PURE__ */ jsx(Tag, { icon: /* @__PURE__ */ jsx(ClockCircleOutlined, {}), color: "default", children: dayjs(loader.startAt).format("YYYY-MM-DD HH:mm:ss") }),
90
- children: [
91
- loader.isPitch ? /* @__PURE__ */ jsx(Typography.Text, { code: true, children: "pitch" }) : null,
92
- loader.isPitch || hasError || !endsWith(resource.path, Constants.JSExtension) ? null : /* @__PURE__ */ jsx(JSIsEqualTag, { input: before, output: loader.result || "" }),
93
- /* @__PURE__ */ jsxs(Space, { direction: "vertical", style: { padding: Size.BasePadding, wordBreak: "break-all" }, children: [
94
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "file path", value: beautifyPath(resource.path, cwd), code: true }),
205
+ /* @__PURE__ */ jsx(Col, { span: 24 - leftSpan, style: { height: "100%" }, children: /* @__PURE__ */ jsx(
206
+ Tabs,
207
+ {
208
+ type: "card",
209
+ defaultActiveKey: "loaderDetails",
210
+ activeKey,
211
+ items: [
212
+ {
213
+ label: "Loader Props",
214
+ key: "loaderProps",
215
+ children: /* @__PURE__ */ jsx(
216
+ LoaderPropsItem,
217
+ {
218
+ loader,
219
+ hasError,
220
+ resource,
221
+ before,
222
+ cwd
223
+ }
224
+ )
225
+ },
226
+ {
227
+ label: "Loader Details",
228
+ key: "loaderDetails",
229
+ children: /* @__PURE__ */ jsx("div", { style: { height: "100%" }, children: hasError ? /* @__PURE__ */ jsxs(Col, { span: 24, style: { height: "53%", minHeight: 400 }, children: [
95
230
  /* @__PURE__ */ jsx(
96
- LoaderInfoItem,
231
+ "div",
97
232
  {
98
- label: "resource path",
99
- value: /* @__PURE__ */ jsx(CodeOpener, { cwd, url: resource.path, loc: "", disabled: true })
233
+ style: {
234
+ padding: Size.BasePadding,
235
+ borderTop: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`,
236
+ borderBottom: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`
237
+ },
238
+ children: /* @__PURE__ */ jsx(
239
+ Title,
240
+ {
241
+ text: `the error stack of [${loader.loader}] ${loader.isPitch ? "pitch" : ""}`
242
+ }
243
+ )
100
244
  }
101
245
  ),
102
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "resource query", value: resource.queryRaw || "-" }),
103
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "duration", value: formatCosts(loader.costs), mark: true }),
104
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "loader name", value: loader.loader, code: true }),
105
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "loader index", value: `${loader.loaderIndex}` }),
106
- /* @__PURE__ */ jsx(LoaderInfoItem, { label: "loader path", value: /* @__PURE__ */ jsx(CodeOpener, { cwd, url: loader.path, loc: "", disabled: true }) }),
246
+ /* @__PURE__ */ jsx("div", { style: { height: "90%" }, children: /* @__PURE__ */ jsx(
247
+ Editor,
248
+ {
249
+ theme: "vs-dark",
250
+ options: {
251
+ readOnly: true,
252
+ domReadOnly: true,
253
+ fontSize: 14,
254
+ minimap: { enabled: false },
255
+ lineNumbers: "off"
256
+ },
257
+ value: loader.errors[0].message,
258
+ language: "javascript"
259
+ }
260
+ ) })
261
+ ] }) : /* @__PURE__ */ jsxs(Col, { span: 24, style: { height: "53%", minHeight: 400 }, children: [
107
262
  /* @__PURE__ */ jsx(
108
- LoaderInfoItem,
263
+ "div",
109
264
  {
110
- label: "options",
111
- value: JSON.stringify(loader.options || "-"),
112
- copyable: true,
113
- ellipsis: {
114
- rows: 2,
115
- expandable: true,
116
- symbol: "more"
117
- }
265
+ style: {
266
+ padding: Size.BasePadding,
267
+ borderTop: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`,
268
+ borderBottom: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`
269
+ },
270
+ children: /* @__PURE__ */ jsx(
271
+ Title,
272
+ {
273
+ text: `the result of [${loader.loader}] ${loader.isPitch ? "pitch" : ""}`
274
+ }
275
+ )
118
276
  }
119
- )
120
- ] })
121
- ]
122
- }
123
- ) }),
124
- hasError ? /* @__PURE__ */ jsxs(Col, { span: 24, style: { height: "53%", minHeight: 400 }, children: [
125
- /* @__PURE__ */ jsx(
126
- "div",
127
- {
128
- style: {
129
- padding: Size.BasePadding,
130
- borderTop: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`,
131
- borderBottom: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`
132
- },
133
- children: /* @__PURE__ */ jsx(Title, { text: `the error stack of [${loader.loader}] ${loader.isPitch ? "pitch" : ""}` })
134
- }
135
- ),
136
- /* @__PURE__ */ jsx("div", { style: { height: "90%" }, children: /* @__PURE__ */ jsx(
137
- Editor,
138
- {
139
- theme: "vs-dark",
140
- options: {
141
- readOnly: true,
142
- domReadOnly: true,
143
- fontSize: 14,
144
- minimap: { enabled: false },
145
- lineNumbers: "off"
146
- },
147
- value: loader.errors[0].message,
148
- language: "javascript"
149
- }
150
- ) })
151
- ] }) : /* @__PURE__ */ jsxs(Col, { span: 24, style: { height: "53%", minHeight: 400 }, children: [
152
- /* @__PURE__ */ jsx(
153
- "div",
154
- {
155
- style: {
156
- padding: Size.BasePadding,
157
- borderTop: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`,
158
- borderBottom: `1px solid ${isLight ? "#f0f0f0" : "rgba(253, 253, 253, 0.12)"}`
159
- },
160
- children: /* @__PURE__ */ jsx(Title, { text: `the result of [${loader.loader}] ${loader.isPitch ? "pitch" : ""}` })
161
- }
162
- ),
163
- loader.isPitch ? loader.result ? /* @__PURE__ */ jsx("div", { style: { height: "90%" }, children: /* @__PURE__ */ jsx(
164
- Editor,
165
- {
166
- theme: "vs-dark",
167
- options: {
168
- readOnly: true,
169
- domReadOnly: true,
170
- fontSize: 14,
171
- formatOnType: true,
172
- formatOnPaste: true
173
- },
174
- value: loader.result,
175
- language: getModifiedLanguage(resource.path)
277
+ ),
278
+ loader.isPitch ? loader.result ? /* @__PURE__ */ jsx("div", { style: { height: "90%" }, children: /* @__PURE__ */ jsx(
279
+ Editor,
280
+ {
281
+ theme: "vs-dark",
282
+ options: {
283
+ readOnly: true,
284
+ domReadOnly: true,
285
+ fontSize: 14,
286
+ formatOnType: true,
287
+ formatOnPaste: true
288
+ },
289
+ value: loader.result,
290
+ language: getModifiedLanguage(resource.path)
291
+ }
292
+ ) }) : /* @__PURE__ */ jsx(
293
+ Empty,
294
+ {
295
+ description: "No loader result. If you use the Brief Mode, there will not have loader results."
296
+ }
297
+ ) : /* @__PURE__ */ jsxs("div", { style: { minHeight: "700px" }, children: [
298
+ /* @__PURE__ */ jsxs(Row, { children: [
299
+ /* @__PURE__ */ jsx(
300
+ Col,
301
+ {
302
+ span: 12,
303
+ style: {
304
+ padding: `${Size.BasePadding / 2}px ${Size.BasePadding}px`
305
+ },
306
+ children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: "Input" })
307
+ }
308
+ ),
309
+ /* @__PURE__ */ jsx(
310
+ Col,
311
+ {
312
+ span: 12,
313
+ style: {
314
+ padding: `${Size.BasePadding / 2}px ${Size.BasePadding}px`
315
+ },
316
+ children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: "Output" })
317
+ }
318
+ )
319
+ ] }),
320
+ /* @__PURE__ */ jsx("div", { style: { height: "40rem" }, children: !loader.result && !before ? /* @__PURE__ */ jsx(
321
+ Empty,
322
+ {
323
+ description: "No loader result. If you use the Brief Mode, there will not have loader results."
324
+ }
325
+ ) : /* @__PURE__ */ jsx(
326
+ DiffViewer,
327
+ {
328
+ filepath: resource.path,
329
+ before,
330
+ after: loader.result || ""
331
+ }
332
+ ) })
333
+ ] })
334
+ ] }) })
176
335
  }
177
- ) }) : /* @__PURE__ */ jsx(Empty, {}) : /* @__PURE__ */ jsxs("div", { style: { height: "90%" }, children: [
178
- /* @__PURE__ */ jsxs(Row, { children: [
179
- /* @__PURE__ */ jsx(Col, { span: 12, style: { padding: `${Size.BasePadding / 2}px ${Size.BasePadding}px` }, children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: "Input" }) }),
180
- /* @__PURE__ */ jsx(
181
- Col,
182
- {
183
- span: 12,
184
- style: {
185
- padding: `${Size.BasePadding / 2}px ${Size.BasePadding}px`
186
- },
187
- children: /* @__PURE__ */ jsx(Typography.Text, { strong: true, children: "Output" })
188
- }
189
- )
190
- ] }),
191
- /* @__PURE__ */ jsx("div", { style: { height: "86%" }, children: /* @__PURE__ */ jsx(DiffViewer, { filepath: resource.path, before, after: loader.result || "" }) })
192
- ] })
193
- ] })
194
- ] })
336
+ ],
337
+ onChange
338
+ }
339
+ ) })
195
340
  ] });
196
341
  };
197
342
  export {
@@ -1,5 +1,5 @@
1
1
  import { jsx } from "react/jsx-runtime";
2
- import { SDK } from "@rsdoctor/types";
2
+ import { Constants, SDK } from "@rsdoctor/types";
3
3
  import { Skeleton, Spin } from "antd";
4
4
  import { useCallback, useEffect, useState } from "react";
5
5
  import { includes, isEqual, isNil, values } from "lodash-es";
@@ -16,15 +16,20 @@ const ServerAPIProvider = (props) => {
16
16
  showSkeleton = true,
17
17
  fallbackComponent
18
18
  } = props;
19
- let promise = manifestLoader();
19
+ let promise;
20
20
  const [manifest, setManifest] = useState();
21
21
  const [state, setState] = useState(ComponentState.Pending);
22
22
  const [res, setRes] = useState({});
23
23
  const { loader } = useDataLoader(manifest);
24
24
  function init(loader2) {
25
- ensureManifest(promise).then(() => {
25
+ if (window[Constants.WINDOW_RSDOCTOR_TAG]) {
26
26
  executeLoader(loader2);
27
- });
27
+ } else {
28
+ promise = manifestLoader();
29
+ ensureManifest(promise).then(() => {
30
+ executeLoader(loader2);
31
+ });
32
+ }
28
33
  }
29
34
  const update = useCallback(
30
35
  ({ req, res: response }) => {
@@ -111,13 +116,22 @@ function withServerAPI({
111
116
  const { body = bodyInRoot, ...rest } = props;
112
117
  return (
113
118
  // @ts-ignore
114
- /* @__PURE__ */ jsx(ServerAPIProvider, { api, body, showSkeleton, fallbackComponent, children: (res) => {
115
- const _props = {
116
- ...rest,
117
- [responsePropName]: res
118
- };
119
- return /* @__PURE__ */ jsx(Component, { ..._props });
120
- } })
119
+ /* @__PURE__ */ jsx(
120
+ ServerAPIProvider,
121
+ {
122
+ api,
123
+ body,
124
+ showSkeleton,
125
+ fallbackComponent,
126
+ children: (res) => {
127
+ const _props = {
128
+ ...rest,
129
+ [responsePropName]: res
130
+ };
131
+ return /* @__PURE__ */ jsx(Component, { ..._props });
132
+ }
133
+ }
134
+ )
121
135
  );
122
136
  };
123
137
  }
@@ -50,6 +50,14 @@ const tagStyle = {
50
50
  margin: "none",
51
51
  marginInlineEnd: 0
52
52
  };
53
+ const EmptyCodeItem = () => /* @__PURE__ */ jsx(
54
+ Empty,
55
+ {
56
+ description: `Do not have the module code.
57
+ (1) If you use the brief mode, there will not have any codes to show.
58
+ (2) If you use lite mode, there will not have source codes.`
59
+ }
60
+ );
53
61
  const ModuleCodeViewer = ({
54
62
  data
55
63
  }) => {
@@ -83,7 +91,7 @@ const ModuleCodeViewer = ({
83
91
  api: SDK.ServerAPI.API.GetModuleCodeByModuleId,
84
92
  body: { moduleId: data.id },
85
93
  children: (source) => {
86
- return /* @__PURE__ */ jsx(Fragment, { children: !source["source"] && !source["parsedSource"] && !source["transformed"] ? /* @__PURE__ */ jsx(Empty, { description: "No Code. Rspack builder not support code yet. And if you upload the stats.json to analysis, it's also no code to show." }) : /* @__PURE__ */ jsx(
94
+ return /* @__PURE__ */ jsx(Fragment, { children: !source["source"] && !source["parsedSource"] && !source["transformed"] ? /* @__PURE__ */ jsx(EmptyCodeItem, {}) : /* @__PURE__ */ jsx(
87
95
  Card,
88
96
  {
89
97
  className: "code-size-card",
@@ -137,7 +145,7 @@ const ModuleCodeViewer = ({
137
145
  children: /* @__PURE__ */ jsx("a", { href: "#", children: "Explain" })
138
146
  }
139
147
  ),
140
- children: /* @__PURE__ */ jsx(
148
+ children: source["parsedSource"] || source["source"] || source["transformed"] ? /* @__PURE__ */ jsx(
141
149
  Editor,
142
150
  {
143
151
  theme: "vs-dark",
@@ -154,7 +162,7 @@ const ModuleCodeViewer = ({
154
162
  }
155
163
  }
156
164
  }
157
- )
165
+ ) : /* @__PURE__ */ jsx(EmptyCodeItem, {})
158
166
  }
159
167
  ) });
160
168
  }
@@ -125,7 +125,8 @@ const WebpackModulesOverallBase = ({ errors, cwd, summary, entryPoints }) => {
125
125
  {
126
126
  path,
127
127
  content,
128
- editorConfig: { readOnly: false, domReadOnly: false }
128
+ editorConfig: { readOnly: false, domReadOnly: false },
129
+ emptyReason: "Do not have the codes of assets. If you use the lite or brief mode, there will have codes."
129
130
  }
130
131
  )
131
132
  ]
@@ -119,6 +119,7 @@ const Component = ({
119
119
  children: /* @__PURE__ */ jsx(
120
120
  FileTree,
121
121
  {
122
+ style: { height: "80%" },
122
123
  className: "tree-shaking-files",
123
124
  selectedKeys: selectedModule ? [selectedModule.path] : [],
124
125
  defaultExpandedKeys: getTreeFilesDefaultExpandedKeys(files),
@@ -8,7 +8,7 @@ const Page = () => {
8
8
  {
9
9
  title: "Webpack Loader Analysis",
10
10
  extra: /* @__PURE__ */ jsx(WebpackConfigurationViewer, { defaultKeys: ["module", "resolve"] }),
11
- bodyStyle: { paddingTop: 0 },
11
+ bodyStyle: { paddingTop: 0, height: 800 },
12
12
  children: /* @__PURE__ */ jsx(LoaderAnalysis, {})
13
13
  }
14
14
  );
@@ -0,0 +1,11 @@
1
+ import { Manifest, SDK } from '@rsdoctor/types';
2
+ import { BaseDataLoader } from './base';
3
+ export declare class BriefDataLoader extends BaseDataLoader {
4
+ isLocal(): boolean;
5
+ loadData<T extends Manifest.RsdoctorManifestMappingKeys>(key: T): Promise<Manifest.InferManifestDataValue<T>>;
6
+ getData(scope: keyof Manifest.RsdoctorManifestData): any;
7
+ loadAPI<T extends SDK.ServerAPI.API, B extends SDK.ServerAPI.InferRequestBodyType<T> = SDK.ServerAPI.InferRequestBodyType<T>, R extends SDK.ServerAPI.InferResponseType<T> = SDK.ServerAPI.InferResponseType<T>>(...args: B extends void ? [api: T] : [api: T, body: B]): Promise<R>;
8
+ dispose(): void;
9
+ onDataUpdate(): void;
10
+ removeOnDataUpdate(): void;
11
+ }
@@ -0,0 +1,42 @@
1
+ import { Algorithm } from "@rsdoctor/utils/common";
2
+ import { BaseDataLoader } from "./base";
3
+ import { Constants } from "@rsdoctor/types";
4
+ class BriefDataLoader extends BaseDataLoader {
5
+ isLocal() {
6
+ return false;
7
+ }
8
+ async loadData(key) {
9
+ console.log(`[loadData]-[key]: ${key}`);
10
+ const [scope] = this.getKeys(key);
11
+ console.log(`[loadData]-[scope]: ${scope}`);
12
+ const data = this.getData(scope);
13
+ console.log(`[loadData]-[data]: ${data}`);
14
+ if (!data)
15
+ return;
16
+ let res = data;
17
+ if (!this.shardingDataMap.has(scope)) {
18
+ const scopeData = typeof res === "object" ? res : JSON.parse(Algorithm.decompressText(res));
19
+ console.log(`[loadData]-[scopeData]: ${scopeData}`);
20
+ this.shardingDataMap.set(scope, scopeData);
21
+ }
22
+ res = await this.shardingDataMap.get(scope);
23
+ return res;
24
+ }
25
+ getData(scope) {
26
+ console.log(`[getData]-[scope]: ${scope}`);
27
+ return window[Constants.WINDOW_RSDOCTOR_TAG][scope];
28
+ }
29
+ async loadAPI(...args) {
30
+ return this.loader.loadAPI(...args);
31
+ }
32
+ dispose() {
33
+ super.dispose();
34
+ }
35
+ onDataUpdate() {
36
+ }
37
+ removeOnDataUpdate() {
38
+ }
39
+ }
40
+ export {
41
+ BriefDataLoader
42
+ };
@@ -1,19 +1,23 @@
1
+ import { Constants } from "@rsdoctor/types";
1
2
  import { useEffect, useState } from "react";
2
3
  import { LocalServerDataLoader } from "./local";
3
4
  import { RemoteDataLoader } from "./remote";
4
5
  import { getAPILoaderModeFromStorage } from "../storage";
5
6
  import { APILoaderMode4Dev } from "../../constants";
7
+ import { BriefDataLoader } from "./brief";
6
8
  const loaderTask = /* @__PURE__ */ new WeakMap();
7
9
  async function createDataLoader(manifest) {
8
10
  try {
9
11
  if (process.env.NODE_ENV === "development") {
10
12
  const mode = getAPILoaderModeFromStorage();
13
+ console.log(`[development]-${mode}`);
11
14
  if (mode === APILoaderMode4Dev.Local)
12
15
  return new LocalServerDataLoader(manifest);
13
16
  if (mode === APILoaderMode4Dev.Remote)
14
17
  return new RemoteDataLoader(manifest);
15
18
  }
16
19
  if (manifest.__LOCAL__SERVER__) {
20
+ console.log(`[LocalServerDataLoader]`);
17
21
  return new LocalServerDataLoader(manifest);
18
22
  }
19
23
  } catch (error) {
@@ -23,6 +27,13 @@ async function createDataLoader(manifest) {
23
27
  }
24
28
  function useDataLoader(manifest) {
25
29
  const [loader, setLoader] = useState(void 0);
30
+ useEffect(() => {
31
+ if (window[Constants.WINDOW_RSDOCTOR_TAG]) {
32
+ console.log("[brief mode]");
33
+ const loader2 = new BriefDataLoader({ data: [] });
34
+ setLoader(loader2);
35
+ }
36
+ }, []);
26
37
  useEffect(() => {
27
38
  if (!manifest)
28
39
  return;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@rsdoctor/components",
3
- "version": "0.3.12-alpha.0",
3
+ "version": "0.4.1",
4
4
  "main": "./dist/index.js",
5
5
  "license": "MIT",
6
6
  "module": "dist/index.js",
@@ -48,14 +48,14 @@
48
48
  "@monaco-editor/react": "4.6.0",
49
49
  "@types/lodash-es": "4.17.12",
50
50
  "@types/node": "^16",
51
- "@types/path-browserify": "1.0.2",
52
- "@types/react": "^18",
51
+ "@types/path-browserify": "1.0.3",
52
+ "@types/react": "^18.3.5",
53
53
  "@types/react-highlight-words": "^0.20.0",
54
54
  "@types/url-parse": "1.4.11",
55
55
  "ansi-to-react": "6.1.6",
56
56
  "antd": "5.15.3",
57
57
  "axios": "^1.7.2",
58
- "dayjs": "1.11.12",
58
+ "dayjs": "1.11.13",
59
59
  "echarts": "^5.5.1",
60
60
  "echarts-for-react": "^3.0.2",
61
61
  "i18next": "22.0.4",
@@ -72,12 +72,12 @@
72
72
  "react-markdown": "^9.0.1",
73
73
  "react-router-dom": "6.4.3",
74
74
  "socket.io-client": "4.6.1",
75
- "terser": "^5.31.3",
75
+ "terser": "^5.31.6",
76
76
  "typescript": "^5.2.2",
77
77
  "url-parse": "1.5.10",
78
- "@rsdoctor/graph": "0.3.12-alpha.0",
79
- "@rsdoctor/types": "0.3.12-alpha.0",
80
- "@rsdoctor/utils": "0.3.12-alpha.0"
78
+ "@rsdoctor/graph": "0.4.1",
79
+ "@rsdoctor/types": "0.4.1",
80
+ "@rsdoctor/utils": "0.4.1"
81
81
  },
82
82
  "publishConfig": {
83
83
  "access": "public",