diff --git a/src/core2/address_payload_unification_design.md b/src/core2/address_payload_unification_design.md index 3b9d3b2..d168302 100644 --- a/src/core2/address_payload_unification_design.md +++ b/src/core2/address_payload_unification_design.md @@ -118,7 +118,7 @@ type NeighborsOptions = {| |}; type Neighbor<+T: NodeReference> = {| +ref: T, - +edge: Edge, + +edge: Edge, |}; ``` @@ -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: ```javascript -type Edge = {| +type Edge<+T> = {| +address: Address, +src: Address, +dst: Address, - +payload: any, + +payload: T, |}; ``` @@ -357,17 +357,17 @@ declare class Graph /* no type parameters! */ { plugins(): Plugins; addNode(np: NodePayload): this; - addEdge(edge: Edge): this; + addEdge(edge: Edge): this; removeNode(address: Address): this; removeEdge(address: Address): this; node(address: Address): ?Node; - edge(address: Address): ?Edge; + edge(address: Address): ?Edge; ref(address: Address): NodeReference; nodes(filter?: {|+type?: string|}): Iterator>; - edges(filter?: {|+type?: string|}): Iterator; + edges(filter?: {|+type?: string|}): Iterator>; static mergeConservative(Iterable): Graph; diff --git a/src/core2/graph.js b/src/core2/graph.js new file mode 100644 index 0000000..9c2e2ec --- /dev/null +++ b/src/core2/graph.js @@ -0,0 +1,169 @@ +// @flow + +import type {Address} from "./address"; +import type {Compatible} from "../util/compat"; + +export type Node = {| + +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; + + neighbors( + options?: NeighborsOptions + ): Iterator<{|+ref: NodeReference, +edge: Edge|}>; +} + +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 { + /** + * 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>; + +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 { + 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> { + const _ = filter; + throw new Error("Graphv2 is not yet implemented"); + } + + edge(address: Address): Edge { + 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> { + 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): 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 { + 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): Graph { + const _ = {plugins, json}; + throw new Error("Graphv2 is not yet implemented"); + } + + toJSON(): Compatible { + throw new Error("Graphv2 is not yet implemented"); + } +} + +export type GraphJSON = any;