Yes and no. In my example I am using the idea of Loggers, but I want to have the capability to reference an arbitrary collection of nodes, whether they have been written by me or not... eg a list of type "mqtt-broker" ( which is part of the standard list of nodered nodes)
I managed to build a bit of a workaround- it has some limitations and it its a bit of a kludge, but it does seem to work. From what I understand, the way nodered determines the order in which to start up nodes is done using a queue-based retry loop, and not a topological sort / graph. It iterates over the node's top-level direct string properties and checks whether any of them match the ID of another config node. If a dependency is not yet active, the current node is pushed to the back of the queue and retried later. The hint here is that instead of just putting the ids of my referenced nodes in an array, I should add them directly to the defaults section. Initially I thought that there might be an issue if I did not add the type of the node to it, but it seems like that only matters if you intend to hook an actual control to it on the editor, so if the user never edits that particular value directly, the type of the referenced node doesn't matter- this also means that if you just so happen to pick a value for a particular field and that value matches the ID of another node exactly, bad things can happen, such an infinite deployment loop, but I am sure the Nodered devs are aware of that one.
The defaults section in my node properties thus looks something like this.
.....
.....
loggerconfigurations: {
value: '',
required: true,
},
_loggerconfigurations_0: {
value: '',
required: false
},
_loggerconfigurations_1: {
value: '',
required: false
},
_loggerconfigurations_2: {
value: '',
required: false
},
_loggerconfigurations_3: {
value: '',
required: false
},
_loggerconfigurations_4: {
value: '',
required: false
},
......
......
the last part is to keep the loggerconfigurations and the list of _loggerconfigurations_N in sync whenever the node is saved, and that is easily done adding this to the last part of oneditsave:
let node = this;
for (let i = 0; i < 10; i++) {
node["_" + loggerconfigurations + "_" + i] = (node.loggerconfigurations[i] || {}).logger || "";
}
This means that the instantiation of the nodes on the flow will use _loggerconfigurations_N to determine the startup order, while I can safely ignore them in the constructor of my node and only deal with loggerconfigurations which is populated from a table on the editor.
The obvious caveat is that we now have a hardcoded number of loggerconfiguration slots. I'll just set it to a sensible value of 10 for now, until it actually comes up short. Fortunately most of the code is generated using a templating engine which makes things a whole lot easier.
Lastly, the unforseen bonus is of course that reference counting works: any node referenced by the direct properties of another node gets counted as a usage reference.