require('total.js').http('debug'); | |
var util = require('util'); | |
var EventEmitter = require('events'); | |
// jen na test | |
var WSCONTROLLER = { | |
send: function(data){ console.log(data)} | |
} | |
// instance aktivních komponent | |
global.COMPONENTS = {}; | |
function VisualFlow() { | |
var self = this; | |
// registrované komponenty z kterých se vytvářejí jednotlivé instance | |
self.components = {}; | |
return self; | |
} | |
VisualFlow.prototype.registerComponent = function(name, fn) { | |
var self = this; | |
self.components[name] = fn; | |
return self; | |
}; | |
VisualFlow.prototype.getComponent = function(name) { | |
return this.components[name]; | |
}; | |
// při změně v designéru zavoláme u všech komponent událost `close`, např. hhtpcomponent odstraní routu | |
VisualFlow.prototype.reset = function(name) { | |
Object.keys(COMPONENTS).forEach(function(comp) { | |
COMPONENTS[comp].emit('close'); | |
}); | |
COMPONENTS = {}; | |
}; | |
// při změně v designéru vytvoříme instance všech komponent | |
VisualFlow.prototype.instantiateComponents = function(components) { | |
var self = this; | |
// možná to bude chtít timeout???? | |
self.reset(); | |
if(!components || !components.length) return; | |
components.forEach(function(comp) { | |
// tohle by se mělo asi dělat už v designéru, name se zobrazí jako vlastní popis komponenty | |
if (comp.name === '') | |
comp.name = comp.component; | |
var c = self.getComponent(comp.component); | |
if(!c) return WSCONTROLLER.send({ target: 'debugwindow', type: 'error', msg: 'Unknown component:' + comp.component }); | |
COMPONENTS[comp.id] = c.call(new Component(comp)); | |
}); | |
}; | |
global.VISUALFLOW = global.VF = new VisualFlow(); | |
// | |
function Component(config) { | |
var self = this; | |
U.extend(self, config); | |
} | |
util.inherits(Component, EventEmitter); | |
Component.prototype.send = function(msg) { | |
// pokud je msg Array a položky v connections taky tak se každá položka z msg posílá na jiný výstup | |
// connections by mělo vypadat nějak takhle | |
// [ ['id1', id2], ['id3'], ['id4']] | |
// a msg [{...}, {...}, {...}] | |
// takže např. msg[0] se pošle do komponenty id1 a id2 | |
// msg[1] se pošle do komponenty id3 | |
// msg[2] se pošle do komponenty id4 | |
var isArray = msg instanceof Array; | |
var connections = this.connections || []; | |
if (connections.length) { | |
for (var i = 0; i < connections.length; i++) { | |
var w = connections[i]; | |
if (w instanceof Array && isArray) { | |
for (var j = 0; j < w.length; i++) { | |
var m = msg[j]; | |
//if (!(m instanceof Message)) m = new Message(m); | |
COMPONENTS[w[j]].emit('msg', m); | |
} | |
} else { | |
//if (!(msg instanceof Message)) msg = new Message(msg); | |
COMPONENTS[w].emit('msg', msg); | |
} | |
} | |
} | |
}; | |
/* | |
pro odesílání statusu do designéru | |
např. u websocket(nebo mqtt) klienta, jestli je připojen nebo ne | |
*/ | |
Component.prototype.status = function(status) { | |
// odešle status přes websocket do designéru | |
// např. -> status === {text: 'Connected', color: 'green'} | |
WSCONTROLLER.send({ target: this.id, type: 'status', msg: status }); | |
return this; | |
}; | |
/* | |
pro odesílání erroru do debug okna v designéru | |
*/ | |
Component.prototype.error = function(error) { | |
// odešle error přes websocket do designéru | |
WSCONTROLLER.send({ target: 'debugwindow', type: 'error', msg: error }); | |
return this; | |
}; | |
/* | |
pro odesílání `msg` do debug okna v designéru | |
*/ | |
Component.prototype.debug = function(msg) { | |
// odešle error přes websocket do designéru | |
WSCONTROLLER.send({ target: 'debugwindow', type: 'debug', msg: msg }); | |
return this; | |
}; | |
// function Message(m) { | |
// var msg = {}; | |
// msg.id = UID(); | |
// console.log('MSG', m); | |
// // if(typeof m === 'object') | |
// // U.extend(msg, m); | |
// // else | |
// msg.payload = m; | |
// return msg; | |
// } | |
// definice komponenty - hhtp route | |
function httpcomponent() { | |
var self = this; | |
if (!self.conf.url || self.conf.url === '') | |
return self.error('httpcomponent-error-no-url-provided'); | |
var flags = [self.conf.method.toLowerCase()].concat(self.conf.flags || []); | |
F.route(self.conf.url, function() { | |
console.log('Incomming request'); | |
self.send({ controller: this }); | |
}, flags); | |
// při změně v designéru je potřeba odstranit routu | |
self.on('close', function() { | |
F.routes.web.forEach(function(route, i, routes) { | |
if (route.name === self.conf.url && route.method === self.conf.method) | |
routes.splice(i, 1); | |
}); | |
Object.keys(F.temporary.other).forEach(function(key) { | |
if (key.startsWith('#' + self.conf.url) || key === self.conf.url) { | |
delete F.temporary.other[key]; | |
} | |
}); | |
}); | |
return self; | |
} | |
VISUALFLOW.registerComponent('http', httpcomponent); | |
// definice komponenty - http response | |
function httpresponsecomponent() { | |
var self = this; | |
self.on('msg', function(msg) { | |
console.log('Responding to request'); | |
msg.controller.json(msg.payload); | |
}); | |
return self; | |
} | |
VISUALFLOW.registerComponent('httpresponse', httpresponsecomponent); | |
// definice komponenty - funkce | |
function functioncomponent(conf) { | |
var self = this; | |
self.on('msg', function(msg) { | |
console.log('Funkce'); | |
msg = self.conf.fn(msg); | |
self.send(msg); | |
}); | |
return self; | |
} | |
VISUALFLOW.registerComponent('function', functioncomponent); | |
// definice komponenty - debug | |
function debugcomponent(conf) { | |
var self = this; | |
self.on('msg', function(msg) { | |
console.log('DEBUG', msg.payload); | |
self.debug(msg); | |
}); | |
return self; | |
} | |
VISUALFLOW.registerComponent('debug', debugcomponent); | |
// data z designéru - mohli by se ukládat do DB nebo jen do souboru components.json a načítali by se po (re)startu | |
VISUALFLOW.instantiateComponents([ | |
{ | |
component: 'http', | |
name: 'Incomming HTTP request', | |
id: '1', | |
connections: ['3', '4'], // id komponent kam se má dál poslat msg | |
conf: { | |
url: '/test', // config z designéru | |
method: 'GET' // config z designéru | |
} | |
}, | |
{ | |
component: 'debug', | |
name: 'Debug', | |
id: '4', | |
connections: [] | |
}, | |
{ | |
component: 'httpresponse', | |
name: 'HTTP response', | |
id: '2', | |
connections: [] | |
}, | |
{ | |
component: 'function', | |
name: 'Set "hello" to payload', | |
id: '3', | |
connections: ['2'], | |
conf: { | |
fn: function(msg) { msg.payload = 'Hello'; | |
return msg; } // config z designéru - fn je funkce napsaná v designéru byl by to string, který by se musel `eval` ale na zkoušku to je takhle | |
} | |
} | |
]); | |
// http komponenta při requestu pošle controller dál jako msg.controller, připojený komponenty jsou `funkce` a `debug` | |
// z komponenty `funkce` jdou data dál do komponenty `httpresponse` | |
// funkce - httpresponse | |
// / | |
// http | |
// \ | |
// debug |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment