Make all `neighbors` options required (#354)

Summary:
In actual code, we almost always call `neighbors` with a specified
direction. Usually, you want to inspect some relation like “parents of
this commit” or “GitHub nodes referenced by this comment”, and so the
edge direction matters. In each of the above cases, forgetting to
include the direction would introduce a bug: you’d get parents _and
children_ of a commit, or GitHub nodes referenced by _or that refer to_
a comment. It’s easy to forget this when writing the code, so we prefer
to make an explicit direction required, and allow people to specify
`Direction.ANY` in the case that that is what they want.

(In other words: we want to make the common thing easy, the uncommon
thing possible, and the wrong thing impossible.)

A similar situation holds for filters. By forcing clients to think about
what kinds of edges they want to follow to what kinds of nodes, we
encourage them to write more robust code. As before, if clients do want
to consider all nodes or all edges, they can pass the appropriate empty
address (`nodeAddress([])` or `edgeAddress([]`), which is a prefix of
every address.

Therefore, we require that clients pass an `options` object to
`neighbors`, and we furthermore require that each of the three options
be present.

Paired with @decentralion, in spirit.

Test Plan:
None; this changes the API for a function that has no implementation or
clients.

wchargin-branch: neighbors-options-required
This commit is contained in:
William Chargin 2018-06-06 15:39:08 -07:00 committed by GitHub
parent dfaa7d9764
commit 08cb60e762
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 5 deletions

View File

@ -16,15 +16,20 @@ export type Edge = {|
export type Neighbor = {|+node: NodeAddress, +edge: Edge|}; export type Neighbor = {|+node: NodeAddress, +edge: Edge|};
export opaque type DirectionT = Symbol; export opaque type DirectionT = Symbol;
export const Direction: {|+IN: DirectionT, +OUT: DirectionT|} = Object.freeze({ export const Direction: {|
+IN: DirectionT,
+OUT: DirectionT,
+ANY: DirectionT,
|} = Object.freeze({
IN: Symbol("IN"), IN: Symbol("IN"),
OUT: Symbol("OUT"), OUT: Symbol("OUT"),
ANY: Symbol("ANY"),
}); });
export type NeighborsOptions = {| export type NeighborsOptions = {|
+direction: ?DirectionT, +direction: DirectionT,
+nodePrefix: ?NodeAddress, +nodePrefix: NodeAddress,
+edgePrefix: ?EdgeAddress, +edgePrefix: EdgeAddress,
|}; |};
export opaque type GraphJSON = any; // TODO export opaque type GraphJSON = any; // TODO
@ -127,7 +132,7 @@ export class Graph {
yield* this._edges.values(); yield* this._edges.values();
} }
neighbors(node: NodeAddress, options?: NeighborsOptions): Iterator<Neighbor> { neighbors(node: NodeAddress, options: NeighborsOptions): Iterator<Neighbor> {
const _ = {node, options}; const _ = {node, options};
throw new Error("neighbors"); throw new Error("neighbors");
} }