aboutsummaryrefslogtreecommitdiff
path: root/README.md
diff options
context:
space:
mode:
Diffstat (limited to 'README.md')
-rw-r--r--README.md169
1 files changed, 169 insertions, 0 deletions
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..9ccd1fd
--- /dev/null
+++ b/README.md
@@ -0,0 +1,169 @@
+# Grafn
+
+Graph + Fn: Execute functions as a graph.
+
+## What it's for?
+
+Grafn lets you execute sequences of async functions by defining them as
+vertices in a graph.
+
+This allows you to easily define and manipulate complex dependencies in
+asynchronous code.
+
+## How can I use it?
+
+In order to use it you must first create a graph.
+
+```javascript
+const Grafn = require('grafn');
+
+const graph = new Grafn();
+```
+
+Next you need to add some vertexes.
+
+```javascript
+graph.vertex({
+ name: 'root',
+ action() {
+
+ return 5;
+ }
+});
+```
+
+This is a vertex without dependencies, it means it can be executed without
+waiting for anything else. The return value of this function will be stored
+so it can be used by its dependents.
+
+You can add dependencies by listing the names as an array in the vertex definition.
+
+```javascript
+graph.vertex({
+ name: 'addition',
+ dependencies: ['root'],
+ action(state) {
+
+ return state.root + state.root;
+ }
+});
+```
+
+Notice how the result of the `root` vertex is available in this action.
+
+Vertexes will be executed as soon as all of their dependencies are met. For
+example, consider the following graph
+
+```javascript
+const Grafn = require('grafn');
+
+const graph = new Grafn();
+
+graph.vertex({
+ name: 'root',
+ action() {
+
+ return 5;
+ }
+});
+
+graph.vertex({
+ name: 'addition',
+ dependencies: ['root'],
+ action(state) {
+
+ return state.root + state.root;
+ }
+});
+
+graph.vertex({
+ name: 'subtraction',
+ dependencies: ['root'],
+ action(state) {
+
+ return state.root - state.root;
+ }
+});
+
+graph.vertex({
+ name: 'multiplication',
+ dependencies: ['root'],
+ action(state) {
+
+ return state.root * state.root;
+ }
+});
+
+graph.vertex({
+ name: 'division',
+ dependencies: ['root'],
+ action(state) {
+
+ return state.root / state.root;
+ }
+});
+
+graph.vertex({
+ name: 'tally',
+ dependencies: ['addition', 'subtraction', 'multiplication', 'division'],
+ action(state) {
+
+ console.log('+', state.addition);
+ console.log('-', state.subtraction);
+ console.log('*', state.multiplication);
+ console.log('/', state.division);
+ }
+});
+```
+
+The `addition`, `subtraction`, `multiplication`, and `division` vertices will
+all run as soon as `roott` is executed. However, the final `tally` vertex won't
+run until all other operations are complete.
+
+You can visualize the graph by using the `graph.toString()` method. This
+will output a graphviz digraph:
+
+```graphviz
+digraph {
+ root
+ addition
+ root -> addition
+ subtraction
+ root -> subtraction
+ multiplication
+ root -> multiplication
+ division
+ root -> division
+ tally
+ addition -> tally
+ subtraction -> tally
+ multiplication -> tally
+ division -> tally
+}
+```
+
+![execution graph, before execution][graph-pre-exec]
+
+You can easily change the shape of the graph by changing the dependencies array.
+
+In order to start execution of the graph you should select which node to start
+from.
+
+```
+graph.run('root');
+```
+
+After an execution, you can use `graph.toString()` to check the result of an
+execution. It will highlight which nodes were executed successfully (green), and
+which nodes threw an error (red).
+
+![execution graph, after execution][graph-post-exec]
+
+## Acknowledgements
+
+This project implements the same ideas behind [fluorine][fluorine], a similar
+graph based library. Grafn wouldn't exist without it.
+
+[fluorine]: https://github.com/freshout-dev/fluorine
+[graph-pre-exec]: doc/images/graph-pre-exec.svg
+[graph-post-exec]: doc/images/graph-post-exec.svg