UNPKG

noflo

Version:

Flow-Based Programming environment for JavaScript

1,246 lines (1,179 loc) 37.8 kB
(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);