@xstate/graph
Advanced tools
Comparing version 1.3.0 to 1.4.0
# @xstate/graph | ||
## 1.4.0 | ||
### Minor Changes | ||
- [#2703](https://github.com/statelyai/xstate/pull/2703) [`6a0ff73bf`](https://github.com/statelyai/xstate/commit/6a0ff73bf8817dc401ef9b45c71dd7875dbc9f20) Thanks [@Silverwolf90](https://github.com/Silverwolf90)! - Add getPathFromEvents to generate a path from a sequence of events. | ||
## 1.3.0 | ||
@@ -4,0 +10,0 @@ |
import { StateNode, State, DefaultContext, Event, EventObject, StateMachine, AnyEventObject } from 'xstate'; | ||
import { StatePath } from '.'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions, DirectedGraphNode } from './types'; | ||
@@ -18,2 +19,3 @@ export declare function toEventObject<TEvent extends EventObject>(event: Event<TEvent>): TEvent; | ||
export declare function toDirectedGraph(stateNode: StateNode): DirectedGraphNode; | ||
export declare function getPathFromEvents<TContext = DefaultContext, TEvent extends EventObject = EventObject>(machine: StateMachine<TContext, any, TEvent>, events: Array<TEvent>): StatePath<TContext, TEvent>; | ||
//# sourceMappingURL=graph.d.ts.map |
@@ -28,5 +28,6 @@ var __assign = (this && this.__assign) || function () { | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
@@ -61,3 +62,3 @@ var __values = (this && this.__values) || function(o) { | ||
var childStateNodes = getStateNodes(childStateNode); | ||
accNodes.push.apply(accNodes, __spread([childStateNode], childStateNodes)); | ||
accNodes.push.apply(accNodes, __spreadArray([childStateNode], __read(childStateNodes))); | ||
return accNodes; | ||
@@ -266,3 +267,3 @@ }, []); | ||
weight: path.length, | ||
segments: __spread(path) | ||
segments: __spreadArray([], __read(path)) | ||
}); | ||
@@ -354,1 +355,58 @@ } | ||
} | ||
export function getPathFromEvents(machine, events) { | ||
var e_6, _a; | ||
var optionsWithDefaults = getValueAdjMapOptions({ | ||
events: events.reduce(function (events, event) { | ||
var _a; | ||
var _b; | ||
(_a = events[_b = event.type]) !== null && _a !== void 0 ? _a : (events[_b] = []); | ||
events[event.type].push(event); | ||
return events; | ||
}, {}) | ||
}); | ||
var stateSerializer = optionsWithDefaults.stateSerializer, eventSerializer = optionsWithDefaults.eventSerializer; | ||
if (!machine.states) { | ||
return { | ||
state: machine.initialState, | ||
segments: [], | ||
weight: 0 | ||
}; | ||
} | ||
var adjacency = getAdjacencyMap(machine, optionsWithDefaults); | ||
var stateMap = new Map(); | ||
var path = []; | ||
var initialStateSerial = stateSerializer(machine.initialState); | ||
stateMap.set(initialStateSerial, machine.initialState); | ||
var stateSerial = initialStateSerial; | ||
var state = machine.initialState; | ||
try { | ||
for (var events_1 = __values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) { | ||
var event_3 = events_1_1.value; | ||
path.push({ | ||
state: stateMap.get(stateSerial), | ||
event: event_3 | ||
}); | ||
var eventSerial = eventSerializer(event_3); | ||
var nextSegment = adjacency[stateSerial][eventSerial]; | ||
if (!nextSegment) { | ||
throw new Error("Invalid transition from " + stateSerial + " with " + eventSerial); | ||
} | ||
var nextStateSerial = stateSerializer(nextSegment.state); | ||
stateMap.set(nextStateSerial, nextSegment.state); | ||
stateSerial = nextStateSerial; | ||
state = nextSegment.state; | ||
} | ||
} | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1); | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
return { | ||
state: state, | ||
segments: path, | ||
weight: path.length | ||
}; | ||
} |
@@ -1,4 +0,4 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
import { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -1,3 +0,3 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
import { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; |
import { StateNode, State, DefaultContext, Event, EventObject, StateMachine, AnyEventObject } from 'xstate'; | ||
import { StatePath } from '.'; | ||
import { StatePathsMap, StatePaths, AdjacencyMap, ValueAdjMapOptions, DirectedGraphNode } from './types'; | ||
@@ -18,2 +19,3 @@ export declare function toEventObject<TEvent extends EventObject>(event: Event<TEvent>): TEvent; | ||
export declare function toDirectedGraph(stateNode: StateNode): DirectedGraphNode; | ||
export declare function getPathFromEvents<TContext = DefaultContext, TEvent extends EventObject = EventObject>(machine: StateMachine<TContext, any, TEvent>, events: Array<TEvent>): StatePath<TContext, TEvent>; | ||
//# sourceMappingURL=graph.d.ts.map |
@@ -29,5 +29,6 @@ "use strict"; | ||
}; | ||
var __spread = (this && this.__spread) || function () { | ||
for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i])); | ||
return ar; | ||
var __spreadArray = (this && this.__spreadArray) || function (to, from) { | ||
for (var i = 0, il = from.length, j = to.length; i < il; i++, j++) | ||
to[j] = from[i]; | ||
return to; | ||
}; | ||
@@ -46,3 +47,3 @@ var __values = (this && this.__values) || function(o) { | ||
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; | ||
exports.getPathFromEvents = 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"); | ||
@@ -66,3 +67,3 @@ function toEventObject(event) { | ||
var childStateNodes = getStateNodes(childStateNode); | ||
accNodes.push.apply(accNodes, __spread([childStateNode], childStateNodes)); | ||
accNodes.push.apply(accNodes, __spreadArray([childStateNode], __read(childStateNodes))); | ||
return accNodes; | ||
@@ -278,3 +279,3 @@ }, []); | ||
weight: path.length, | ||
segments: __spread(path) | ||
segments: __spreadArray([], __read(path)) | ||
}); | ||
@@ -369,1 +370,59 @@ } | ||
exports.toDirectedGraph = toDirectedGraph; | ||
function getPathFromEvents(machine, events) { | ||
var e_6, _a; | ||
var optionsWithDefaults = getValueAdjMapOptions({ | ||
events: events.reduce(function (events, event) { | ||
var _a; | ||
var _b; | ||
(_a = events[_b = event.type]) !== null && _a !== void 0 ? _a : (events[_b] = []); | ||
events[event.type].push(event); | ||
return events; | ||
}, {}) | ||
}); | ||
var stateSerializer = optionsWithDefaults.stateSerializer, eventSerializer = optionsWithDefaults.eventSerializer; | ||
if (!machine.states) { | ||
return { | ||
state: machine.initialState, | ||
segments: [], | ||
weight: 0 | ||
}; | ||
} | ||
var adjacency = getAdjacencyMap(machine, optionsWithDefaults); | ||
var stateMap = new Map(); | ||
var path = []; | ||
var initialStateSerial = stateSerializer(machine.initialState); | ||
stateMap.set(initialStateSerial, machine.initialState); | ||
var stateSerial = initialStateSerial; | ||
var state = machine.initialState; | ||
try { | ||
for (var events_1 = __values(events), events_1_1 = events_1.next(); !events_1_1.done; events_1_1 = events_1.next()) { | ||
var event_3 = events_1_1.value; | ||
path.push({ | ||
state: stateMap.get(stateSerial), | ||
event: event_3 | ||
}); | ||
var eventSerial = eventSerializer(event_3); | ||
var nextSegment = adjacency[stateSerial][eventSerial]; | ||
if (!nextSegment) { | ||
throw new Error("Invalid transition from " + stateSerial + " with " + eventSerial); | ||
} | ||
var nextStateSerial = stateSerializer(nextSegment.state); | ||
stateMap.set(nextStateSerial, nextSegment.state); | ||
stateSerial = nextStateSerial; | ||
state = nextSegment.state; | ||
} | ||
} | ||
catch (e_6_1) { e_6 = { error: e_6_1 }; } | ||
finally { | ||
try { | ||
if (events_1_1 && !events_1_1.done && (_a = events_1.return)) _a.call(events_1); | ||
} | ||
finally { if (e_6) throw e_6.error; } | ||
} | ||
return { | ||
state: state, | ||
segments: path, | ||
weight: path.length | ||
}; | ||
} | ||
exports.getPathFromEvents = getPathFromEvents; |
@@ -1,4 +0,4 @@ | ||
import { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
import { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph } from './graph'; | ||
export { getStateNodes, getPathFromEvents, getSimplePaths, getShortestPaths, serializeEvent, serializeState, toDirectedGraph }; | ||
export * from './types'; | ||
//# sourceMappingURL=index.d.ts.map |
@@ -13,5 +13,6 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.toDirectedGraph = exports.serializeState = exports.serializeEvent = exports.getShortestPaths = exports.getSimplePaths = exports.getStateNodes = void 0; | ||
exports.toDirectedGraph = exports.serializeState = exports.serializeEvent = exports.getShortestPaths = exports.getSimplePaths = exports.getPathFromEvents = exports.getStateNodes = void 0; | ||
var graph_1 = require("./graph"); | ||
Object.defineProperty(exports, "getStateNodes", { enumerable: true, get: function () { return graph_1.getStateNodes; } }); | ||
Object.defineProperty(exports, "getPathFromEvents", { enumerable: true, get: function () { return graph_1.getPathFromEvents; } }); | ||
Object.defineProperty(exports, "getSimplePaths", { enumerable: true, get: function () { return graph_1.getSimplePaths; } }); | ||
@@ -18,0 +19,0 @@ Object.defineProperty(exports, "getShortestPaths", { enumerable: true, get: function () { return graph_1.getShortestPaths; } }); |
{ | ||
"name": "@xstate/graph", | ||
"version": "1.3.0", | ||
"version": "1.4.0", | ||
"description": "XState graph utilities", | ||
@@ -14,3 +14,3 @@ "keywords": [ | ||
"author": "David Khourshid <davidkpiano@gmail.com>", | ||
"homepage": "https://github.com/davidkpiano/xstate/tree/master/packages/xstate-test#readme", | ||
"homepage": "https://github.com/davidkpiano/xstate/tree/main/packages/xstate-test#readme", | ||
"license": "MIT", | ||
@@ -44,6 +44,6 @@ "main": "lib/index.js", | ||
"devDependencies": { | ||
"jest": "^26.4.2", | ||
"jest": "^26.6.3", | ||
"lerna-alias": "3.0.3-0", | ||
"ts-jest": "^26.4.0", | ||
"typescript": "^4.1.2", | ||
"ts-jest": "^26.5.6", | ||
"typescript": "^4.3.5", | ||
"xstate": "*" | ||
@@ -50,0 +50,0 @@ }, |
392
README.md
@@ -5,4 +5,7 @@ # @xstate/graph | ||
## Quick Start | ||
- [Read the full documentation in the XState docs](https://xstate.js.org/docs/packages/xstate-graph/). | ||
- [Read our contribution guidelines](https://github.com/statelyai/xstate/blob/main/CONTRIBUTING.md). | ||
## Quick start | ||
1. Install `xstate` and `@xstate/graph`: | ||
@@ -17,390 +20,7 @@ | ||
```js | ||
import { Machine } from 'xstate'; | ||
import { createMachine } from 'xstate'; | ||
import { getSimplePaths } from '@xstate/graph'; | ||
const machine = Machine(/* ... */); | ||
const machine = createMachine(/* ... */); | ||
const paths = getSimplePaths(machine); | ||
``` | ||
## API | ||
### `getShortestPaths(machine, options?)` | ||
**Arguments** | ||
- `machine` - the [`Machine`](https://xstate.js.org/docs/guides/machines.html) to traverse | ||
- `options` (optional) - [options](#options) that customize how the algorithm will traverse the machine | ||
Returns the [shortest paths (Dijkstra's algorithm)](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm) of a [machine](https://xstate.js.org/docs/guides/machines.html) from the initial state to every other state as a mapped object, where the: | ||
- **key** is the stringified state | ||
- **value** is an object with the properties: | ||
- `state` - the target [`State`](https://xstate.js.org/docs/guides/states.html) | ||
- `path` - the shortest path to get from the initial state to the target state | ||
The `path` is an array of segments, where each segment is an object with the properties: | ||
- `state` - the [`State`](https://xstate.js.org/docs/guides/states.html) of the segment | ||
- `weight` - the total [weight](<https://en.wikipedia.org/wiki/Graph_(discrete_mathematics)#Weighted_graph>) of the path | ||
- Currently, each transition from one state to another has a weight of 1. This will be customizable in the future. | ||
- `event` - the event object that transitions the `machine` from the state to the next state in the path | ||
Every path starts with the initial state. | ||
The overall object structure looks like this: | ||
```json5 | ||
{ | ||
"<SERIALIZED STATE>": { | ||
"state": State { ... }, | ||
"path": [ | ||
{ | ||
"state": State { ... }, | ||
"event": { "type": "<event.type>", "<PROP>": "<event.PROP>" } | ||
}, | ||
{ | ||
"state": State { ... }, | ||
"event": { "type": "<event.type>", "<PROP>": "<event.PROP>" } | ||
}, | ||
... | ||
] | ||
}, | ||
... | ||
} | ||
``` | ||
**Example** | ||
```js | ||
import { Machine } from 'xstate'; | ||
import { getShortestPaths } from '@xstate/graph'; | ||
const feedbackMachine = Machine({ | ||
id: 'feedback', | ||
initial: 'question', | ||
states: { | ||
question: { | ||
on: { | ||
CLICK_GOOD: 'thanks', | ||
CLICK_BAD: 'form', | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
form: { | ||
on: { | ||
SUBMIT: 'thanks', | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
thanks: { | ||
on: { | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
closed: { | ||
type: 'final' | ||
} | ||
} | ||
}); | ||
const shortestPaths = getShortestPaths(feedbackMachine); | ||
console.log(shortestPaths); | ||
// => { | ||
// '"question"': { | ||
// state: State { value: 'question', context: undefined }, | ||
// weight: 0, | ||
// path: [] | ||
// }, | ||
// '"thanks"': { | ||
// state: State { value: 'thanks', context: undefined }, | ||
// weight: 1, | ||
// path: [ | ||
// { | ||
// state: State { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_GOOD' } | ||
// } | ||
// ] | ||
// }, | ||
// '"form"': { | ||
// state: State { value: 'form', context: undefined }, | ||
// weight: 1, | ||
// path: [ | ||
// { | ||
// state: State { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_BAD' } | ||
// } | ||
// ] | ||
// }, | ||
// '"closed"': { | ||
// state: State { value: 'closed', context: undefined }, | ||
// weight: 1, | ||
// path: [ | ||
// { | ||
// state: State { value: 'question', context: undefined }, | ||
// event: { type: 'CLOSE' } | ||
// } | ||
// ] | ||
// } | ||
// }; | ||
``` | ||
### `getSimplePaths(machine, options?)` | ||
**Arguments** | ||
- `machine` - the [`Machine`](https://xstate.js.org/docs/guides/machines.html) to traverse | ||
- `options` (optional) - [options](#options) that customize how the algorithm will traverse the machine | ||
Returns the [simple paths](<https://en.wikipedia.org/wiki/Path_(graph_theory)#Definitions>) of a [machine](https://xstate.js.org/docs/guides/machines.html) as a mapped object, where the: | ||
- **key** is the stringified state | ||
- **value** is an object with the properties: | ||
- `state` - the target [`State`](https://xstate.js.org/docs/guides/states.html) | ||
- `paths` - the array of paths to get from the initial state to the target state | ||
Each `path` in `paths` is an array of segments, where each segment of the path is an object with the properties: | ||
- `state` - the [`State`](https://xstate.js.org/docs/guides/states.html) of the segment | ||
- `event` - the event object that transitions the `machine` from the state to the next state in the path | ||
Every path starts with the initial state. | ||
The overall object structure looks like this: | ||
```json5 | ||
{ | ||
"<SERIALIZED STATE>": { | ||
"state": State { ... }, | ||
"paths": [ | ||
[ | ||
{ | ||
"state": State { ... }, | ||
"event": { "type": "<event.type>", "<PROP>": "<event.PROP>" } | ||
}, | ||
{ | ||
"state": State { ... }, | ||
"event": { "type": "<event.type>", "<PROP>": "<event.PROP>" } | ||
}, | ||
... | ||
], | ||
... | ||
] | ||
}, | ||
... | ||
} | ||
``` | ||
**Example** | ||
```js | ||
import { Machine } from 'xstate'; | ||
import { getSimplePaths } from '@xstate/graph'; | ||
const feedbackMachine = Machine({ | ||
id: 'feedback', | ||
initial: 'question', | ||
states: { | ||
question: { | ||
on: { | ||
CLICK_GOOD: 'thanks', | ||
CLICK_BAD: 'form', | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
form: { | ||
on: { | ||
SUBMIT: 'thanks', | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
thanks: { | ||
on: { | ||
CLOSE: 'closed', | ||
ESC: 'closed' | ||
} | ||
}, | ||
closed: { | ||
type: 'final' | ||
} | ||
} | ||
}); | ||
const simplePaths = getSimplePaths(feedbackMachine); | ||
console.log(simplePaths); | ||
// => { | ||
// '"question"': { | ||
// state: { value: 'question', context: undefined }, | ||
// paths: [[]] | ||
// }, | ||
// '"thanks"': { | ||
// state: { value: 'thanks', context: undefined }, | ||
// paths: [ | ||
// [ | ||
// { | ||
// state: { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_GOOD' } | ||
// } | ||
// ], | ||
// [ | ||
// { | ||
// state: { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_BAD' } | ||
// }, | ||
// { | ||
// state: { value: 'form', context: undefined }, | ||
// event: { type: 'SUBMIT' } | ||
// } | ||
// ] | ||
// ] | ||
// }, | ||
// '"closed"': { | ||
// state: { value: 'closed', context: undefined }, | ||
// paths: [ | ||
// [ | ||
// { | ||
// state: { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_GOOD' } | ||
// }, | ||
// { | ||
// state: { value: 'thanks', context: undefined }, | ||
// event: { type: 'CLOSE' } | ||
// } | ||
// ], | ||
// [ | ||
// { | ||
// state: { value: 'question', context: undefined }, | ||
// event: { type: 'CLICK_GOOD' } | ||
// }, | ||
// { | ||
// state: { value: 'thanks', context: undefined }, | ||
// event: { type: 'ESC' } | ||
// } | ||
// ], | ||
// ... | ||
// ] | ||
// }, | ||
// ... | ||
// }; | ||
``` | ||
### `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 | ||
Options can be passed into `getShortestPaths` or `getSimplePaths` to customize how the graph represented by the machine should be traversed: | ||
- `events` - a mapping of event types to an array of event objects to be used for those events | ||
- `filter` - a function that determines whether a `state` should be traversed. If `false`, the traversal algorithm(s) will assume the state was "seen" and ignore traversing it. | ||
**Examples** | ||
In the below example, the `INC` event is expanded to include two possible events, with `value: 1` and `value: 2` as the payload. It also ensures that the `state.context.count <= 5`; otherwise, this machine would be traversed infinitely. | ||
```js | ||
const counterMachine = Machine({ | ||
id: 'counter', | ||
initial: 'active', | ||
context: { count: 0 }, | ||
states: { | ||
active: { | ||
on: { | ||
INC: { | ||
actions: assign({ count: (ctx, e) => ctx.count + e.value }) | ||
} | ||
} | ||
} | ||
} | ||
}); | ||
const shortestPaths = getShortestPaths(counterMachine, { | ||
events: { | ||
INC: [ | ||
{ type: 'INC', value: 1 }, | ||
{ type: 'INC', value: 2 } | ||
] | ||
}, | ||
filter: (state) => state.context.count <= 5 | ||
}); | ||
console.log(shortestPaths); | ||
// => { | ||
// '"active" | {"count":0}': { | ||
// state: { value: 'active', context: { count: 0 } }, | ||
// weight: 0, | ||
// path: [] | ||
// }, | ||
// '"active" | {"count":1}': { | ||
// state: { value: 'active', context: { count: 1 } }, | ||
// weight: 1, | ||
// path: [ | ||
// { | ||
// state: { value: 'active', context: { count: 0 } }, | ||
// event: { type: 'INC', value: 1 } | ||
// } | ||
// ] | ||
// }, | ||
// '"active" | {"count":2}': { | ||
// state: { value: 'active', context: { count: 2 } }, | ||
// weight: 1, | ||
// path: [ | ||
// { | ||
// state: { value: 'active', context: { count: 0 } }, | ||
// event: { type: 'INC', value: 2 } | ||
// } | ||
// ] | ||
// }, | ||
// '"active" | {"count":3}': { | ||
// state: { value: 'active', context: { count: 3 } }, | ||
// weight: 2, | ||
// path: [ | ||
// { | ||
// state: { value: 'active', context: { count: 0 } }, | ||
// event: { type: 'INC', value: 1 } | ||
// }, | ||
// { | ||
// state: { value: 'active', context: { count: 1 } }, | ||
// event: { type: 'INC', value: 2 } | ||
// } | ||
// ] | ||
// }, | ||
// ... | ||
// }; | ||
``` |
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
No website
QualityPackage does not have a website.
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
No website
QualityPackage does not have a website.
Found 1 instance in 1 package
1084
51802
25