Create type signatures for new graph API (#306)

src/core2/graph.js has the types and Graph class scaffold as
described in address_payload_unification_design.md.
Also, we decided to modify the design doc to include a type parameter
for Edges (although we aer open to removing if it becomes cumbersome).

Test plan:
`yarn flow` passes, and the design doc still typechecks too.

Paired with @wchargin
This commit is contained in:
Dandelion Mané 2018-05-28 13:04:03 -07:00 committed by GitHub
parent c957e84da1
commit 7078125c56
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 175 additions and 6 deletions

View File

@ -118,7 +118,7 @@ type NeighborsOptions = {|
|}; |};
type Neighbor<+T: NodeReference> = {| type Neighbor<+T: NodeReference> = {|
+ref: T, +ref: T,
+edge: Edge, +edge: Edge<any>,
|}; |};
``` ```
@ -334,11 +334,11 @@ Graphs, of course, also need to refer to edges. In this proposal, we
leave edges structurally unchanged, but remove their type parameters: leave edges structurally unchanged, but remove their type parameters:
```javascript ```javascript
type Edge = {| type Edge<+T> = {|
+address: Address, +address: Address,
+src: Address, +src: Address,
+dst: Address, +dst: Address,
+payload: any, +payload: T,
|}; |};
``` ```
@ -357,17 +357,17 @@ declare class Graph /* no type parameters! */ {
plugins(): Plugins; plugins(): Plugins;
addNode(np: NodePayload): this; addNode(np: NodePayload): this;
addEdge(edge: Edge): this; addEdge(edge: Edge<any>): this;
removeNode(address: Address): this; removeNode(address: Address): this;
removeEdge(address: Address): this; removeEdge(address: Address): this;
node(address: Address): ?Node<any, any>; node(address: Address): ?Node<any, any>;
edge(address: Address): ?Edge; edge(address: Address): ?Edge<any>;
ref(address: Address): NodeReference; ref(address: Address): NodeReference;
nodes(filter?: {|+type?: string|}): Iterator<Node<any, any>>; nodes(filter?: {|+type?: string|}): Iterator<Node<any, any>>;
edges(filter?: {|+type?: string|}): Iterator<Edge>; edges(filter?: {|+type?: string|}): Iterator<Edge<any>>;
static mergeConservative(Iterable<Graph>): Graph; static mergeConservative(Iterable<Graph>): Graph;

169
src/core2/graph.js Normal file
View File

@ -0,0 +1,169 @@
// @flow
import type {Address} from "./address";
import type {Compatible} from "../util/compat";
export type Node<NR: NodeReference, NP: NodePayload> = {|
+ref: NR,
+payload: NP,
+address: Address,
|};
export interface NodePayload {
address(): Address;
/**
* Convert this object to its serialized form. This must be a plain
* old JSON value: i.e., a value `v` such that
* `JSON.parse(JSON.stringify(v))` is deep-equal to `v`.
*/
toJSON(): any;
}
export interface NodeReference {
graph(): Graph;
address(): Address;
get(): ?Node<any, any>;
neighbors(
options?: NeighborsOptions
): Iterator<{|+ref: NodeReference, +edge: Edge<any>|}>;
}
export type Edge<+T> = {|
+address: Address,
+src: Address,
+dst: Address,
+payload: T,
|};
export type NeighborsOptions = {|
+nodeType?: string,
+edgeType?: string,
+direction?: "IN" | "OUT" | "ANY",
|};
export interface PluginHandler<NR: NodeReference, NP: NodePayload> {
/**
* Enrich a base reference with plugin-/domain-specific properties.
*/
createReference(baseReference: NodeReference): NR;
/**
* Deserialize a JSON payload, which is guaranteed to be the
* serialization of a previous `NP`.
*/
createPayload(json: any): NP;
/**
* Provide the name of the plugin.
* Should return a constant string.
*/
pluginName(): string;
}
export type Plugins = $ReadOnlyArray<PluginHandler<any, any>>;
export class Graph {
constructor(plugins: Plugins) {
const _ = plugins;
throw new Error("Graphv2 is not yet implemented");
}
ref(address: Address): NodeReference {
const _ = address;
throw new Error("Graphv2 is not yet implemented");
}
node(address: Address): ?Node<any, any> {
const _ = address;
throw new Error("Graphv2 is not yet implemented");
}
/**
* Get nodes in the graph, in unspecified order.
*
* If filter is provided, it will return only nodes with the requested type.
*/
nodes(filter?: {|+type?: string|}): Iterator<Node<any, any>> {
const _ = filter;
throw new Error("Graphv2 is not yet implemented");
}
edge(address: Address): Edge<any> {
const _ = address;
throw new Error("Graphv2 is not yet implemented");
}
/**
* Gets edges in the graph, in unspecified order.
*
* If filter is provided, it will return only edges with the requested type.
*/
edges(filter?: {|+type?: string|}): Iterator<Edge<any>> {
const _ = filter;
throw new Error("Graphv2 is not yet implemented");
}
addNode(payload: NodePayload): this {
const _ = payload;
throw new Error("Graphv2 is not yet implemented");
}
removeNode(address: Address): this {
const _ = address;
throw new Error("Graphv2 is not yet implemented");
}
addEdge(edge: Edge<any>): this {
const _ = edge;
throw new Error("Graphv2 is not yet implemented");
}
removeEdge(address: Address): this {
const _ = address;
throw new Error("Graphv2 is not yet implemented");
}
/**
* Merge a collection of graphs. If multiple graphs have a node with a
* particular address, then the nodes must all have identical payload,
* and a single copy of this node will be included in the result
* graph; if not all nodes are identical, then an error is thrown.
* Likewise, all edges at a particular address must have identical
* source, destination, and payload.
*
* The existing graph objects are not modified.
*/
static mergeConservative(
plugins: Plugins,
graphs: $ReadOnlyArray<Graph>
): Graph {
const _ = {plugins, graphs};
throw new Error("Graphv2 is not yet implemented");
}
equals(that: Graph): boolean {
const _ = that;
throw new Error("Graphv2 is not yet implemented");
}
copy(): Graph {
throw new Error("Graphv2 is not yet implemented");
}
plugins(): Plugins {
throw new Error("Graphv2 is not yet implemented");
}
static fromJSON(plugins: Plugins, json: Compatible<GraphJSON>): Graph {
const _ = {plugins, json};
throw new Error("Graphv2 is not yet implemented");
}
toJSON(): Compatible<GraphJSON> {
throw new Error("Graphv2 is not yet implemented");
}
}
export type GraphJSON = any;