metagraph
Version:
A framework for building higher-order graph data structures
170 lines (165 loc) • 6.23 kB
JavaScript
/*!
* metagraph.js <%= conf.pkg.version %>
* http://gordonwoodhull.github.io/metagraph.js/
* Copyright 2019 AT&T Intellectual Property
*
* Licensed under the MIT License
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
import { map_of_lists, list, singleton, map, input } from './dataflow_calcs.js';
import { lookupKVal, lookupFVal, fetch, lookupArg, call, createable } from './interface.js';
const graph_options = (opts) => Object.assign({
nodeKey: (kv) => kv.key,
edgeKey: (kv) => kv.key,
nodeValue: (kv) => kv.value,
edgeValue: (kv) => kv.value,
edgeSource: (kv) => kv.value.source,
edgeTarget: (kv) => kv.value.target
}, opts || {});
/**
* Creates a standard graph pattern specification for building graph instances.
* Defines the dataflow computation and interface for creating graph objects with nodes and edges.
*
* @param opts - Optional graph options for customizing node/edge accessors
* @returns A pattern specification that can create graph instances
*
* @example
* ```typescript
* // Create a graph pattern and use it to build a graph
* const pat = pattern(graph_pattern());
* const myGraph = pat.node('Graph').value().create({
* nodes: [{key: 'a'}, {key: 'b'}],
* edges: [{key: 'edge', value: {source: 'a', target: 'b'}}]
* });
* ```
*/
const graph_pattern = (opts) => {
const options = graph_options(opts);
return {
dataflow: {
incidences: {
nodes: { node: input() },
edges: { node: input() },
node_by_key: {
node: map(),
refs: 'Node',
ins: 'nodes'
},
edge_by_key: {
node: map(),
refs: 'Edge',
ins: 'edges'
},
graph: { node: singleton() },
node_list: {
node: list(),
refs: 'Node',
ins: ['nodes', 'node_by_key']
},
edge_list: {
node: list(),
refs: 'Edge',
ins: ['edges', 'edge_by_key']
},
node_outs: {
node: map_of_lists(options.edgeSource),
refs: 'Node',
ins: ['edges', 'edge_by_key']
},
node_ins: {
node: map_of_lists(options.edgeTarget),
refs: 'Node',
ins: ['edges', 'edge_by_key']
}
}
},
interface: {
nodes: {
Graph: createable('graph'),
Node: [call('key')(options.nodeKey), call('value')(options.nodeValue)],
Edge: [call('key')(options.edgeKey), call('value')(options.edgeValue)]
},
edges: {
graph_node: {
name: 'node',
source: 'Graph', target: 'Node',
deps: 'node_by_key',
member: lookupArg()
},
node_graph: {
name: 'graph',
source: 'Node', target: 'Graph',
deps: 'graph',
member: fetch()
},
graph_nodes: {
name: 'nodes',
source: 'Graph', target: 'Node',
deps: 'node_list',
member: fetch()
},
graph_edge: {
name: 'edge',
source: 'Graph', target: 'Edge',
deps: 'edge_by_key',
member: lookupArg()
},
edge_graph: {
name: 'graph',
source: 'Edge', target: 'Graph',
deps: 'graph',
member: fetch()
},
graph_edges: {
name: 'edges',
source: 'Graph', target: 'Edge',
deps: 'edge_list',
member: fetch()
},
edge_source: {
name: 'source',
source: 'Edge', target: 'Node',
deps: 'node_by_key',
member: lookupFVal(options.edgeSource)
},
edge_target: {
name: 'target',
source: 'Edge', target: 'Node',
deps: 'node_by_key',
member: lookupFVal(options.edgeTarget)
},
node_outs: {
name: 'outs',
source: 'Node', target: 'Edge',
deps: 'node_outs',
member: lookupKVal()
},
node_ins: {
name: 'ins',
source: 'Node', target: 'Edge',
deps: 'node_ins',
member: lookupKVal()
}
}
}
};
};
export { graph_pattern };
//# sourceMappingURL=graph_pattern.js.map