func Traverse(root ipld.Node, o Options) error {
	t := traversal{
		opts: o,
		seen: map[string]struct{}{},
	}
	state := State{
		Node:  root,
		Depth: 0,
	}
	switch o.Order {
	default:
		return dfsPreTraverse(state, &t)
	case DFSPre:
		return dfsPreTraverse(state, &t)
	case DFSPost:
		return dfsPostTraverse(state, &t)
	case BFS:
		return bfsTraverse(state, &t)
	}
}
Traverse initiates a DAG traversal with the given options starting at
the given root.
package traverse
import (
	"context"
	"errors"
	ipld "github.com/ipfs/go-ipld-format"
)
type Order int
const (
	DFSPre Order = iota
	DFSPost
	BFS
)
type Options struct {
	DAG     ipld.NodeGetter  
	Order   Order            
	Func    Func             
	ErrFunc ErrFunc          
	SkipDuplicates bool  
}
type State struct {
	Node  ipld.Node
	Depth int
}
type traversal struct {
	opts Options
	seen map[string]struct{}
}
func (t *traversal) shouldSkip(n ipld.Node) (bool, error) {
	if t.opts.SkipDuplicates {
		k := n.Cid()
		if _, found := t.seen[k.KeyString()]; found {
			return true, nil
		}
		t.seen[k.KeyString()] = struct{}{}
	}
	return false, nil
}
func (t *traversal) callFunc(next State) error {
	return t.opts.Func(next)
}
func (t *traversal) getNode(link *ipld.Link) (ipld.Node, error) {
	getNode := func(l *ipld.Link) (ipld.Node, error) {
		next, err := l.GetNode(context.TODO(), t.opts.DAG)
		if err != nil {
			return nil, err
		}
		skip, err := t.shouldSkip(next)
		if skip {
			next = nil
		}
		return next, err
	}
	next, err := getNode(link)
	if err != nil && t.opts.ErrFunc != nil {  
		err = t.opts.ErrFunc(err)
		next = nil  
	}
	return next, err
}
type Func func(current State) error
type ErrFunc func(err error) error