noflo
Version:
Flow-Based Programming environment for JavaScript
1,246 lines (1,179 loc) • 37.8 kB
JavaScript
(function() {
var EventEmitter, Graph, clone, mergeResolveTheirsNaive, platform, resetGraph,
__hasProp = {}.hasOwnProperty,
__extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
EventEmitter = require('events').EventEmitter;
clone = require('./Utils').clone;
platform = require('./Platform');
Graph = (function(_super) {
__extends(Graph, _super);
Graph.prototype.name = '';
Graph.prototype.properties = {};
Graph.prototype.nodes = [];
Graph.prototype.edges = [];
Graph.prototype.initializers = [];
Graph.prototype.exports = [];
Graph.prototype.inports = {};
Graph.prototype.outports = {};
Graph.prototype.groups = [];
function Graph(name) {
this.name = name != null ? name : '';
this.properties = {};
this.nodes = [];
this.edges = [];
this.initializers = [];
this.exports = [];
this.inports = {};
this.outports = {};
this.groups = [];
this.transaction = {
id: null,
depth: 0
};
}
Graph.prototype.startTransaction = function(id, metadata) {
if (this.transaction.id) {
throw Error("Nested transactions not supported");
}
this.transaction.id = id;
this.transaction.depth = 1;
return this.emit('startTransaction', id, metadata);
};
Graph.prototype.endTransaction = function(id, metadata) {
if (!this.transaction.id) {
throw Error("Attempted to end non-existing transaction");
}
this.transaction.id = null;
this.transaction.depth = 0;
return this.emit('endTransaction', id, metadata);
};
Graph.prototype.checkTransactionStart = function() {
if (!this.transaction.id) {
return this.startTransaction('implicit');
} else if (this.transaction.id === 'implicit') {
return this.transaction.depth += 1;
}
};
Graph.prototype.checkTransactionEnd = function() {
if (this.transaction.id === 'implicit') {
this.transaction.depth -= 1;
}
if (this.transaction.depth === 0) {
return this.endTransaction('implicit');
}
};
Graph.prototype.setProperties = function(properties) {
var before, item, val;
this.checkTransactionStart();
before = clone(this.properties);
for (item in properties) {
val = properties[item];
this.properties[item] = val;
}
this.emit('changeProperties', this.properties, before);
return this.checkTransactionEnd();
};
Graph.prototype.addExport = function(publicPort, nodeKey, portKey, metadata) {
var exported;
if (metadata == null) {
metadata = {
x: 0,
y: 0
};
}
if (!this.getNode(nodeKey)) {
return;
}
this.checkTransactionStart();
exported = {
"public": publicPort.toLowerCase(),
process: nodeKey,
port: portKey.toLowerCase(),
metadata: metadata
};
this.exports.push(exported);
this.emit('addExport', exported);
return this.checkTransactionEnd();
};
Graph.prototype.removeExport = function(publicPort) {
var exported, found, idx, _i, _len, _ref;
publicPort = publicPort.toLowerCase();
found = null;
_ref = this.exports;
for (idx = _i = 0, _len = _ref.length; _i < _len; idx = ++_i) {
exported = _ref[idx];
if (exported["public"] === publicPort) {
found = exported;
}
}
if (!found) {
return;
}
this.checkTransactionStart();
this.exports.splice(this.exports.indexOf(found), 1);
this.emit('removeExport', found);
return this.checkTransactionEnd();
};
Graph.prototype.addInport = function(publicPort, nodeKey, portKey, metadata) {
if (!this.getNode(nodeKey)) {
return;
}
publicPort = publicPort.toLowerCase();
this.checkTransactionStart();
this.inports[publicPort] = {
process: nodeKey,
port: portKey.toLowerCase(),
metadata: metadata
};
this.emit('addInport', publicPort, this.inports[publicPort]);
return this.checkTransactionEnd();
};
Graph.prototype.removeInport = function(publicPort) {
var port;
publicPort = publicPort.toLowerCase();
if (!this.inports[publicPort]) {
return;
}
this.checkTransactionStart();
port = this.inports[publicPort];
this.setInportMetadata(publicPort, {});
delete this.inports[publicPort];
this.emit('removeInport', publicPort, port);
return this.checkTransactionEnd();
};
Graph.prototype.renameInport = function(oldPort, newPort) {
oldPort = oldPort.toLowerCase();
newPort = newPort.toLowerCase();
if (!this.inports[oldPort]) {
return;
}
this.checkTransactionStart();
this.inports[newPort] = this.inports[oldPort];
delete this.inports[oldPort];
this.emit('renameInport', oldPort, newPort);
return this.checkTransactionEnd();
};
Graph.prototype.setInportMetadata = function(publicPort, metadata) {
var before, item, val;
publicPort = publicPort.toLowerCase();
if (!this.inports[publicPort]) {
return;
}
this.checkTransactionStart();
before = clone(this.inports[publicPort].metadata);
if (!this.inports[publicPort].metadata) {
this.inports[publicPort].metadata = {};
}
for (item in metadata) {
val = metadata[item];
if (val != null) {
this.inports[publicPort].metadata[item] = val;
} else {
delete this.inports[publicPort].metadata[item];
}
}
this.emit('changeInport', publicPort, this.inports[publicPort], before);
return this.checkTransactionEnd();
};
Graph.prototype.addOutport = function(publicPort, nodeKey, portKey, metadata) {
if (!this.getNode(nodeKey)) {
return;
}
publicPort = publicPort.toLowerCase();
this.checkTransactionStart();
this.outports[publicPort] = {
process: nodeKey,
port: portKey.toLowerCase(),
metadata: metadata
};
this.emit('addOutport', publicPort, this.outports[publicPort]);
return this.checkTransactionEnd();
};
Graph.prototype.removeOutport = function(publicPort) {
var port;
publicPort = publicPort.toLowerCase();
if (!this.outports[publicPort]) {
return;
}
this.checkTransactionStart();
port = this.outports[publicPort];
this.setOutportMetadata(publicPort, {});
delete this.outports[publicPort];
this.emit('removeOutport', publicPort, port);
return this.checkTransactionEnd();
};
Graph.prototype.renameOutport = function(oldPort, newPort) {
oldPort = oldPort.toLowerCase();
newPort = newPort.toLowerCase();
if (!this.outports[oldPort]) {
return;
}
this.checkTransactionStart();
this.outports[newPort] = this.outports[oldPort];
delete this.outports[oldPort];
this.emit('renameOutport', oldPort, newPort);
return this.checkTransactionEnd();
};
Graph.prototype.setOutportMetadata = function(publicPort, metadata) {
var before, item, val;
publicPort = publicPort.toLowerCase();
if (!this.outports[publicPort]) {
return;
}
this.checkTransactionStart();
before = clone(this.outports[publicPort].metadata);
if (!this.outports[publicPort].metadata) {
this.outports[publicPort].metadata = {};
}
for (item in metadata) {
val = metadata[item];
if (val != null) {
this.outports[publicPort].metadata[item] = val;
} else {
delete this.outports[publicPort].metadata[item];
}
}
this.emit('changeOutport', publicPort, this.outports[publicPort], before);
return this.checkTransactionEnd();
};
Graph.prototype.addGroup = function(group, nodes, metadata) {
var g;
this.checkTransactionStart();
g = {
name: group,
nodes: nodes,
metadata: metadata
};
this.groups.push(g);
this.emit('addGroup', g);
return this.checkTransactionEnd();
};
Graph.prototype.renameGroup = function(oldName, newName) {
var group, _i, _len, _ref;
this.checkTransactionStart();
_ref = this.groups;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
group = _ref[_i];
if (!group) {
continue;
}
if (group.name !== oldName) {
continue;
}
group.name = newName;
this.emit('renameGroup', oldName, newName);
}
return this.checkTransactionEnd();
};
Graph.prototype.removeGroup = function(groupName) {
var group, _i, _len, _ref;
this.checkTransactionStart();
_ref = this.groups;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
group = _ref[_i];
if (!group) {
continue;
}
if (group.name !== groupName) {
continue;
}
this.setGroupMetadata(group.name, {});
this.groups.splice(this.groups.indexOf(group), 1);
this.emit('removeGroup', group);
}
return this.checkTransactionEnd();
};
Graph.prototype.setGroupMetadata = function(groupName, metadata) {
var before, group, item, val, _i, _len, _ref;
this.checkTransactionStart();
_ref = this.groups;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
group = _ref[_i];
if (!group) {
continue;
}
if (group.name !== groupName) {
continue;
}
before = clone(group.metadata);
for (item in metadata) {
val = metadata[item];
if (val != null) {
group.metadata[item] = val;
} else {
delete group.metadata[item];
}
}
this.emit('changeGroup', group, before);
}
return this.checkTransactionEnd();
};
Graph.prototype.addNode = function(id, component, metadata) {
var node;
this.checkTransactionStart();
if (!metadata) {
metadata = {};
}
node = {
id: id,
component: component,
metadata: metadata
};
this.nodes.push(node);
this.emit('addNode', node);
this.checkTransactionEnd();
return node;
};
Graph.prototype.removeNode = function(id) {
var edge, exported, group, index, initializer, node, priv, pub, toRemove, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _len5, _len6, _len7, _len8, _m, _n, _o, _p, _q, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
node = this.getNode(id);
if (!node) {
return;
}
this.checkTransactionStart();
toRemove = [];
_ref = this.edges;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
edge = _ref[_i];
if ((edge.from.node === node.id) || (edge.to.node === node.id)) {
toRemove.push(edge);
}
}
for (_j = 0, _len1 = toRemove.length; _j < _len1; _j++) {
edge = toRemove[_j];
this.removeEdge(edge.from.node, edge.from.port, edge.to.node, edge.to.port);
}
toRemove = [];
_ref1 = this.initializers;
for (_k = 0, _len2 = _ref1.length; _k < _len2; _k++) {
initializer = _ref1[_k];
if (initializer.to.node === node.id) {
toRemove.push(initializer);
}
}
for (_l = 0, _len3 = toRemove.length; _l < _len3; _l++) {
initializer = toRemove[_l];
this.removeInitial(initializer.to.node, initializer.to.port);
}
toRemove = [];
_ref2 = this.exports;
for (_m = 0, _len4 = _ref2.length; _m < _len4; _m++) {
exported = _ref2[_m];
if (id.toLowerCase() === exported.process) {
toRemove.push(exported);
}
}
for (_n = 0, _len5 = toRemove.length; _n < _len5; _n++) {
exported = toRemove[_n];
this.removeExport(exported["public"]);
}
toRemove = [];
_ref3 = this.inports;
for (pub in _ref3) {
priv = _ref3[pub];
if (priv.process === id) {
toRemove.push(pub);
}
}
for (_o = 0, _len6 = toRemove.length; _o < _len6; _o++) {
pub = toRemove[_o];
this.removeInport(pub);
}
toRemove = [];
_ref4 = this.outports;
for (pub in _ref4) {
priv = _ref4[pub];
if (priv.process === id) {
toRemove.push(pub);
}
}
for (_p = 0, _len7 = toRemove.length; _p < _len7; _p++) {
pub = toRemove[_p];
this.removeOutport(pub);
}
_ref5 = this.groups;
for (_q = 0, _len8 = _ref5.length; _q < _len8; _q++) {
group = _ref5[_q];
if (!group) {
continue;
}
index = group.nodes.indexOf(id);
if (index === -1) {
continue;
}
group.nodes.splice(index, 1);
}
this.setNodeMetadata(id, {});
if (-1 !== this.nodes.indexOf(node)) {
this.nodes.splice(this.nodes.indexOf(node), 1);
}
this.emit('removeNode', node);
return this.checkTransactionEnd();
};
Graph.prototype.getNode = function(id) {
var node, _i, _len, _ref;
_ref = this.nodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
if (!node) {
continue;
}
if (node.id === id) {
return node;
}
}
return null;
};
Graph.prototype.renameNode = function(oldId, newId) {
var edge, exported, group, iip, index, node, priv, pub, _i, _j, _k, _l, _len, _len1, _len2, _len3, _ref, _ref1, _ref2, _ref3, _ref4, _ref5;
this.checkTransactionStart();
node = this.getNode(oldId);
if (!node) {
return;
}
node.id = newId;
_ref = this.edges;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
edge = _ref[_i];
if (!edge) {
continue;
}
if (edge.from.node === oldId) {
edge.from.node = newId;
}
if (edge.to.node === oldId) {
edge.to.node = newId;
}
}
_ref1 = this.initializers;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
iip = _ref1[_j];
if (!iip) {
continue;
}
if (iip.to.node === oldId) {
iip.to.node = newId;
}
}
_ref2 = this.inports;
for (pub in _ref2) {
priv = _ref2[pub];
if (priv.process === oldId) {
priv.process = newId;
}
}
_ref3 = this.outports;
for (pub in _ref3) {
priv = _ref3[pub];
if (priv.process === oldId) {
priv.process = newId;
}
}
_ref4 = this.exports;
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
exported = _ref4[_k];
if (exported.process === oldId) {
exported.process = newId;
}
}
_ref5 = this.groups;
for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
group = _ref5[_l];
if (!group) {
continue;
}
index = group.nodes.indexOf(oldId);
if (index === -1) {
continue;
}
group.nodes[index] = newId;
}
this.emit('renameNode', oldId, newId);
return this.checkTransactionEnd();
};
Graph.prototype.setNodeMetadata = function(id, metadata) {
var before, item, node, val;
node = this.getNode(id);
if (!node) {
return;
}
this.checkTransactionStart();
before = clone(node.metadata);
if (!node.metadata) {
node.metadata = {};
}
for (item in metadata) {
val = metadata[item];
if (val != null) {
node.metadata[item] = val;
} else {
delete node.metadata[item];
}
}
this.emit('changeNode', node, before);
return this.checkTransactionEnd();
};
Graph.prototype.addEdge = function(outNode, outPort, inNode, inPort, metadata) {
var edge, _i, _len, _ref;
if (metadata == null) {
metadata = {};
}
outPort = outPort.toLowerCase();
inPort = inPort.toLowerCase();
_ref = this.edges;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
edge = _ref[_i];
if (edge.from.node === outNode && edge.from.port === outPort && edge.to.node === inNode && edge.to.port === inPort) {
return;
}
}
if (!this.getNode(outNode)) {
return;
}
if (!this.getNode(inNode)) {
return;
}
this.checkTransactionStart();
edge = {
from: {
node: outNode,
port: outPort
},
to: {
node: inNode,
port: inPort
},
metadata: metadata
};
this.edges.push(edge);
this.emit('addEdge', edge);
this.checkTransactionEnd();
return edge;
};
Graph.prototype.addEdgeIndex = function(outNode, outPort, outIndex, inNode, inPort, inIndex, metadata) {
var edge;
if (metadata == null) {
metadata = {};
}
if (!this.getNode(outNode)) {
return;
}
if (!this.getNode(inNode)) {
return;
}
outPort = outPort.toLowerCase();
inPort = inPort.toLowerCase();
if (inIndex === null) {
inIndex = void 0;
}
if (outIndex === null) {
outIndex = void 0;
}
if (!metadata) {
metadata = {};
}
this.checkTransactionStart();
edge = {
from: {
node: outNode,
port: outPort,
index: outIndex
},
to: {
node: inNode,
port: inPort,
index: inIndex
},
metadata: metadata
};
this.edges.push(edge);
this.emit('addEdge', edge);
this.checkTransactionEnd();
return edge;
};
Graph.prototype.removeEdge = function(node, port, node2, port2) {
var edge, index, toKeep, toRemove, _i, _j, _k, _len, _len1, _len2, _ref, _ref1;
this.checkTransactionStart();
port = port.toLowerCase();
port2 = port2.toLowerCase();
toRemove = [];
toKeep = [];
if (node2 && port2) {
_ref = this.edges;
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
edge = _ref[index];
if (edge.from.node === node && edge.from.port === port && edge.to.node === node2 && edge.to.port === port2) {
this.setEdgeMetadata(edge.from.node, edge.from.port, edge.to.node, edge.to.port, {});
toRemove.push(edge);
} else {
toKeep.push(edge);
}
}
} else {
_ref1 = this.edges;
for (index = _j = 0, _len1 = _ref1.length; _j < _len1; index = ++_j) {
edge = _ref1[index];
if ((edge.from.node === node && edge.from.port === port) || (edge.to.node === node && edge.to.port === port)) {
this.setEdgeMetadata(edge.from.node, edge.from.port, edge.to.node, edge.to.port, {});
toRemove.push(edge);
} else {
toKeep.push(edge);
}
}
}
this.edges = toKeep;
for (_k = 0, _len2 = toRemove.length; _k < _len2; _k++) {
edge = toRemove[_k];
this.emit('removeEdge', edge);
}
return this.checkTransactionEnd();
};
Graph.prototype.getEdge = function(node, port, node2, port2) {
var edge, index, _i, _len, _ref;
port = port.toLowerCase();
port2 = port2.toLowerCase();
_ref = this.edges;
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
edge = _ref[index];
if (!edge) {
continue;
}
if (edge.from.node === node && edge.from.port === port) {
if (edge.to.node === node2 && edge.to.port === port2) {
return edge;
}
}
}
return null;
};
Graph.prototype.setEdgeMetadata = function(node, port, node2, port2, metadata) {
var before, edge, item, val;
edge = this.getEdge(node, port, node2, port2);
if (!edge) {
return;
}
this.checkTransactionStart();
before = clone(edge.metadata);
if (!edge.metadata) {
edge.metadata = {};
}
for (item in metadata) {
val = metadata[item];
if (val != null) {
edge.metadata[item] = val;
} else {
delete edge.metadata[item];
}
}
this.emit('changeEdge', edge, before);
return this.checkTransactionEnd();
};
Graph.prototype.addInitial = function(data, node, port, metadata) {
var initializer;
if (!this.getNode(node)) {
return;
}
port = port.toLowerCase();
this.checkTransactionStart();
initializer = {
from: {
data: data
},
to: {
node: node,
port: port
},
metadata: metadata
};
this.initializers.push(initializer);
this.emit('addInitial', initializer);
this.checkTransactionEnd();
return initializer;
};
Graph.prototype.addInitialIndex = function(data, node, port, index, metadata) {
var initializer;
if (!this.getNode(node)) {
return;
}
if (index === null) {
index = void 0;
}
port = port.toLowerCase();
this.checkTransactionStart();
initializer = {
from: {
data: data
},
to: {
node: node,
port: port,
index: index
},
metadata: metadata
};
this.initializers.push(initializer);
this.emit('addInitial', initializer);
this.checkTransactionEnd();
return initializer;
};
Graph.prototype.addGraphInitial = function(data, node, metadata) {
var inport;
inport = this.inports[node];
if (!inport) {
return;
}
return this.addInitial(data, inport.process, inport.port, metadata);
};
Graph.prototype.addGraphInitialIndex = function(data, node, index, metadata) {
var inport;
inport = this.inports[node];
if (!inport) {
return;
}
return this.addInitialIndex(data, inport.process, inport.port, index, metadata);
};
Graph.prototype.removeInitial = function(node, port) {
var edge, index, toKeep, toRemove, _i, _j, _len, _len1, _ref;
port = port.toLowerCase();
this.checkTransactionStart();
toRemove = [];
toKeep = [];
_ref = this.initializers;
for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
edge = _ref[index];
if (edge.to.node === node && edge.to.port === port) {
toRemove.push(edge);
} else {
toKeep.push(edge);
}
}
this.initializers = toKeep;
for (_j = 0, _len1 = toRemove.length; _j < _len1; _j++) {
edge = toRemove[_j];
this.emit('removeInitial', edge);
}
return this.checkTransactionEnd();
};
Graph.prototype.removeGraphInitial = function(node) {
var inport;
inport = this.inports[node];
if (!inport) {
return;
}
return this.removeInitial(inport.process, inport.port);
};
Graph.prototype.toDOT = function() {
var cleanID, cleanPort, data, dot, edge, id, initializer, node, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2;
cleanID = function(id) {
return id.replace(/\s*/g, "");
};
cleanPort = function(port) {
return port.replace(/\./g, "");
};
dot = "digraph {\n";
_ref = this.nodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
dot += " " + (cleanID(node.id)) + " [label=" + node.id + " shape=box]\n";
}
_ref1 = this.initializers;
for (id = _j = 0, _len1 = _ref1.length; _j < _len1; id = ++_j) {
initializer = _ref1[id];
if (typeof initializer.from.data === 'function') {
data = 'Function';
} else {
data = initializer.from.data;
}
dot += " data" + id + " [label=\"'" + data + "'\" shape=plaintext]\n";
dot += " data" + id + " -> " + (cleanID(initializer.to.node)) + "[headlabel=" + (cleanPort(initializer.to.port)) + " labelfontcolor=blue labelfontsize=8.0]\n";
}
_ref2 = this.edges;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
edge = _ref2[_k];
dot += " " + (cleanID(edge.from.node)) + " -> " + (cleanID(edge.to.node)) + "[taillabel=" + (cleanPort(edge.from.port)) + " headlabel=" + (cleanPort(edge.to.port)) + " labelfontcolor=blue labelfontsize=8.0]\n";
}
dot += "}";
return dot;
};
Graph.prototype.toYUML = function() {
var edge, initializer, yuml, _i, _j, _len, _len1, _ref, _ref1;
yuml = [];
_ref = this.initializers;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
initializer = _ref[_i];
yuml.push("(start)[" + initializer.to.port + "]->(" + initializer.to.node + ")");
}
_ref1 = this.edges;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
edge = _ref1[_j];
yuml.push("(" + edge.from.node + ")[" + edge.from.port + "]->(" + edge.to.node + ")");
}
return yuml.join(",");
};
Graph.prototype.toJSON = function() {
var connection, edge, exported, group, groupData, initializer, json, node, priv, property, pub, value, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _ref7;
json = {
properties: {},
inports: {},
outports: {},
groups: [],
processes: {},
connections: []
};
if (this.name) {
json.properties.name = this.name;
}
_ref = this.properties;
for (property in _ref) {
value = _ref[property];
json.properties[property] = value;
}
_ref1 = this.inports;
for (pub in _ref1) {
priv = _ref1[pub];
json.inports[pub] = priv;
}
_ref2 = this.outports;
for (pub in _ref2) {
priv = _ref2[pub];
json.outports[pub] = priv;
}
_ref3 = this.exports;
for (_i = 0, _len = _ref3.length; _i < _len; _i++) {
exported = _ref3[_i];
if (!json.exports) {
json.exports = [];
}
json.exports.push(exported);
}
_ref4 = this.groups;
for (_j = 0, _len1 = _ref4.length; _j < _len1; _j++) {
group = _ref4[_j];
groupData = {
name: group.name,
nodes: group.nodes
};
if (Object.keys(group.metadata).length) {
groupData.metadata = group.metadata;
}
json.groups.push(groupData);
}
_ref5 = this.nodes;
for (_k = 0, _len2 = _ref5.length; _k < _len2; _k++) {
node = _ref5[_k];
json.processes[node.id] = {
component: node.component
};
if (node.metadata) {
json.processes[node.id].metadata = node.metadata;
}
}
_ref6 = this.edges;
for (_l = 0, _len3 = _ref6.length; _l < _len3; _l++) {
edge = _ref6[_l];
connection = {
src: {
process: edge.from.node,
port: edge.from.port,
index: edge.from.index
},
tgt: {
process: edge.to.node,
port: edge.to.port,
index: edge.to.index
}
};
if (Object.keys(edge.metadata).length) {
connection.metadata = edge.metadata;
}
json.connections.push(connection);
}
_ref7 = this.initializers;
for (_m = 0, _len4 = _ref7.length; _m < _len4; _m++) {
initializer = _ref7[_m];
json.connections.push({
data: initializer.from.data,
tgt: {
process: initializer.to.node,
port: initializer.to.port,
index: initializer.to.index
}
});
}
return json;
};
Graph.prototype.save = function(file, callback) {
var json;
json = JSON.stringify(this.toJSON(), null, 4);
return require('fs').writeFile("" + file + ".json", json, "utf-8", function(err, data) {
if (err) {
throw err;
}
return callback(file);
});
};
return Graph;
})(EventEmitter);
exports.Graph = Graph;
exports.createGraph = function(name) {
return new Graph(name);
};
exports.loadJSON = function(definition, callback, metadata) {
var conn, def, exported, graph, group, id, portId, priv, processId, properties, property, pub, split, value, _i, _j, _k, _len, _len1, _len2, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6;
if (metadata == null) {
metadata = {};
}
if (typeof definition === 'string') {
definition = JSON.parse(definition);
}
if (!definition.properties) {
definition.properties = {};
}
if (!definition.processes) {
definition.processes = {};
}
if (!definition.connections) {
definition.connections = [];
}
graph = new Graph(definition.properties.name);
graph.startTransaction('loadJSON', metadata);
properties = {};
_ref = definition.properties;
for (property in _ref) {
value = _ref[property];
if (property === 'name') {
continue;
}
properties[property] = value;
}
graph.setProperties(properties);
_ref1 = definition.processes;
for (id in _ref1) {
def = _ref1[id];
if (!def.metadata) {
def.metadata = {};
}
graph.addNode(id, def.component, def.metadata);
}
_ref2 = definition.connections;
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
conn = _ref2[_i];
metadata = conn.metadata ? conn.metadata : {};
if (conn.data !== void 0) {
if (typeof conn.tgt.index === 'number') {
graph.addInitialIndex(conn.data, conn.tgt.process, conn.tgt.port.toLowerCase(), conn.tgt.index, metadata);
} else {
graph.addInitial(conn.data, conn.tgt.process, conn.tgt.port.toLowerCase(), metadata);
}
continue;
}
if (typeof conn.src.index === 'number' || typeof conn.tgt.index === 'number') {
graph.addEdgeIndex(conn.src.process, conn.src.port.toLowerCase(), conn.src.index, conn.tgt.process, conn.tgt.port.toLowerCase(), conn.tgt.index, metadata);
continue;
}
graph.addEdge(conn.src.process, conn.src.port.toLowerCase(), conn.tgt.process, conn.tgt.port.toLowerCase(), metadata);
}
if (definition.exports && definition.exports.length) {
_ref3 = definition.exports;
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
exported = _ref3[_j];
if (exported["private"]) {
split = exported["private"].split('.');
if (split.length !== 2) {
continue;
}
processId = split[0];
portId = split[1];
for (id in definition.processes) {
if (id.toLowerCase() === processId.toLowerCase()) {
processId = id;
}
}
} else {
processId = exported.process;
portId = exported.port.toLowerCase();
}
graph.addExport(exported["public"], processId, portId, exported.metadata);
}
}
if (definition.inports) {
_ref4 = definition.inports;
for (pub in _ref4) {
priv = _ref4[pub];
graph.addInport(pub, priv.process, priv.port.toLowerCase(), priv.metadata);
}
}
if (definition.outports) {
_ref5 = definition.outports;
for (pub in _ref5) {
priv = _ref5[pub];
graph.addOutport(pub, priv.process, priv.port.toLowerCase(), priv.metadata);
}
}
if (definition.groups) {
_ref6 = definition.groups;
for (_k = 0, _len2 = _ref6.length; _k < _len2; _k++) {
group = _ref6[_k];
graph.addGroup(group.name, group.nodes, group.metadata || {});
}
}
graph.endTransaction('loadJSON');
return callback(null, graph);
};
exports.loadFBP = function(fbpData, callback) {
var definition, e;
try {
definition = require('fbp').parse(fbpData);
} catch (_error) {
e = _error;
return callback(e);
}
return exports.loadJSON(definition, callback);
};
exports.loadHTTP = function(url, callback) {
var req;
req = new XMLHttpRequest;
req.onreadystatechange = function() {
if (req.readyState !== 4) {
return;
}
if (req.status !== 200) {
return callback(new Error("Failed to load " + url + ": HTTP " + req.status));
}
return callback(null, req.responseText);
};
req.open('GET', url, true);
return req.send();
};
exports.loadFile = function(file, callback, metadata) {
var definition, e;
if (metadata == null) {
metadata = {};
}
if (platform.isBrowser()) {
try {
definition = require(file);
} catch (_error) {
e = _error;
exports.loadHTTP(file, function(err, data) {
if (err) {
return callback(err);
}
if (file.split('.').pop() === 'fbp') {
return exports.loadFBP(data, callback, metadata);
}
definition = JSON.parse(data);
return exports.loadJSON(definition, callback, metadata);
});
return;
}
exports.loadJSON(definition, callback, metadata);
return;
}
return require('fs').readFile(file, "utf-8", function(err, data) {
if (err) {
return callback(err);
}
if (file.split('.').pop() === 'fbp') {
return exports.loadFBP(data, callback);
}
definition = JSON.parse(data);
return exports.loadJSON(definition, callback);
});
};
resetGraph = function(graph) {
var edge, exp, group, iip, node, port, v, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _results;
_ref = (clone(graph.groups)).reverse();
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
group = _ref[_i];
if (group != null) {
graph.removeGroup(group.name);
}
}
_ref1 = clone(graph.outports);
for (port in _ref1) {
v = _ref1[port];
graph.removeOutport(port);
}
_ref2 = clone(graph.inports);
for (port in _ref2) {
v = _ref2[port];
graph.removeInport(port);
}
_ref3 = clone(graph.exports.reverse());
for (_j = 0, _len1 = _ref3.length; _j < _len1; _j++) {
exp = _ref3[_j];
graph.removeExport(exp["public"]);
}
graph.setProperties({});
_ref4 = (clone(graph.initializers)).reverse();
for (_k = 0, _len2 = _ref4.length; _k < _len2; _k++) {
iip = _ref4[_k];
graph.removeInitial(iip.to.node, iip.to.port);
}
_ref5 = (clone(graph.edges)).reverse();
for (_l = 0, _len3 = _ref5.length; _l < _len3; _l++) {
edge = _ref5[_l];
graph.removeEdge(edge.from.node, edge.from.port, edge.to.node, edge.to.port);
}
_ref6 = (clone(graph.nodes)).reverse();
_results = [];
for (_m = 0, _len4 = _ref6.length; _m < _len4; _m++) {
node = _ref6[_m];
_results.push(graph.removeNode(node.id));
}
return _results;
};
mergeResolveTheirsNaive = function(base, to) {
var edge, exp, group, iip, node, priv, pub, _i, _j, _k, _l, _len, _len1, _len2, _len3, _len4, _m, _ref, _ref1, _ref2, _ref3, _ref4, _ref5, _ref6, _results;
resetGraph(base);
_ref = to.nodes;
for (_i = 0, _len = _ref.length; _i < _len; _i++) {
node = _ref[_i];
base.addNode(node.id, node.component, node.metadata);
}
_ref1 = to.edges;
for (_j = 0, _len1 = _ref1.length; _j < _len1; _j++) {
edge = _ref1[_j];
base.addEdge(edge.from.node, edge.from.port, edge.to.node, edge.to.port, edge.metadata);
}
_ref2 = to.initializers;
for (_k = 0, _len2 = _ref2.length; _k < _len2; _k++) {
iip = _ref2[_k];
base.addInitial(iip.from.data, iip.to.node, iip.to.port, iip.metadata);
}
_ref3 = to.exports;
for (_l = 0, _len3 = _ref3.length; _l < _len3; _l++) {
exp = _ref3[_l];
base.addExport(exp["public"], exp.node, exp.port, exp.metadata);
}
base.setProperties(to.properties);
_ref4 = to.inports;
for (pub in _ref4) {
priv = _ref4[pub];
base.addInport(pub, priv.process, priv.port, priv.metadata);
}
_ref5 = to.outports;
for (pub in _ref5) {
priv = _ref5[pub];
base.addOutport(pub, priv.process, priv.port, priv.metadata);
}
_ref6 = to.groups;
_results = [];
for (_m = 0, _len4 = _ref6.length; _m < _len4; _m++) {
group = _ref6[_m];
_results.push(base.addGroup(group.name, group.nodes, group.metadata));
}
return _results;
};
exports.equivalent = function(a, b, options) {
var A, B;
if (options == null) {
options = {};
}
A = JSON.stringify(a);
B = JSON.stringify(b);
return A === B;
};
exports.mergeResolveTheirs = mergeResolveTheirsNaive;
}).call(this);