-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathGustavGraph.js
80 lines (80 loc) · 2.93 KB
/
GustavGraph.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
'use strict';
var Rx = require('@reactivex/rxjs');
var GustavGraph = (function () {
function GustavGraph() {
this.sinkEdges = [];
this.transformEdges = {};
this.nodes = {};
}
GustavGraph.prototype.addEdge = function (from, to) {
if (!this.nodes[from]) {
throw new Error('From node ' + from.toString() + ' not registered');
}
if (!this.nodes[to]) {
throw new Error('To node ' + to.toString() + ' not registered');
}
if (from === to) {
throw new Error('Nodes cannot depend on themselves: ' + from.toString());
}
if (this.nodes[from].type === 'source') {
throw new Error('Loaders cannot have dependencies: ' + from.toString());
}
if (this.nodes[to].type === 'sink') {
throw new Error('Sinks cannot be depended on: ' /*they're sneaky like that*/ + to.toString());
}
if (this.nodes[from].type === 'sink') {
// Cant use destructuring here because from/to are Symbols
this.sinkEdges.push({
from: from,
to: to
});
}
else {
if (!this.transformEdges[from]) {
this.transformEdges[from] = [];
}
this.transformEdges[from].push(to);
}
};
GustavGraph.prototype.makeGraph = function () {
var _this = this;
var cache = {};
var seen = [];
var resolveDeps = function (nodeName) {
if (seen.indexOf(nodeName) > -1) {
throw new Error('Loop detected in dependency graph');
}
seen.push(nodeName);
if (cache[nodeName]) {
return cache[nodeName];
}
// All loaders do not have deps
if (_this.nodes[nodeName].type === 'source') {
return _this.nodes[nodeName].init();
}
// TODO: try/catch here and throw relevant error
// Will break with
// gustav.addDep(consoleSink(), logParser());
// gustav.addDep(logParser(), logGenerator())
// (Two different logParsers)
// console.log('bananas', nodeName);
var nextNode = _this.transformEdges[nodeName].map(resolveDeps);
// console.log('asdf', nodeName, nextNode);
if (nextNode.length) {
nextNode = Rx.Observable.merge.apply(null, nextNode);
}
var result = cache[nodeName] = _this.nodes[nodeName].init(nextNode);
return result;
};
// All sinks are terminal
// For each sinkEdge, find the next item
this.sinkEdges.forEach(function (edge) {
seen = [];
var x = resolveDeps(edge.to);
_this.nodes[edge.from].init(x);
});
};
return GustavGraph;
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = GustavGraph;