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 ADDED
@@ -0,0 +1,78 @@
1
+ # sfn-diagram-react
2
+
3
+ [![npm version](https://img.shields.io/npm/v/sfn-diagram-react.svg)](https://www.npmjs.com/package/sfn-diagram-react)
4
+ [![license](https://img.shields.io/npm/l/sfn-diagram-react.svg)](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;
@@ -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 };
@@ -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
+ }