# graph-traversal

Gremlin-like generalized graph traversal API

## Usage

This package comes in iterable and async iterable flavors. The exports are named the same in each.

```typescript
import { VertexTraversal, EdgeTraversal } from "graph-traversal"
import { VertexTraversal, EdgeTraversal } from "graph-traversal/async"
```

Currently, the only way to begin a traversal is to call `VertexTraversal.from`. Any graph with a `match` method will be accepted. (Implementers can always make a proxy object that implements such.)

Almost all traversal methods yield a new traversal object that holds immutable state.

For the below method descriptions:
* `in` means traveling towards the current result.
* `out` means traveling away from the current result.
* `both` means getting results from both `in` and `out` directions.
* For the methods with optional parameters: `undefined` can be a valid vertex, so passing `undefined` is not the same as passing no arguments at all. Passing `undefined` will match `undefined` vertices or edges with the graph.

### Common traversal methods

#### traversal.as(key)

Assigns a key name to the current object being traversed. For a vertex traversal, the object will be a vertex. For an edge traversal, the object will be an edge.

The key can be a `string`, a `number`, or a `symbol`.

#### traversal.collect()

Collects all of the named objects as a single object. For example, `.as("foo").out("child").as("bar")` will emit objects with the signature `{ foo: ?, bar: ? }`.

#### traversal.filter(filterFn)

Filters the currently matched vertices/edges.

#### traversal.filterTriple(filterFn)

Filters the previously matched triple. For example, `.out("x").filterTriple(fn)` will consider all the triples that led to `x`. Note: At the beginning of the traversal, there will be no triples.

#### traversal[Symbol.iterator]() or traversal[Symbol.asyncIterator]()

Traverses through the currently matched vertices or edges.

### Vertex traversal methods

#### VertexTraversal.from(graph, vertex)

Creates a new vertex traversal starting from the specified vertex.

`graph` should be an object that implements a `match` method that takes `pattern`.
`pattern` is an object that has any of the keys `subject`, `predicate`, or `object`.
`match` should return either an `IterableIterator` or an `AsyncIterableIterator`, depending on the flavor of traversal, that iterates through all of the triples matched by the pattern.

#### vt.out(), vt.in(), vt.both()

`out`, `in`, and `both` can take the following arguments:
* `()` - go through all the adjacent vertices in the specified direction
* `(predicate: E)` - filter by predicate
* `(predicate: E, vertex: V)` - filter by predicate and adjacent vertex

Return value: vertex traversal

#### vt.outE(), vt.inE(), vt.bothE()

`outE`, `inE`, and `bothE` can take the following arguments:
* `()` - go through all the adjacent edges
* `(predicate: E)` - filter by predicate

Return value: edge traversal

### Edge traversal methods

#### et.outV(), et.inV(), et.bothV()

`outV`, `inV`, and `bothV` depend on the last set of triples matched. There will be no previous triples at the start of the traversal 

They can take the following arguments:
* `()` - go through all the adjacent vertices in the specified direction
* `(vertex: V)` - filter by vertex

Return value: vertex traversal
