Restore node order in palette following async changes

The move to async loading of node files led to them appearing
out of order in the palette.
This commit is contained in:
Nick O'Leary 2015-04-08 20:17:24 +01:00
parent 8ee90777ee
commit e1dd8cf2ab
6 changed files with 127 additions and 44 deletions

View File

@ -127,7 +127,6 @@ module.exports = {
getNodeList: registry.getNodeList,
getModuleInfo: registry.getModuleInfo,
getModuleList: registry.getModuleList,
getNodeConfigs: registry.getNodeConfigs,
getNodeConfig: registry.getNodeConfig,

View File

@ -31,6 +31,11 @@ function init(_settings) {
}
function load(defaultNodesDir,disableNodePathScan) {
// To skip node scan, the following line will use the stored node list.
// We should expose that as an option at some point, although the
// performance gains are minimal.
//return loadNodeFiles(registry.getModuleList());
var nodeFiles = localfilesystem.getNodeFiles(defaultNodesDir,disableNodePathScan);
return loadNodeFiles(nodeFiles);
}
@ -41,9 +46,31 @@ function loadNodeFiles(nodeFiles) {
/* istanbul ignore else */
if (nodeFiles.hasOwnProperty(module)) {
if (!registry.getModuleInfo(module)) {
var first = true;
for (var node in nodeFiles[module].nodes) {
/* istanbul ignore else */
if (nodeFiles[module].nodes.hasOwnProperty(node)) {
if (module != "node-red" && first) {
// Check the module directory exists
first = false;
var fn = nodeFiles[module].nodes[node].file;
var parts = fn.split("/");
var i = parts.length-1;
for (;i>=0;i--) {
if (parts[i] == "node_modules") {
break;
}
}
var moduleFn = parts.slice(0,i+2).join("/");
try {
var stat = fs.statSync(moduleFn);
} catch(err) {
// Module not found, don't attempt to load its nodes
break;
}
}
try {
promises.push(loadNodeConfig(nodeFiles[module].nodes[node]))
} catch(err) {
@ -55,7 +82,10 @@ function loadNodeFiles(nodeFiles) {
}
}
return when.settle(promises).then(function(results) {
var nodes = results.map(function(r) { return r.value; });
var nodes = results.map(function(r) {
registry.addNodeSet(r.value.id,r.value,r.value.version);
return r.value;
});
return loadNodeSetList(nodes);
});
}
@ -84,15 +114,23 @@ function loadNodeConfig(fileInfo) {
file: file,
template: file.replace(/\.js$/,".html"),
enabled: isEnabled,
loaded:false
loaded:false,
version: version
};
if (fileInfo.hasOwnProperty("types")) {
node.types = fileInfo.types;
}
fs.readFile(node.template,'utf8', function(err,content) {
if (err) {
node.types = [];
if (err.code === 'ENOENT') {
if (!node.types) {
node.types = [];
}
node.err = "Error: "+file+" does not exist";
} else {
node.types = [];
node.err = err.toString();
}
} else {
@ -116,7 +154,6 @@ function loadNodeConfig(fileInfo) {
}
}
}
registry.addNodeSet(id,node,version);
resolve(node);
});
});

View File

@ -158,7 +158,6 @@ function addNodeSet(id,set,version) {
nodeTypeToId[t] = id;
});
}
moduleNodes[set.module] = moduleNodes[set.module]||[];
moduleNodes[set.module].push(set.name);
@ -262,14 +261,16 @@ function getNodeList(filter) {
}
function getModuleList() {
var list = [];
for (var module in moduleNodes) {
/* istanbul ignore else */
if (moduleNodes.hasOwnProperty(module)) {
list.push(registry.getModuleInfo(module));
}
}
return list;
//var list = [];
//for (var module in moduleNodes) {
// /* istanbul ignore else */
// if (moduleNodes.hasOwnProperty(module)) {
// list.push(registry.getModuleInfo(module));
// }
//}
//return list;
return moduleConfigs;
}
function getModuleInfo(module) {
@ -437,16 +438,18 @@ function cleanModuleList() {
}
}
}
} else if (moduleConfigs[mod] && !moduleNodes[mod]) {
// For node modules, look for missing ones
for (node in nodes) {
/* istanbul ignore else */
if (nodes.hasOwnProperty(node)) {
removeNode(mod+"/"+node);
removed = true;
} else {
if (moduleConfigs[mod] && !moduleNodes[mod]) {
// For node modules, look for missing ones
for (node in nodes) {
/* istanbul ignore else */
if (nodes.hasOwnProperty(node)) {
removeNode(mod+"/"+node);
removed = true;
}
}
delete moduleConfigs[mod];
}
delete moduleConfigs[mod];
}
}
}

