/** * Copyright JS Foundation and other contributors, http://js.foundation * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. **/ var when = require("when"); var clone = require("clone"); var typeRegistry = require("@node-red/registry"); var Log; var redUtil = require("@node-red/util").util; var flowUtil = require("./util"); var nodeCloseTimeout = 15000; class Flow { constructor(global,flow) { this.global = global; if (typeof flow === 'undefined') { this.flow = global; } else { this.flow = flow; } this.activeNodes = {}; this.subflowInstanceNodes = {}; this.catchNodeMap = {}; this.statusNodeMap = {}; } start(diff) { var node; var newNode; var id; this.catchNodeMap = {}; this.statusNodeMap = {}; var configNodes = Object.keys(this.flow.configs); var configNodeAttempts = {}; while (configNodes.length > 0) { id = configNodes.shift(); node = this.flow.configs[id]; if (!this.activeNodes[id]) { var readyToCreate = true; // This node doesn't exist. // Check it doesn't reference another non-existent config node for (var prop in node) { if (node.hasOwnProperty(prop) && prop !== 'id' && prop !== 'wires' && prop !== '_users' && this.flow.configs[node[prop]]) { if (!this.activeNodes[node[prop]]) { // References a non-existent config node // Add it to the back of the list to try again later configNodes.push(id); configNodeAttempts[id] = (configNodeAttempts[id]||0)+1; if (configNodeAttempts[id] === 100) { throw new Error("Circular config node dependency detected: "+id); } readyToCreate = false; break; } } } if (readyToCreate) { newNode = createNode(node.type,node); if (newNode) { this.activeNodes[id] = newNode; } } } } if (diff && diff.rewired) { for (var j=0;j { var i; if (stopList) { for (i=0;i