Komponensek folyamának építése a Flow.load()-dal és futtatása az exec()-kel
A FlowStream egy kis program, amely komponensekből (bemenetekkel és kimenetekkel rendelkező dobozokból) és a köztük lévő kapcsolatokból áll. A Total.js az alkalmazásán belül futtatja: egy üzenet belép egy komponensbe, a komponens eredményeket küld a kimeneteire, a kapcsolatok pedig a következő komponensekhez viszik őket. Ugyanezt a sémát rajzolja a Total.js Flow-tervezője; itt kézzel van megírva.
A Flow.load(schema, [callback]) elindít egy FlowStreamet, és a callbacknek (err, instance) értéket ad. A séma egy objektum:
idésname: az id a kulcs aFlow.instances-ben (Flow.instances.demo); id nélkül véletlenszerűt hoz létre.components: egy objektum az egyes komponensek forráskódjával, szövegként. A szöveg egy szkript,<script total>...</script>(az a forma, amelyet a tervező ment).design: a komponensek példányai. Mindegyiknek vanid-ja, a használtcomponent, a sajátconfigésconnectionsértéke, egy objektum, amelynek kulcsai a kimenetek id-jai, értékei pedig{ id, index }listák: az a példány és bemenet-id, amely megkapja, amit arra a kimenetre küldenek.variables: értékek, amelyeket a komponensek olvashatnak.
A komponens egy modul: exports.id, exports.name, exports.inputs és exports.outputs ({ id, name } listák), exports.config (az alapértelmezések) és exports.make = function(instance, config). A make()-ben a komponens beállítja az instance.message = function($) {} függvényt, amely minden üzenetet megkap: a $.data az adat, a $.send(outputid, data) egy kimenetre küldi, a $.destroy() pedig befejez egy üzenetet, amely nem megy tovább.
A folyamat kódból való használatához az instance.exec({ id, data, callback }) elküldi a data-t az id példánynak, és meghívja a callback(err, message) függvényt, amikor az üzenet véget ér; a lánc utolsó üzenete a message (így a message.data az, amit az utolsó komponens kapott). Az instance.reconfigure(id, config) megváltoztatja egy futó példány konfigurációját, a Flow.remove(id) pedig leállítja a FlowStreamet és elfelejti. A FlowStream ugyanaz az objektum, mint a Flow: két név a kezelőre.
A komponens olyan kód, amely az alkalmazás összes jogával fut (ugyanabban a szálban, hacsak a séma nem mondja, hogy worker). Soha ne töltsön be olyan sémát vagy komponenst, amelyet egy látogató írhat.
const upper = `<script total>
exports.id = 'upper';
exports.name = 'Upper case';
exports.inputs = [{ id: 'input', name: 'Input' }];
exports.outputs = [{ id: 'output', name: 'Output' }];
exports.config = { prefix: '' };
exports.make = function(instance, config) {
instance.message = function($) {
$.send('output', config.prefix + String($.data).toUpperCase());
};
};
</script>`;
const collect = `<script total>
exports.id = 'collect';
exports.name = 'Collect';
exports.inputs = [{ id: 'input', name: 'Input' }];
exports.make = function(instance) {
instance.message = function($) {
MAIN.collected.push($.data);
$.destroy();
};
};
</script>`;
MAIN.collected = [];
MAIN.flow = null;
Flow.load({
id: 'demo',
name: 'Demo',
components: { upper: upper, collect: collect },
design: {
a: { id: 'a', component: 'upper', config: { prefix: '> ' }, connections: { output: [{ id: 'b', index: 'input' }] } },
b: { id: 'b', component: 'collect', config: {}, connections: {} }
},
variables: {}
}, function(err, instance) {
MAIN.flow = instance;
});exports.install = function() {
ROUTE('GET /shout/', shout);
ROUTE('POST /prefix/ @json', prefix);
ROUTE('GET /collected/', collected);
ROUTE('GET /info/', info);
ROUTE('POST /stop/', stop);
};
function shout($) {
if (!MAIN.flow)
return $.invalid('The flow is not running');
MAIN.flow.exec({ id: 'a', data: $.query.text, callback: (err, message) => $.json({ result: message ? message.data : null }) });
}
function prefix($) {
MAIN.flow.reconfigure('a', { prefix: $.body.prefix });
$.json({ ok: true });
}
function collected($) {
$.json(MAIN.collected);
}
function info($) {
$.json({ flows: Object.keys(Flow.instances), instances: Object.keys(MAIN.flow.flow.meta.flow), same: Flow === FlowStream });
}
function stop($) {
Flow.remove('demo');
MAIN.flow = null;
$.json({ flows: Object.keys(Flow.instances) });
}