jsongraph
Version:
powerful minimalist graph/dataflow programming based on jsonschema references (nodejs/coffeescript)
174 lines (169 loc) • 5.1 kB
JavaScript
// Generated by CoffeeScript 1.9.3
(function() {
var clone, jref;
jref = require('json-ref-lite');
clone = function(obj) {
return JSON.parse(JSON.stringify(obj));
};
module.exports = (function(jg) {
jg.graph = false;
jg.filters = {
global: {}
};
jg.bindings = [];
jg.types = {};
jg.parsers = {};
jg.opts = {
verbose: 0,
maxrecurse: 1,
halt: function(node, data, processed) {
if ((node.processed != null) && node.processed === this.maxrecurse) {
return true;
}
if (data == null) {
return true;
}
return false;
}
};
jg.bind = function(nodenames, cb) {
return this.bindings.push({
nodenames: nodenames,
process: cb
});
};
jg.register = function(type, cb) {
return this.types[type] = cb;
};
jg.evaluate = function(data, opts) {
var g, i, len, parser, parsers;
g = ((opts != null ? opts.graph : void 0) != null ? opts.graph : jg.graph);
g = clone(g);
parsers = ((opts != null ? opts.parsers : void 0) ? opts.parsers : ['expr', 'ref']);
for (i = 0, len = parsers.length; i < len; i++) {
parser = parsers[i];
if (jg.parsers[parser] != null) {
jg.parsers[parser](g, data);
}
}
if ((opts != null ? opts.graph : void 0) == null) {
jg.graph = g;
}
return g;
};
jg._run = function(node, data, cb) {
var _, err, process, result;
_ = this.opts;
if ((node != null) && !_.halt(node, data)) {
try {
if (this.opts.verbose > 1) {
console.log("[ " + node.name + " ]\n ├ input : " + JSON.stringify(data));
}
process = cb = (cb != null ? cb : function(node, data, next) {
return next(node, data);
});
if ((node.type != null) && (jg.types[node.type] != null)) {
process = function(node, data, next) {
return jg.types[node.type](node, data, function() {
return cb(node, data, next);
});
};
}
return result = process(node, data, function(node, data) {
var filter, filtername, i, len, o, ref, ref1, results;
ref = jg.filters.global;
for (filtername in ref) {
filter = ref[filtername];
filter(node, data);
}
if (jg.opts.verbose > 1) {
console.log(" ├ output: " + JSON.stringify(data));
}
node.processed = (node.processed == null ? 1 : ++node.processed);
if (node["$ref"] != null) {
ref1 = node["$ref"];
results = [];
for (i = 0, len = ref1.length; i < len; i++) {
o = ref1[i];
results.push(jg._run(o, clone(data), cb));
}
return results;
}
});
} catch (_error) {
err = _error;
if (err === "flow-stop") {
return;
}
throw err;
}
}
};
jg.run = function(startnode, data, cb) {
var graph, name, node, ref, ref1;
if (typeof startnode !== 'string' || typeof data !== 'object') {
throw 'invalid args';
}
graph = jref.resolve(clone(jg.graph));
ref = graph.graph;
for (name in ref) {
node = ref[name];
node.name = name;
}
if ((graph != null ? (ref1 = graph.graph) != null ? ref1[startnode] : void 0 : void 0) == null) {
throw 'node "' + startnode + '" not found';
}
return jg._run(graph.graph[startnode], data, cb);
};
jg.utils = {
dump: function() {
return console.log(JSON.stringify(this.get(), null, 2));
},
get: function(nodename) {
if (nodename == null) {
return jg.graph;
}
return (jg.graph.graph[nodename] != null ? jg.graph.graph[nodename] : null);
},
set: function(name, node) {
jg.graph.graph[name] = (node == null ? {
name: name
} : node);
return jg.graph.graph[name];
},
link: function(a, b) {
var graph;
graph = jg.graph.graph;
if (typeof a !== "object" && (graph[a] != null)) {
a = graph[a];
}
if (typeof b !== "object" && (graph[b] != null)) {
b = graph[b];
}
if (a["$ref"] == null) {
a["$ref"] = [];
}
return a["$ref"].push(b);
},
run: jg.run,
evaluate: jg.evaluate
};
jg.init = function(graph) {
if (typeof graph !== 'object' || (graph.graph == null)) {
throw 'invalid args';
}
this.graph = graph;
return this.utils;
};
jg.parsers.ref = function(graph, data) {
graph.data = data;
jref.resolve(graph);
delete graph.data;
return graph;
};
jg.parsers.expr = function(graph, data) {
return jref.evaluate(graph, data);
};
return jg;
})({});
}).call(this);