(
source: GraphSource<any>,
input: Iterable<TraversalPath<any, any, any>>,
_context?: QueryContext,
)
| 3430 | } |
| 3431 | |
| 3432 | public *traverse( |
| 3433 | source: GraphSource<any>, |
| 3434 | input: Iterable<TraversalPath<any, any, any>>, |
| 3435 | _context?: QueryContext, |
| 3436 | ): IterableIterator<TraversalPath<any, any, any>> { |
| 3437 | const { direction, edgeLabels, stepLabels } = this.config; |
| 3438 | for (const path of input) { |
| 3439 | this.traversed++; |
| 3440 | const value = path.value as any; |
| 3441 | if (value === undefined) continue; |
| 3442 | if (value instanceof Vertex) { |
| 3443 | if (direction === "in" || direction === "both") { |
| 3444 | // Incoming edges: this vertex is the target (inV) |
| 3445 | // Navigate to the source vertex (outV) |
| 3446 | for (const edge of source.getIncomingEdges(value.id)) { |
| 3447 | this.traversed++; |
| 3448 | if (edgeLabels.length === 0 || edgeLabels.includes(edge.label)) { |
| 3449 | this.emitted++; |
| 3450 | yield path.with(edge).with(edge.outV, stepLabels); |
| 3451 | } |
| 3452 | } |
| 3453 | } |
| 3454 | if (direction === "out" || direction === "both") { |
| 3455 | // Outgoing edges: this vertex is the source (outV) |
| 3456 | // Navigate to the target vertex (inV) |
| 3457 | for (const edge of source.getOutgoingEdges(value.id)) { |
| 3458 | this.traversed++; |
| 3459 | if (edgeLabels.length === 0 || edgeLabels.includes(edge.label)) { |
| 3460 | // For direction='both', skip self-loops since they were already |
| 3461 | // yielded in the incoming edges pass above |
| 3462 | const storedEdge = edge[$StoredElement]; |
| 3463 | if (direction === "both" && storedEdge.inV === storedEdge.outV) { |
| 3464 | continue; |
| 3465 | } |
| 3466 | this.emitted++; |
| 3467 | yield path.with(edge).with(edge.inV, stepLabels); |
| 3468 | } |
| 3469 | } |
| 3470 | } |
| 3471 | } else if (value instanceof Edge) { |
| 3472 | // When processing an edge, we have two different semantics: |
| 3473 | // 1. Traversal continuation (direction="in"/"out"/"both"): |
| 3474 | // - "out" means continue forward along edge (to target = inV) |
| 3475 | // - "in" means go backward along edge (to source = outV) |
| 3476 | // 2. Direct vertex access (direction="inVertex"/"outVertex"): |
| 3477 | // - "inVertex" returns edge.inV (target) |
| 3478 | // - "outVertex" returns edge.outV (source) |
| 3479 | if (direction === "inVertex") { |
| 3480 | // Fluent API: return the target vertex (inV) |
| 3481 | this.emitted++; |
| 3482 | yield path.with(value.inV, stepLabels); |
| 3483 | } else if (direction === "outVertex") { |
| 3484 | // Fluent API: return the source vertex (outV) |
| 3485 | this.emitted++; |
| 3486 | yield path.with(value.outV, stepLabels); |
| 3487 | } else if (direction === "in") { |
| 3488 | // Traversal: going backward along edge, return source |
| 3489 | this.emitted++; |
nothing calls this directly
no test coverage detected