metagraph
Version:
A framework for building higher-order graph data structures
100 lines (95 loc) • 3.52 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 { isDataflowInstance } from './types.js';
import { graph_detect } from './graph.js';
class DataflowInstanceImpl {
constructor(flowgraph, instance, inputs) {
this.flowgraph = flowgraph;
this.instance = instance;
this.inputs = inputs;
this._yes_i_am_really_dataflow = true;
}
calc(id) {
if (!this.instance[id]) {
const n = this.flowgraph.node(id);
if (!n) {
throw new Error(`Node ${id} not found in dataflow graph`);
}
const nodeValue = n.value();
this.instance[id] = nodeValue.calc(this).apply(null, n.ins().map((e) => {
return this.calc(e.source().key());
}));
console.assert(this.instance[id]);
}
return this.instance[id];
}
input(namespace, field) {
const input = this.inputs[namespace];
if (input && isDataflowInstance(input)) {
return input.calc(field);
}
else if (input && typeof input === 'object') {
return input[field];
}
return undefined;
}
}
class DataflowImpl {
constructor(spec, options) {
this.flowgraph = graph_detect(spec, options);
}
instantiate(instance, inputs) {
return new DataflowInstanceImpl(this.flowgraph, instance, inputs);
}
}
/**
* Creates a dataflow computation graph for lazy evaluation of dependent calculations.
* Nodes represent computations and edges represent data dependencies.
*
* @param spec - Graph specification defining the computation nodes and their dependencies
* @param options - Optional configuration for graph format
* @returns A dataflow instance that can be instantiated with input data
*
* @example
* ```typescript
* const flow = dataflow({
* nodes: [
* {key: 'a'},
* {key: 'sum', calc: (flow) => (a, b) => a + b}
* ],
* edges: [
* {key: 'dep', value: {source: 'a', target: 'sum'}}
* ]
* });
* const instance = flow.instantiate({sum: 10}, {a: 5});
* console.log(instance.calc('sum')); // 15
* ```
*/
function dataflow(spec, options) {
return new DataflowImpl(spec, options);
}
export { dataflow };
//# sourceMappingURL=dataflow.js.map