sfn-diagram-react 0.1.0
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.
- package/README.md +78 -0
- package/dist/index.cjs +59 -0
- package/dist/index.d.cts +33 -0
- package/dist/index.d.ts +33 -0
- package/dist/index.js +58 -0
- package/package.json +79 -0
package/README.md
ADDED
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
# sfn-diagram-react
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/sfn-diagram-react)
|
|
4
|
+
[](https://github.com/yusufaf/sfn-diagram/blob/main/LICENSE)
|
|
5
|
+
|
|
6
|
+
React component for rendering [AWS Step Functions](https://aws.amazon.com/step-functions/) ASL definitions as diagrams, built on top of [`sfn-diagram`](https://www.npmjs.com/package/sfn-diagram).
|
|
7
|
+
|
|
8
|
+
The core is DOM-free, so `<SfnDiagram>` renders the SVG (or Mermaid code) with no browser-only dependencies.
|
|
9
|
+
|
|
10
|
+
## Installation
|
|
11
|
+
|
|
12
|
+
```bash
|
|
13
|
+
npm install sfn-diagram-react sfn-diagram
|
|
14
|
+
# or
|
|
15
|
+
pnpm add sfn-diagram-react sfn-diagram
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
`react` and `sfn-diagram` are peer dependencies.
|
|
19
|
+
|
|
20
|
+
## Usage
|
|
21
|
+
|
|
22
|
+
```tsx
|
|
23
|
+
import { SfnDiagram } from 'sfn-diagram-react'
|
|
24
|
+
|
|
25
|
+
const definition = {
|
|
26
|
+
StartAt: 'Hello',
|
|
27
|
+
States: {
|
|
28
|
+
Hello: { Type: 'Pass', Next: 'World' },
|
|
29
|
+
World: { Type: 'Succeed' },
|
|
30
|
+
},
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export function Diagram() {
|
|
34
|
+
return (
|
|
35
|
+
<SfnDiagram
|
|
36
|
+
definition={definition}
|
|
37
|
+
layout="TB"
|
|
38
|
+
theme="light"
|
|
39
|
+
onError={(error) => console.error(error)}
|
|
40
|
+
/>
|
|
41
|
+
)
|
|
42
|
+
}
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
`definition` accepts either an ASL object or a JSON string.
|
|
46
|
+
|
|
47
|
+
### Execution overlay
|
|
48
|
+
|
|
49
|
+
Pass an execution's `history` to overlay a real run onto the diagram: states are
|
|
50
|
+
coloured by outcome (succeeded / failed / caught / not-reached), the taken path is
|
|
51
|
+
emphasized, and per-state duration and retry counts are annotated.
|
|
52
|
+
|
|
53
|
+
```tsx
|
|
54
|
+
// historyJson: output of `aws stepfunctions get-execution-history`, as a JSON string
|
|
55
|
+
<SfnDiagram definition={definition} history={historyJson} />
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
`history` accepts a `GetExecutionHistory` events array, the raw command output, or a
|
|
59
|
+
JSON string of either. In the browser, pass the JSON string.
|
|
60
|
+
|
|
61
|
+
## Props
|
|
62
|
+
|
|
63
|
+
| Prop | Type | Default | Description |
|
|
64
|
+
| --- | --- | --- | --- |
|
|
65
|
+
| `definition` | `object \| string` | — (required) | ASL definition as an object or JSON string |
|
|
66
|
+
| `format` | `'svg' \| 'mermaid'` | `'svg'` | Render an SVG diagram or emit Mermaid code |
|
|
67
|
+
| `history` | `HistoryEvent[] \| GetExecutionHistoryCommandOutput \| string` | — | Execution history; when set, renders an execution overlay |
|
|
68
|
+
| `layout` | `'TB' \| 'LR' \| 'RL' \| 'BT'` | `'TB'` | Graph layout direction |
|
|
69
|
+
| `theme` | `'light' \| 'dark' \| CustomTheme` | `'light'` | Diagram theme |
|
|
70
|
+
| `onError` | `(error: Error) => void` | — | Called when the definition fails to parse/render |
|
|
71
|
+
| `className` | `string` | — | Applied to the wrapper element |
|
|
72
|
+
| `style` | `React.CSSProperties` | — | Applied to the wrapper element |
|
|
73
|
+
|
|
74
|
+
When the definition is invalid the component renders `null` and (if provided) calls `onError`.
|
|
75
|
+
|
|
76
|
+
## License
|
|
77
|
+
|
|
78
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
+
let react = require("react");
|
|
3
|
+
let sfn_diagram = require("sfn-diagram");
|
|
4
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
5
|
+
//#region src/SfnDiagram.tsx
|
|
6
|
+
function SfnDiagram({ className, definition, format = "svg", history, layout = "TB", onError, style, theme = "light" }) {
|
|
7
|
+
const asl = (0, react.useMemo)(() => typeof definition === "string" ? definition : JSON.stringify(definition), [definition]);
|
|
8
|
+
const result = (0, react.useMemo)(() => {
|
|
9
|
+
try {
|
|
10
|
+
if (format === "mermaid") return {
|
|
11
|
+
type: "mermaid",
|
|
12
|
+
code: (history ? (0, sfn_diagram.generateMermaidExecution)({
|
|
13
|
+
aslDefinition: asl,
|
|
14
|
+
history
|
|
15
|
+
}) : (0, sfn_diagram.generateMermaid)({ aslDefinition: asl })).code
|
|
16
|
+
};
|
|
17
|
+
return {
|
|
18
|
+
type: "svg",
|
|
19
|
+
svg: (history ? (0, sfn_diagram.generateExecution)({
|
|
20
|
+
aslDefinition: asl,
|
|
21
|
+
history,
|
|
22
|
+
layout,
|
|
23
|
+
theme
|
|
24
|
+
}) : (0, sfn_diagram.generateSvg)({
|
|
25
|
+
aslDefinition: asl,
|
|
26
|
+
layout,
|
|
27
|
+
theme
|
|
28
|
+
})).svg
|
|
29
|
+
};
|
|
30
|
+
} catch (err) {
|
|
31
|
+
return {
|
|
32
|
+
type: "error",
|
|
33
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
34
|
+
};
|
|
35
|
+
}
|
|
36
|
+
}, [
|
|
37
|
+
asl,
|
|
38
|
+
format,
|
|
39
|
+
history,
|
|
40
|
+
layout,
|
|
41
|
+
theme
|
|
42
|
+
]);
|
|
43
|
+
if (result.type === "error") {
|
|
44
|
+
onError?.(result.error);
|
|
45
|
+
return null;
|
|
46
|
+
}
|
|
47
|
+
if (result.type === "mermaid") return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("pre", {
|
|
48
|
+
className,
|
|
49
|
+
style,
|
|
50
|
+
children: result.code
|
|
51
|
+
});
|
|
52
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
53
|
+
className,
|
|
54
|
+
dangerouslySetInnerHTML: { __html: result.svg },
|
|
55
|
+
style
|
|
56
|
+
});
|
|
57
|
+
}
|
|
58
|
+
//#endregion
|
|
59
|
+
exports.SfnDiagram = SfnDiagram;
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as _$react from "react";
|
|
2
|
+
import { ExecutionHistoryInput, LayoutDirection, ThemeOption } from "sfn-diagram";
|
|
3
|
+
|
|
4
|
+
//#region src/SfnDiagram.d.ts
|
|
5
|
+
interface SfnDiagramProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
definition: object | string;
|
|
8
|
+
format?: 'mermaid' | 'svg';
|
|
9
|
+
/**
|
|
10
|
+
* Optional execution history. When provided, the diagram is rendered as an
|
|
11
|
+
* execution overlay: states are coloured by outcome, the taken path is
|
|
12
|
+
* emphasized, and per-state duration / retry counts are annotated.
|
|
13
|
+
* Accepts a GetExecutionHistory events array, the raw command output, or a
|
|
14
|
+
* JSON string of either.
|
|
15
|
+
*/
|
|
16
|
+
history?: ExecutionHistoryInput;
|
|
17
|
+
layout?: LayoutDirection;
|
|
18
|
+
onError?: (error: Error) => void;
|
|
19
|
+
style?: React.CSSProperties;
|
|
20
|
+
theme?: ThemeOption;
|
|
21
|
+
}
|
|
22
|
+
declare function SfnDiagram({
|
|
23
|
+
className,
|
|
24
|
+
definition,
|
|
25
|
+
format,
|
|
26
|
+
history,
|
|
27
|
+
layout,
|
|
28
|
+
onError,
|
|
29
|
+
style,
|
|
30
|
+
theme
|
|
31
|
+
}: SfnDiagramProps): _$react.JSX.Element | null;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { SfnDiagram, type SfnDiagramProps };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import * as _$react from "react";
|
|
2
|
+
import { ExecutionHistoryInput, LayoutDirection, ThemeOption } from "sfn-diagram";
|
|
3
|
+
|
|
4
|
+
//#region src/SfnDiagram.d.ts
|
|
5
|
+
interface SfnDiagramProps {
|
|
6
|
+
className?: string;
|
|
7
|
+
definition: object | string;
|
|
8
|
+
format?: 'mermaid' | 'svg';
|
|
9
|
+
/**
|
|
10
|
+
* Optional execution history. When provided, the diagram is rendered as an
|
|
11
|
+
* execution overlay: states are coloured by outcome, the taken path is
|
|
12
|
+
* emphasized, and per-state duration / retry counts are annotated.
|
|
13
|
+
* Accepts a GetExecutionHistory events array, the raw command output, or a
|
|
14
|
+
* JSON string of either.
|
|
15
|
+
*/
|
|
16
|
+
history?: ExecutionHistoryInput;
|
|
17
|
+
layout?: LayoutDirection;
|
|
18
|
+
onError?: (error: Error) => void;
|
|
19
|
+
style?: React.CSSProperties;
|
|
20
|
+
theme?: ThemeOption;
|
|
21
|
+
}
|
|
22
|
+
declare function SfnDiagram({
|
|
23
|
+
className,
|
|
24
|
+
definition,
|
|
25
|
+
format,
|
|
26
|
+
history,
|
|
27
|
+
layout,
|
|
28
|
+
onError,
|
|
29
|
+
style,
|
|
30
|
+
theme
|
|
31
|
+
}: SfnDiagramProps): _$react.JSX.Element | null;
|
|
32
|
+
//#endregion
|
|
33
|
+
export { SfnDiagram, type SfnDiagramProps };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import { useMemo } from "react";
|
|
2
|
+
import { generateExecution, generateMermaid, generateMermaidExecution, generateSvg } from "sfn-diagram";
|
|
3
|
+
import { jsx } from "react/jsx-runtime";
|
|
4
|
+
//#region src/SfnDiagram.tsx
|
|
5
|
+
function SfnDiagram({ className, definition, format = "svg", history, layout = "TB", onError, style, theme = "light" }) {
|
|
6
|
+
const asl = useMemo(() => typeof definition === "string" ? definition : JSON.stringify(definition), [definition]);
|
|
7
|
+
const result = useMemo(() => {
|
|
8
|
+
try {
|
|
9
|
+
if (format === "mermaid") return {
|
|
10
|
+
type: "mermaid",
|
|
11
|
+
code: (history ? generateMermaidExecution({
|
|
12
|
+
aslDefinition: asl,
|
|
13
|
+
history
|
|
14
|
+
}) : generateMermaid({ aslDefinition: asl })).code
|
|
15
|
+
};
|
|
16
|
+
return {
|
|
17
|
+
type: "svg",
|
|
18
|
+
svg: (history ? generateExecution({
|
|
19
|
+
aslDefinition: asl,
|
|
20
|
+
history,
|
|
21
|
+
layout,
|
|
22
|
+
theme
|
|
23
|
+
}) : generateSvg({
|
|
24
|
+
aslDefinition: asl,
|
|
25
|
+
layout,
|
|
26
|
+
theme
|
|
27
|
+
})).svg
|
|
28
|
+
};
|
|
29
|
+
} catch (err) {
|
|
30
|
+
return {
|
|
31
|
+
type: "error",
|
|
32
|
+
error: err instanceof Error ? err : new Error(String(err))
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
}, [
|
|
36
|
+
asl,
|
|
37
|
+
format,
|
|
38
|
+
history,
|
|
39
|
+
layout,
|
|
40
|
+
theme
|
|
41
|
+
]);
|
|
42
|
+
if (result.type === "error") {
|
|
43
|
+
onError?.(result.error);
|
|
44
|
+
return null;
|
|
45
|
+
}
|
|
46
|
+
if (result.type === "mermaid") return /* @__PURE__ */ jsx("pre", {
|
|
47
|
+
className,
|
|
48
|
+
style,
|
|
49
|
+
children: result.code
|
|
50
|
+
});
|
|
51
|
+
return /* @__PURE__ */ jsx("div", {
|
|
52
|
+
className,
|
|
53
|
+
dangerouslySetInnerHTML: { __html: result.svg },
|
|
54
|
+
style
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//#endregion
|
|
58
|
+
export { SfnDiagram };
|
package/package.json
ADDED
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "sfn-diagram-react",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "React component for AWS Step Functions ASL diagrams",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"sideEffects": false,
|
|
7
|
+
"main": "./dist/index.cjs",
|
|
8
|
+
"module": "./dist/index.js",
|
|
9
|
+
"types": "./dist/index.d.ts",
|
|
10
|
+
"exports": {
|
|
11
|
+
".": {
|
|
12
|
+
"import": {
|
|
13
|
+
"types": "./dist/index.d.ts",
|
|
14
|
+
"default": "./dist/index.js"
|
|
15
|
+
},
|
|
16
|
+
"require": {
|
|
17
|
+
"types": "./dist/index.d.cts",
|
|
18
|
+
"default": "./dist/index.cjs"
|
|
19
|
+
}
|
|
20
|
+
}
|
|
21
|
+
},
|
|
22
|
+
"files": ["dist"],
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=20"
|
|
25
|
+
},
|
|
26
|
+
"scripts": {
|
|
27
|
+
"build": "tsdown",
|
|
28
|
+
"dev": "tsdown --watch",
|
|
29
|
+
"test": "vitest run",
|
|
30
|
+
"typecheck": "tsc --noEmit",
|
|
31
|
+
"lint": "eslint .",
|
|
32
|
+
"prepublishOnly": "pnpm run build && pnpm run validate",
|
|
33
|
+
"validate": "pnpm run validate:publint && pnpm run validate:types",
|
|
34
|
+
"validate:publint": "publint",
|
|
35
|
+
"validate:types": "attw --pack ."
|
|
36
|
+
},
|
|
37
|
+
"keywords": [
|
|
38
|
+
"aws",
|
|
39
|
+
"step-functions",
|
|
40
|
+
"react",
|
|
41
|
+
"diagram",
|
|
42
|
+
"asl",
|
|
43
|
+
"state-machine",
|
|
44
|
+
"visualization",
|
|
45
|
+
"svg",
|
|
46
|
+
"mermaid"
|
|
47
|
+
],
|
|
48
|
+
"author": "Yusuf Afzal",
|
|
49
|
+
"license": "MIT",
|
|
50
|
+
"repository": {
|
|
51
|
+
"type": "git",
|
|
52
|
+
"url": "git+https://github.com/yusufaf/sfn-diagram.git",
|
|
53
|
+
"directory": "packages/sfn-diagram-react"
|
|
54
|
+
},
|
|
55
|
+
"bugs": {
|
|
56
|
+
"url": "https://github.com/yusufaf/sfn-diagram/issues"
|
|
57
|
+
},
|
|
58
|
+
"homepage": "https://github.com/yusufaf/sfn-diagram/tree/main/packages/sfn-diagram-react#readme",
|
|
59
|
+
"peerDependencies": {
|
|
60
|
+
"react": "^18.0.0 || ^19.0.0",
|
|
61
|
+
"sfn-diagram": "^1.1.1"
|
|
62
|
+
},
|
|
63
|
+
"devDependencies": {
|
|
64
|
+
"@arethetypeswrong/cli": "^0.18.2",
|
|
65
|
+
"@testing-library/jest-dom": "^6.6.0",
|
|
66
|
+
"@testing-library/react": "^16.0.0",
|
|
67
|
+
"@types/react": "^18.3.0",
|
|
68
|
+
"@types/react-dom": "^18.3.0",
|
|
69
|
+
"jsdom": "^26.0.0",
|
|
70
|
+
"publint": "^0.3.16",
|
|
71
|
+
"react": "^18.3.0",
|
|
72
|
+
"react-dom": "^18.3.0",
|
|
73
|
+
"sfn-diagram": "workspace:*",
|
|
74
|
+
"tsdown": "^0.21.7",
|
|
75
|
+
"typescript": "^5.9.2",
|
|
76
|
+
"vite": "^6.3.0",
|
|
77
|
+
"vitest": "^3.2.6"
|
|
78
|
+
}
|
|
79
|
+
}
|