Skip to content

Commit cb44702

Browse files
committed
Refactoring
1 parent 4616b3d commit cb44702

File tree

3 files changed

+87
-76
lines changed

3 files changed

+87
-76
lines changed

src/buildGraph.ts renamed to src/graph.ts

Lines changed: 41 additions & 75 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,19 @@ import { graphlib } from "dagre-d3";
22
import { v4 as uuidv4 } from "uuid";
33
import * as R from "ramda";
44
import { StepFunction, State, Operator, stringifyChoiceOperator } from "./stepFunction";
5+
import { getNodeOptions, getClusterOptions, getEdgeOptions, getMissingStyle } from "./graphStyles";
56

67
const makeGroupName = () => `Group_${uuidv4()}`;
78
const makeNodeName = () => `Node_${uuidv4()}`;
89

910
const createMissingNodes = (g: graphlib.Graph) => {
10-
const style = "fill: #ff0000;";
1111
const makeLabel = (edgePointer) => `${edgePointer} (Missing)`;
1212
g.edges().forEach((edge) => {
1313
if (!g.node(edge.v)) {
14-
g.setNode(edge.v, { label: makeLabel(edge.v), style });
14+
g.setNode(edge.v, { label: makeLabel(edge.v), style: getMissingStyle() });
1515
}
1616
if (!g.node(edge.w)) {
17-
g.setNode(edge.w, { label: makeLabel(edge.w), style });
17+
g.setNode(edge.w, { label: makeLabel(edge.w), style: getMissingStyle() });
1818
}
1919
});
2020
return g;
@@ -31,21 +31,6 @@ const roundNodes = (g: graphlib.Graph) => {
3131
return g;
3232
};
3333

34-
const stroke = "#999";
35-
const red = "#a80d35";
36-
const green = "#2BD62E";
37-
38-
const getNodeOptions = (state) => {
39-
switch (state.Type) {
40-
case "Fail":
41-
return { style: `stroke: ${red};` };
42-
case "Succeed":
43-
return { style: `stroke: ${green};` };
44-
default:
45-
return {};
46-
}
47-
};
48-
4934
const isTerminalState = (state: State) => {
5035
return (
5136
(state.End && state.Type !== "Parallel" && state.Type !== "Map") ||
@@ -56,6 +41,15 @@ const isTerminalState = (state: State) => {
5641

5742
const serializeGraph = R.compose(JSON.stringify, graphlib.json.write);
5843

44+
const makeCluster = (g: graphlib.Graph, state: State, parentClusterName: string) => {
45+
const clusterName = makeGroupName();
46+
g.setNode(clusterName, getClusterOptions(state));
47+
if (parentClusterName) {
48+
g.setParent(clusterName, parentClusterName);
49+
}
50+
return clusterName;
51+
};
52+
5953
export const buildGraph = (stepFunction: StepFunction) => {
6054
const g = new graphlib.Graph({ compound: true, multigraph: true }).setGraph({}).setDefaultEdgeLabel(() => ({}));
6155

@@ -65,12 +59,22 @@ export const buildGraph = (stepFunction: StepFunction) => {
6559
g.setNode(startNodeName, { label: "Start", shape: "circle", style: "fill: #fcba03;" });
6660
g.setNode(endNodeName, { label: "End", shape: "circle", style: "fill: #fcba03;" });
6761

68-
const traverse = (stepFunction: StepFunction, g: graphlib.Graph, groupName?: string) => {
62+
const traverse = (
63+
stepFunction: StepFunction,
64+
g: graphlib.Graph,
65+
parentClusterName?: string,
66+
fromState?: string,
67+
nextState?: string
68+
) => {
6969
const startAtName = stepFunction.StartAt;
70-
const isRootLevel = !groupName;
70+
const isRootLevel = !parentClusterName;
71+
72+
if (fromState) {
73+
g.setEdge(fromState, startAtName);
74+
}
7175

72-
if (groupName) {
73-
g.setParent(startAtName, groupName);
76+
if (parentClusterName) {
77+
g.setParent(startAtName, parentClusterName);
7478
}
7579

7680
const statesToAddToParent = new Set(Object.keys(stepFunction.States));
@@ -84,77 +88,39 @@ export const buildGraph = (stepFunction: StepFunction) => {
8488

8589
switch (state.Type) {
8690
case "Parallel": {
87-
const newGroupName = makeGroupName();
88-
g.setNode(newGroupName, {
89-
label: "Parallel",
90-
style: `stroke: ${stroke}; stroke-width: 2px; stroke-dasharray: 8, 4; rx: 5;`,
91-
clusterLabelPos: "top",
92-
});
93-
if (groupName) {
94-
g.setParent(newGroupName, groupName);
95-
}
96-
91+
const clusterName = makeCluster(g, state, parentClusterName);
9792
state.Branches.forEach((branch) => {
98-
g.setEdge(stateName, branch.StartAt);
99-
traverse(branch, g, newGroupName);
100-
101-
R.toPairs(branch.States)
102-
.filter(([branchStateName, branchState]) => isTerminalState(branchState))
103-
.forEach(([branchStateName, branchState]) => g.setEdge(branchStateName, state.Next || endNodeName));
93+
traverse(branch, g, clusterName, stateName, state.Next);
10494
});
10595
break;
10696
}
10797
case "Map": {
108-
const newGroupName = makeGroupName();
109-
g.setNode(newGroupName, {
110-
label: "Map",
111-
style: `stroke: ${stroke}; stroke-width: 2px; stroke-dasharray: 16, 4; rx: 5;`,
112-
clusterLabelPos: "top",
113-
});
114-
if (groupName) {
115-
g.setParent(newGroupName, groupName);
116-
}
117-
const branch = state.Iterator;
118-
g.setEdge(stateName, branch.StartAt);
119-
traverse(branch, g, newGroupName);
120-
R.toPairs(branch.States)
121-
.filter(([branchStateName, branchState]) => isTerminalState(branchState))
122-
.forEach(([branchStateName, branchState]) => g.setEdge(branchStateName, state.Next || endNodeName));
98+
const clusterName = makeCluster(g, state, parentClusterName);
99+
traverse(state.Iterator, g, clusterName, stateName, state.Next);
123100
break;
124101
}
125102
case "Choice": {
126103
if (state.Choices) {
127-
const newGroupName = makeGroupName();
128-
g.setNode(newGroupName, {
129-
label: "Choice",
130-
style: "fill: #d9dddc; rx: 5;",
131-
clusterLabelPos: "top",
132-
});
133-
134-
if (groupName) {
135-
g.setParent(newGroupName, groupName);
136-
}
137-
138-
const edgeOptions = { labelStyle: "font-style: italic;" };
104+
const clusterName = makeCluster(g, state, parentClusterName);
139105

140106
state.Choices.forEach((choice: Operator) => {
141107
const label = stringifyChoiceOperator(choice);
142-
g.setEdge(stateName, choice.Next, { label, ...edgeOptions });
143-
g.setParent(choice.Next, newGroupName);
108+
g.setEdge(stateName, choice.Next, { label, ...getEdgeOptions() });
109+
g.setParent(choice.Next, clusterName);
144110
statesToAddToParent.delete(choice.Next);
145111
});
146112
if (state.Default) {
147113
const label = "Default";
148-
g.setEdge(stateName, state.Default, { label, ...edgeOptions });
149-
g.setParent(state.Default, newGroupName);
114+
g.setEdge(stateName, state.Default, { label, ...getEdgeOptions() });
115+
g.setParent(state.Default, clusterName);
150116
statesToAddToParent.delete(state.Default);
151117
}
152118
}
153119
break;
154120
}
155121
default: {
156-
if (isTerminalState(state) && isRootLevel) {
157-
g.setEdge(stateName, endNodeName);
122+
if (isTerminalState(state)) {
123+
g.setEdge(stateName, nextState || endNodeName);
158124
}
159125
if (state.Next) {
160126
g.setEdge(stateName, state.Next);
@@ -165,19 +131,19 @@ export const buildGraph = (stepFunction: StepFunction) => {
165131
if (state.Catch) {
166132
state.Catch.forEach((catcher) => {
167133
const label = (catcher.ErrorEquals || []).join(" or ");
168-
g.setEdge(stateName, catcher.Next, { label, labelStyle: "font-style: italic;" });
134+
g.setEdge(stateName, catcher.Next, { label, ...getEdgeOptions() });
169135
});
170136
}
171137
if (state.Retry) {
172138
const conditionsLength = (state.Retry || []).length;
173139
const label = `(${conditionsLength} condition${conditionsLength > 1 ? "s" : ""})`;
174-
g.setEdge(stateName, stateName, { label, labelStyle: "font-style: italic;" });
140+
g.setEdge(stateName, stateName, { label, ...getEdgeOptions() });
175141
}
176142
});
177143

178-
if (groupName) {
144+
if (parentClusterName) {
179145
[...statesToAddToParent].forEach((stateName) => {
180-
g.setParent(stateName, groupName);
146+
g.setParent(stateName, parentClusterName);
181147
});
182148
}
183149

src/graphStyles.ts

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import { State } from "./stepFunction";
2+
3+
const stroke = "#999";
4+
const red = "#a80d35";
5+
const green = "#2BD62E";
6+
7+
export const getNodeOptions = (state) => {
8+
switch (state.Type) {
9+
case "Fail":
10+
return { style: `stroke: ${red};` };
11+
case "Succeed":
12+
return { style: `stroke: ${green};` };
13+
default:
14+
return {};
15+
}
16+
};
17+
18+
export const getClusterOptions = (state: State) => {
19+
switch (state.Type) {
20+
case "Parallel":
21+
return {
22+
label: "Parallel",
23+
style: `stroke: ${stroke}; stroke-width: 2px; stroke-dasharray: 8, 4; rx: 5;`,
24+
clusterLabelPos: "top",
25+
};
26+
case "Map":
27+
return {
28+
label: "Map",
29+
style: `stroke: ${stroke}; stroke-width: 2px; stroke-dasharray: 16, 4; rx: 5;`,
30+
clusterLabelPos: "top",
31+
};
32+
case "Choice":
33+
return {
34+
label: "Choice",
35+
style: "fill: #d9dddc; rx: 5;",
36+
clusterLabelPos: "top",
37+
};
38+
default:
39+
return {};
40+
}
41+
};
42+
43+
export const getEdgeOptions = () => ({ labelStyle: "font-style: italic;" });
44+
45+
export const getMissingStyle = () => "fill: #ff0000;"

src/postData.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import * as vscode from "vscode";
22
import * as _ from "lodash";
33

44
import { parse, getSourceMap } from "./parse/parse";
5-
import { buildGraph } from "./buildGraph";
5+
import { buildGraph } from "./graph";
66
import { getStates } from "./stepFunction";
77

88
export const postData = async (panel: vscode.WebviewPanel, uri: vscode.Uri, fileName: string) => {

0 commit comments

Comments
 (0)