View File

@ -63,7 +63,7 @@ function start() {
log.info("Node.js version: "+process.version);
log.info("Loading palette nodes");
redNodes.init(settings,storage,app);
redNodes.load().then(function() {
return redNodes.load().then(function() {
var i;
var nodeErrors = redNodes.getNodeList(function(n) { return n.err!=null;});
@ -106,10 +106,10 @@ function start() {
}
log.info("Settings file : "+settings.settingsFile);
redNodes.loadFlows();
comms.start();
}).otherwise(function(err) {
console.log(err);
});
comms.start();
});
}

View File

@ -307,22 +307,34 @@ describe('red/nodes/registry/index', function() {
typeRegistry.load("wontexist",true).then(function() {
var nodeList = typeRegistry.getNodeList();
var moduleList = typeRegistry.getModuleList();
Object.keys(moduleList).should.have.length(1);
moduleList.should.have.a.property("node-red");
Object.keys(moduleList["node-red"].nodes).should.have.length(3);
nodeList.should.be.Array.and.have.length(3);
moduleList.should.be.Array.and.have.length(1);
settingsSave.callCount.should.equal(1);
settingsSave.firstCall.args[0].should.be.equal("nodes");
var savedList = settingsSave.firstCall.args[1];
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("id","node-red/TestNode1");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("name","TestNode1");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("module","node-red");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("file");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("enabled",true);
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("types");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("config");
moduleList['node-red'].nodes['TestNode1'].should.have.a.property("template");
savedList[moduleList[0].name].name.should.equal(moduleList[0].name);
savedList[moduleList[0].name].nodes[moduleList[0].nodes[0].name].name.should.equal(moduleList[0].nodes[0].name);
savedList[moduleList[0].name].nodes[moduleList[0].nodes[1].name].name.should.equal(moduleList[0].nodes[1].name);
savedList[moduleList[0].name].nodes[moduleList[0].nodes[2].name].name.should.equal(moduleList[0].nodes[2].name);
savedList[moduleList[0].name].nodes[moduleList[0].nodes[0].name].should.not.have.property("err");
savedList[moduleList[0].name].nodes[moduleList[0].nodes[1].name].should.not.have.property("err");
savedList[moduleList[0].name].nodes[moduleList[0].nodes[2].name].should.not.have.property("err");
savedList['node-red'].nodes['TestNode1'].should.not.have.a.property("id");
savedList['node-red'].nodes['TestNode1'].should.have.a.property("name",moduleList['node-red'].nodes['TestNode1'].name);
savedList['node-red'].nodes['TestNode1'].should.have.a.property("module",moduleList['node-red'].nodes['TestNode1'].module);
savedList['node-red'].nodes['TestNode1'].should.have.a.property("file",moduleList['node-red'].nodes['TestNode1'].file);
savedList['node-red'].nodes['TestNode1'].should.have.a.property("enabled",moduleList['node-red'].nodes['TestNode1'].enabled);
savedList['node-red'].nodes['TestNode1'].should.have.a.property("types",moduleList['node-red'].nodes['TestNode1'].types);
savedList['node-red'].nodes['TestNode1'].should.not.have.a.property("config");
savedList['node-red'].nodes['TestNode1'].should.not.have.a.property("template");
done();
}).catch(function(e) {
@ -415,10 +427,12 @@ describe('red/nodes/registry/index', function() {
typeRegistry.addModule("TestNodeModule").then(function() {
var list = typeRegistry.getModuleList();
list.should.be.an.Array.and.have.lengthOf(1);
list[0].should.have.property("name", "TestNodeModule");
list[0].should.have.property("nodes");
list[0].nodes.should.be.an.Array.and.have.lengthOf(2);
Object.keys(list).should.have.length(1);
list.should.have.a.property("TestNodeModule");
Object.keys(list["TestNodeModule"].nodes).should.have.length(2);
list["TestNodeModule"].nodes["TestNodeMod1"].should.have.property("name", "TestNodeMod1");
list["TestNodeModule"].nodes["TestNodeMod2"].should.have.property("name", "TestNodeMod2");
done();
}).catch(function(e) {
@ -656,8 +670,8 @@ describe('red/nodes/registry/index', function() {
var modules = typeRegistry.getModuleList();
modules[0].should.have.property("name","TestNodeModule");
modules[0].should.have.property("version","0.0.1");
modules.should.have.property("TestNodeModule");
modules["TestNodeModule"].should.have.property("version","0.0.1");
done();
}).catch(function(e) {

View File

@ -117,12 +117,26 @@ describe("red/nodes/registry/registry",function() {
typeRegistry.init(settings);
typeRegistry.getNodeList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.eql({});
typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1");
typeRegistry.getNodeList().should.have.lengthOf(1);
typeRegistry.getModuleList().should.have.lengthOf(1);
var moduleList = typeRegistry.getModuleList();
moduleList.should.have.a.property("test-module");
moduleList["test-module"].should.have.a.property("name","test-module");
moduleList["test-module"].should.have.a.property("version","0.0.1");
moduleList["test-module"].should.have.a.property("nodes");
moduleList["test-module"].nodes.should.have.a.property("test-name");
moduleList["test-module"].nodes["test-name"].should.eql({
id: 'test-module/test-name',
module: 'test-module',
name: 'test-name',
enabled: true,
loaded: false,
types: [ 'test-a', 'test-b' ]
});
});
@ -130,20 +144,36 @@ describe("red/nodes/registry/registry",function() {
typeRegistry.init(settings);
typeRegistry.getNodeList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.eql({});
typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1");
typeRegistry.getNodeList().should.have.lengthOf(1);
var moduleList = typeRegistry.getModuleList();
Object.keys(moduleList).should.have.a.lengthOf(1);
moduleList.should.have.a.property("test-module");
moduleList["test-module"].should.have.a.property("name","test-module");
moduleList["test-module"].should.have.a.property("version","0.0.1");
moduleList["test-module"].should.have.a.property("nodes");
Object.keys(moduleList["test-module"].nodes).should.have.a.lengthOf(1);
moduleList["test-module"].nodes.should.have.a.property("test-name");
typeRegistry.addNodeSet("test-module/test-name-2",testNodeSet2);
typeRegistry.getNodeList().should.have.lengthOf(2);
typeRegistry.getModuleList().should.have.lengthOf(1);
moduleList = typeRegistry.getModuleList();
Object.keys(moduleList).should.have.a.lengthOf(1);
Object.keys(moduleList["test-module"].nodes).should.have.a.lengthOf(2);
moduleList["test-module"].nodes.should.have.a.property("test-name");
moduleList["test-module"].nodes.should.have.a.property("test-name-2");
});
it('doesnt add node set types if node set has an error', function() {
typeRegistry.init(settings);
typeRegistry.getNodeList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.have.lengthOf(0);
typeRegistry.getModuleList().should.eql({});
typeRegistry.addNodeSet("test-module/test-name",testNodeSet1, "0.0.1");