@xstate/graph
Advanced tools
Comparing version 1.1.0 to 1.2.0
# @xstate/graph | ||
## 1.2.0 | ||
### Minor Changes | ||
- [`142f54e1`](https://github.com/davidkpiano/xstate/commit/142f54e1238919a53c73a40723c415b0044774bb) [#1366](https://github.com/davidkpiano/xstate/pull/1366) Thanks [@davidkpiano](https://github.com/davidkpiano)! - The `toDirectedGraph(...)` function was added, which converts a `machine` into an object that can be used in many different graph-based and visualization tools: | ||
```js | ||
import { toDirectedGraph } from '@xstate/graph'; | ||
const machine = createMachine({/* ... */}); | ||
const digraph = toDirectedGraph(machine); | ||
// returns an object with this structure: | ||
{ | ||
id: '...', | ||
stateNode: /* StateNode */, | ||
children: [ | ||
{ id: '...', children: [/* ... */], edges: [/* ... */] }, | ||
{ id: '...', /* ... */ }, | ||
// ... | ||
], | ||
edges: [ | ||
{ source: /* ... */, target: /* ... */, transition: /* ... */ } | ||
// ... | ||
] | ||
} | ||
``` | ||
## 1.1.0 | ||
@@ -4,0 +33,0 @@ |
import { StateNode, State, DefaultContext, Event, EventObject, StateMachine, AnyEventObject } from 'xstate'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions } from './types'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions, DirectedGraphNode } from './types'; | ||
export declare function toEventObject<TEvent extends EventObject>(event: Event<TEvent>): TEvent; | ||
@@ -9,2 +9,3 @@ /** | ||
export declare function getStateNodes(stateNode: StateNode | StateMachine<any, any, any>): StateNode[]; | ||
export declare function getChildren(stateNode: StateNode): StateNode[]; | ||
export declare function serializeState<TContext>(state: State<TContext, any>): string; | ||
@@ -17,2 +18,3 @@ export declare function serializeEvent<TEvent extends EventObject>(event: TEvent): string; | ||
export declare function getSimplePathsAsArray<TContext = DefaultContext, TEvent extends EventObject = EventObject>(machine: StateNode<TContext, any, TEvent>, options?: ValueAdjMapOptions<TContext, TEvent>): Array<StatePaths<TContext, TEvent>>; | ||
export declare function toDirectedGraph(stateNode: StateNode): DirectedGraphNode; | ||
//# sourceMappingURL=graph.d.ts.map |
@@ -65,2 +65,11 @@ var __assign = (this && this.__assign) || function () { | ||
} | ||
export function getChildren(stateNode) { | ||
if (!stateNode.states) { | ||
return []; | ||
} | ||
var children = Object.keys(stateNode.states).map(function (key) { | ||
return stateNode.states[key]; | ||
}); | ||
return children; | ||
} | ||
export function serializeState(state) { | ||
@@ -314,1 +323,34 @@ var value = state.value, context = state.context; | ||
} | ||
export function toDirectedGraph(stateNode) { | ||
var edges = flatten(stateNode.transitions.map(function (t, transitionIndex) { | ||
var targets = t.target ? t.target : [stateNode]; | ||
return targets.map(function (target, targetIndex) { | ||
var edge = { | ||
id: stateNode.id + ":" + transitionIndex + ":" + targetIndex, | ||
source: stateNode, | ||
target: target, | ||
transition: t, | ||
label: { | ||
text: t.eventType, | ||
toJSON: function () { return ({ text: t.eventType }); } | ||
}, | ||
toJSON: function () { | ||
var label = edge.label; | ||
return { source: stateNode.id, target: target.id, label: label }; | ||
} | ||
}; | ||
return edge; | ||
}); | ||
})); | ||
var graph = { | ||
id: stateNode.id, | ||
stateNode: stateNode, | ||
children: getChildren(stateNode).map(function (sn) { return toDirectedGraph(sn); }), | ||
edges: edges, | ||
toJSON: function () { | ||
var id = graph.id, children = graph.children, graphEdges = graph.edges; | ||
return { id: id, children: children, edges: graphEdges }; | ||
} | ||
}; | ||
return graph; | ||
} |
@@ -1,4 +0,4 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState }; | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,2 +0,3 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState }; | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; |
@@ -1,5 +0,36 @@ | ||
import { State, EventObject, StateValue } from 'xstate'; | ||
import { State, EventObject, StateValue, StateNode, TransitionDefinition } from 'xstate'; | ||
export interface TransitionMap { | ||
state: StateValue | undefined; | ||
} | ||
export declare type JSONSerializable<T extends object, U> = T & { | ||
toJSON: () => U; | ||
}; | ||
export declare type DirectedGraphLabel = JSONSerializable<{ | ||
text: string; | ||
}, { | ||
text: string; | ||
}>; | ||
export declare type DirectedGraphEdge = JSONSerializable<{ | ||
id: string; | ||
source: StateNode; | ||
target: StateNode; | ||
label: DirectedGraphLabel; | ||
transition: TransitionDefinition<any, any>; | ||
}, { | ||
source: string; | ||
target: string; | ||
label: ReturnType<DirectedGraphLabel['toJSON']>; | ||
}>; | ||
export declare type DirectedGraphNode = JSONSerializable<{ | ||
id: string; | ||
stateNode: StateNode; | ||
children: DirectedGraphNode[]; | ||
/** | ||
* The edges representing all transitions from this `stateNode`. | ||
*/ | ||
edges: DirectedGraphEdge[]; | ||
}, { | ||
id: string; | ||
children: DirectedGraphNode[]; | ||
}>; | ||
export interface AdjacencyMap<TContext, TEvent extends EventObject> { | ||
@@ -6,0 +37,0 @@ [stateId: string]: Record<string, { |
import { StateNode, State, DefaultContext, Event, EventObject, StateMachine, AnyEventObject } from 'xstate'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions } from './types'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions, DirectedGraphNode } from './types'; | ||
export declare function toEventObject<TEvent extends EventObject>(event: Event<TEvent>): TEvent; | ||
@@ -9,2 +9,3 @@ /** | ||
export declare function getStateNodes(stateNode: StateNode | StateMachine<any, any, any>): StateNode[]; | ||
export declare function getChildren(stateNode: StateNode): StateNode[]; | ||
export declare function serializeState<TContext>(state: State<TContext, any>): string; | ||
@@ -17,2 +18,3 @@ export declare function serializeEvent<TEvent extends EventObject>(event: TEvent): string; | ||
export declare function getSimplePathsAsArray<TContext = DefaultContext, TEvent extends EventObject = EventObject>(machine: StateNode<TContext, any, TEvent>, options?: ValueAdjMapOptions<TContext, TEvent>): Array<StatePaths<TContext, TEvent>>; | ||
export declare function toDirectedGraph(stateNode: StateNode): DirectedGraphNode; | ||
//# sourceMappingURL=graph.d.ts.map |
@@ -45,2 +45,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toDirectedGraph = exports.getSimplePathsAsArray = exports.getSimplePaths = exports.getShortestPaths = exports.getAdjacencyMap = exports.deserializeEventString = exports.serializeEvent = exports.serializeState = exports.getChildren = exports.getStateNodes = exports.toEventObject = void 0; | ||
var utils_1 = require("xstate/lib/utils"); | ||
@@ -70,2 +71,12 @@ function toEventObject(event) { | ||
exports.getStateNodes = getStateNodes; | ||
function getChildren(stateNode) { | ||
if (!stateNode.states) { | ||
return []; | ||
} | ||
var children = Object.keys(stateNode.states).map(function (key) { | ||
return stateNode.states[key]; | ||
}); | ||
return children; | ||
} | ||
exports.getChildren = getChildren; | ||
function serializeState(state) { | ||
@@ -326,1 +337,35 @@ var value = state.value, context = state.context; | ||
exports.getSimplePathsAsArray = getSimplePathsAsArray; | ||
function toDirectedGraph(stateNode) { | ||
var edges = utils_1.flatten(stateNode.transitions.map(function (t, transitionIndex) { | ||
var targets = t.target ? t.target : [stateNode]; | ||
return targets.map(function (target, targetIndex) { | ||
var edge = { | ||
id: stateNode.id + ":" + transitionIndex + ":" + targetIndex, | ||
source: stateNode, | ||
target: target, | ||
transition: t, | ||
label: { | ||
text: t.eventType, | ||
toJSON: function () { return ({ text: t.eventType }); } | ||
}, | ||
toJSON: function () { | ||
var label = edge.label; | ||
return { source: stateNode.id, target: target.id, label: label }; | ||
} | ||
}; | ||
return edge; | ||
}); | ||
})); | ||
var graph = { | ||
id: stateNode.id, | ||
stateNode: stateNode, | ||
children: getChildren(stateNode).map(function (sn) { return toDirectedGraph(sn); }), | ||
edges: edges, | ||
toJSON: function () { | ||
var id = graph.id, children = graph.children, graphEdges = graph.edges; | ||
return { id: id, children: children, edges: graphEdges }; | ||
} | ||
}; | ||
return graph; | ||
} | ||
exports.toDirectedGraph = toDirectedGraph; |
@@ -1,4 +0,4 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState }; | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } }); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __exportStar = (this && this.__exportStar) || function(m, exports) { | ||
for (var p in m) if (p !== "default" && !exports.hasOwnProperty(p)) __createBinding(exports, m, p); | ||
}; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toDirectedGraph = exports.serializeState = exports.serializeEvent = exports.getShortestPaths = exports.getSimplePaths = exports.getStateNodes = void 0; | ||
var graph_1 = require("./graph"); | ||
exports.getStateNodes = graph_1.getStateNodes; | ||
exports.getSimplePaths = graph_1.getSimplePaths; | ||
exports.getShortestPaths = graph_1.getShortestPaths; | ||
exports.serializeEvent = graph_1.serializeEvent; | ||
exports.serializeState = graph_1.serializeState; | ||
Object.defineProperty(exports, "getStateNodes", { enumerable: true, get: function () { return graph_1.getStateNodes; } }); | ||
Object.defineProperty(exports, "getSimplePaths", { enumerable: true, get: function () { return graph_1.getSimplePaths; } }); | ||
Object.defineProperty(exports, "getShortestPaths", { enumerable: true, get: function () { return graph_1.getShortestPaths; } }); | ||
Object.defineProperty(exports, "serializeEvent", { enumerable: true, get: function () { return graph_1.serializeEvent; } }); | ||
Object.defineProperty(exports, "serializeState", { enumerable: true, get: function () { return graph_1.serializeState; } }); | ||
Object.defineProperty(exports, "toDirectedGraph", { enumerable: true, get: function () { return graph_1.toDirectedGraph; } }); | ||
__exportStar(require("./types"), exports); |
@@ -1,5 +0,36 @@ | ||
import { State, EventObject, StateValue } from 'xstate'; | ||
import { State, EventObject, StateValue, StateNode, TransitionDefinition } from 'xstate'; | ||
export interface TransitionMap { | ||
state: StateValue | undefined; | ||
} | ||
export declare type JSONSerializable<T extends object, U> = T & { | ||
toJSON: () => U; | ||
}; | ||
export declare type DirectedGraphLabel = JSONSerializable<{ | ||
text: string; | ||
}, { | ||
text: string; | ||
}>; | ||
export declare type DirectedGraphEdge = JSONSerializable<{ | ||
id: string; | ||
source: StateNode; | ||
target: StateNode; | ||
label: DirectedGraphLabel; | ||
transition: TransitionDefinition<any, any>; | ||
}, { | ||
source: string; | ||
target: string; | ||
label: ReturnType<DirectedGraphLabel['toJSON']>; | ||
}>; | ||
export declare type DirectedGraphNode = JSONSerializable<{ | ||
id: string; | ||
stateNode: StateNode; | ||
children: DirectedGraphNode[]; | ||
/** | ||
* The edges representing all transitions from this `stateNode`. | ||
*/ | ||
edges: DirectedGraphEdge[]; | ||
}, { | ||
id: string; | ||
children: DirectedGraphNode[]; | ||
}>; | ||
export interface AdjacencyMap<TContext, TEvent extends EventObject> { | ||
@@ -6,0 +37,0 @@ [stateId: string]: Record<string, { |
{ | ||
"name": "@xstate/graph", | ||
"version": "1.1.0", | ||
"version": "1.2.0", | ||
"description": "XState graph utilities", | ||
@@ -46,3 +46,3 @@ "keywords": [ | ||
"ts-jest": "^24.1.9", | ||
"typescript": "^3.8.3", | ||
"typescript": "^3.9.7", | ||
"xstate": "*" | ||
@@ -49,0 +49,0 @@ }, |
@@ -291,2 +291,35 @@ # @xstate/graph | ||
### `toDirectedGraph(machine)` | ||
Converts a `machine` to a directed graph structure. | ||
| Argument | Type | Description | | ||
| --------- | ---------------------------------------------- | ---------------------------------------------------- | | ||
| `machine` | XState Machine created by `createMachine(...)` | The machine to convert to a directed graph structure | | ||
**Example** | ||
```js | ||
import { toDirectedGraph } from '@xstate/graph'; | ||
const machine = createMachine({/* ... */}); | ||
const digraph = toDirectedGraph(machine); | ||
// returns an object with this structure: | ||
{ | ||
id: '...', | ||
stateNode: /* StateNode */, | ||
children: [ | ||
{ id: '...', children: [/* ... */], edges: [/* ... */] }, | ||
{ id: '...', /* ... */ }, | ||
// ... | ||
], | ||
edges: [ | ||
{ source: /* ... */, target: /* ... */, transition: /* ... */ } | ||
// ... | ||
] | ||
} | ||
``` | ||
## Options | ||
@@ -321,5 +354,8 @@ | ||
events: { | ||
INC: [{ type: 'INC', value: 1 }, { type: 'INC', value: 2 }] | ||
INC: [ | ||
{ type: 'INC', value: 1 }, | ||
{ type: 'INC', value: 2 } | ||
] | ||
}, | ||
filter: state => state.context.count <= 5 | ||
filter: (state) => state.context.count <= 5 | ||
}); | ||
@@ -326,0 +362,0 @@ |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
53728
969
405