UNPKG

rete

Version:
1,845 lines (1,545 loc) 75.8 kB
/*! * rete v1.2.2 * (c) 2019 Vitaliy Stoliarov * Released under the MIT license. */ 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } } function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } function _objectSpread(target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i] != null ? arguments[i] : {}; var ownKeys = Object.keys(source); if (typeof Object.getOwnPropertySymbols === 'function') { ownKeys = ownKeys.concat(Object.getOwnPropertySymbols(source).filter(function (sym) { return Object.getOwnPropertyDescriptor(source, sym).enumerable; })); } ownKeys.forEach(function (key) { _defineProperty(target, key, source[key]); }); } return target; } function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } function _superPropBase(object, property) { while (!Object.prototype.hasOwnProperty.call(object, property)) { object = _getPrototypeOf(object); if (object === null) break; } return object; } function _get(target, property, receiver) { if (typeof Reflect !== "undefined" && Reflect.get) { _get = Reflect.get; } else { _get = function _get(target, property, receiver) { var base = _superPropBase(target, property); if (!base) return; var desc = Object.getOwnPropertyDescriptor(base, property); if (desc.get) { return desc.get.call(receiver); } return desc.value; }; } return _get(target, property, receiver || target); } function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _nonIterableRest(); } function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); } function _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) arr2[i] = arr[i]; return arr2; } } function _arrayWithHoles(arr) { if (Array.isArray(arr)) return arr; } function _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); } function _iterableToArrayLimit(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i["return"] != null) _i["return"](); } finally { if (_d) throw _e; } } return _arr; } function _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); } function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance"); } var Component = function Component(name) { _classCallCheck(this, Component); _defineProperty(this, "name", void 0); _defineProperty(this, "data", {}); _defineProperty(this, "engine", null); this.name = name; }; var Emitter = /*#__PURE__*/ function () { function Emitter(events) { _classCallCheck(this, Emitter); _defineProperty(this, "events", {}); _defineProperty(this, "silent", false); this.events = events instanceof Emitter ? events.events : events.handlers; } _createClass(Emitter, [{ key: "on", value: function on(names, handler) { var _this = this; var events = names instanceof Array ? names : names.split(' '); events.forEach(function (name) { if (!_this.events[name]) throw new Error("The event ".concat(name, " does not exist")); _this.events[name].push(handler); }); return this; } }, { key: "trigger", value: function trigger(name) { var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {}; if (!(name in this.events)) throw new Error("The event ".concat(name, " cannot be triggered")); return this.events[name].reduce(function (r, e) { return e(params) !== false && r; }, true); // return false if at least one event is false } }, { key: "bind", value: function bind(name) { if (this.events[name]) throw new Error("The event ".concat(name, " is already bound")); this.events[name] = []; } }, { key: "exist", value: function exist(name) { return Array.isArray(this.events[name]); } }]); return Emitter; }(); var Validator = /*#__PURE__*/ function () { function Validator() { _classCallCheck(this, Validator); } _createClass(Validator, null, [{ key: "isValidData", value: function isValidData(data) { return typeof data.id === 'string' && this.isValidId(data.id) && data.nodes instanceof Object && !(data.nodes instanceof Array); } }, { key: "isValidId", value: function isValidId(id) { return /^[\w-]{3,}@[0-9]+\.[0-9]+\.[0-9]+$/.test(id); } }, { key: "validate", value: function validate(id, data) { var id1 = id.split('@'); var id2 = data.id.split('@'); var msg = []; if (!this.isValidData(data)) msg.push('Data is not suitable'); if (id !== data.id) msg.push('IDs not equal'); if (id1[0] !== id2[0]) msg.push('Names don\'t match'); if (id1[1] !== id2[1]) msg.push('Versions don\'t match'); return { success: Boolean(!msg.length), msg: msg.join('. ') }; } }]); return Validator; }(); var Context = /*#__PURE__*/ function (_Emitter) { _inherits(Context, _Emitter); function Context(id, events) { var _this; _classCallCheck(this, Context); _this = _possibleConstructorReturn(this, _getPrototypeOf(Context).call(this, events)); _defineProperty(_assertThisInitialized(_this), "id", void 0); _defineProperty(_assertThisInitialized(_this), "plugins", void 0); _defineProperty(_assertThisInitialized(_this), "components", void 0); if (!Validator.isValidId(id)) throw new Error('ID should be valid to name@0.1.0 format'); _this.id = id; _this.plugins = new Map(); _this.components = new Map(); return _this; } _createClass(Context, [{ key: "use", value: function use(plugin, options) { if (plugin.name && this.plugins.has(plugin.name)) throw new Error("Plugin ".concat(plugin.name, " already in use")); plugin.install(this, options || {}); this.plugins.set(plugin.name, options); } }, { key: "register", value: function register(component) { if (this.components.has(component.name)) throw new Error("Component ".concat(component.name, " already registered")); this.components.set(component.name, component); this.trigger('componentregister', component); } }]); return Context; }(Emitter); var Events = function Events(handlers) { _classCallCheck(this, Events); _defineProperty(this, "handlers", void 0); this.handlers = _objectSpread({ warn: [console.warn], error: [console.error], componentregister: [] }, handlers); }; var EngineEvents = /*#__PURE__*/ function (_Events) { _inherits(EngineEvents, _Events); function EngineEvents() { _classCallCheck(this, EngineEvents); return _possibleConstructorReturn(this, _getPrototypeOf(EngineEvents).call(this, {})); } return EngineEvents; }(Events); function intersect(array1, array2) { return array1.filter(function (value) { return -1 !== array2.indexOf(value); }); } var Recursion = /*#__PURE__*/ function () { function Recursion(nodes) { _classCallCheck(this, Recursion); _defineProperty(this, "nodes", void 0); this.nodes = nodes; } _createClass(Recursion, [{ key: "extractInputNodes", value: function extractInputNodes(node) { var _this = this; return Object.keys(node.inputs).reduce(function (a, key) { return [].concat(_toConsumableArray(a), _toConsumableArray((node.inputs[key].connections || []).reduce(function (b, c) { return [].concat(_toConsumableArray(b), [_this.nodes[c.node]]); }, []))); }, []); } }, { key: "findSelf", value: function findSelf(list, inputNodes) { var inters = intersect(list, inputNodes); if (inters.length) return inters[0]; var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = inputNodes[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { var node = _step.value; var l = [node].concat(_toConsumableArray(list)); var inter = this.findSelf(l, this.extractInputNodes(node)); if (inter) return inter; } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return != null) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } return null; } }, { key: "detect", value: function detect() { var _this2 = this; var nodesArr = Object.keys(this.nodes).map(function (id) { return _this2.nodes[id]; }); var _iteratorNormalCompletion2 = true; var _didIteratorError2 = false; var _iteratorError2 = undefined; try { for (var _iterator2 = nodesArr[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) { var node = _step2.value; var inters = this.findSelf([node], this.extractInputNodes(node)); if (inters) return inters; } } catch (err) { _didIteratorError2 = true; _iteratorError2 = err; } finally { try { if (!_iteratorNormalCompletion2 && _iterator2.return != null) { _iterator2.return(); } } finally { if (_didIteratorError2) { throw _iteratorError2; } } } return null; } }]); return Recursion; }(); var State = { AVAILABLE: 0, PROCESSED: 1, ABORT: 2 }; var Engine = /*#__PURE__*/ function (_Context) { _inherits(Engine, _Context); function Engine(id) { var _this; _classCallCheck(this, Engine); _this = _possibleConstructorReturn(this, _getPrototypeOf(Engine).call(this, id, new EngineEvents())); _defineProperty(_assertThisInitialized(_this), "args", []); _defineProperty(_assertThisInitialized(_this), "data", null); _defineProperty(_assertThisInitialized(_this), "state", State.AVAILABLE); _defineProperty(_assertThisInitialized(_this), "onAbort", function () {}); return _this; } _createClass(Engine, [{ key: "clone", value: function clone() { var engine = new Engine(this.id); this.components.forEach(function (c) { return engine.register(c); }); return engine; } }, { key: "throwError", value: function () { var _throwError = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(message) { var data, _args = arguments; return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: data = _args.length > 1 && _args[1] !== undefined ? _args[1] : null; _context.next = 3; return this.abort(); case 3: this.trigger('error', { message: message, data: data }); this.processDone(); return _context.abrupt("return", 'error'); case 6: case "end": return _context.stop(); } } }, _callee, this); })); function throwError(_x) { return _throwError.apply(this, arguments); } return throwError; }() }, { key: "processStart", value: function processStart() { if (this.state === State.AVAILABLE) { this.state = State.PROCESSED; return true; } if (this.state === State.ABORT) { return false; } console.warn("The process is busy and has not been restarted.\n Use abort() to force it to complete"); return false; } }, { key: "processDone", value: function processDone() { var success = this.state !== State.ABORT; this.state = State.AVAILABLE; if (!success) { this.onAbort(); this.onAbort = function () {}; } return success; } }, { key: "abort", value: function () { var _abort = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { var _this2 = this; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: return _context2.abrupt("return", new Promise(function (ret) { if (_this2.state === State.PROCESSED) { _this2.state = State.ABORT; _this2.onAbort = ret; } else if (_this2.state === State.ABORT) { _this2.onAbort(); _this2.onAbort = ret; } else ret(); })); case 1: case "end": return _context2.stop(); } } }, _callee2); })); function abort() { return _abort.apply(this, arguments); } return abort; }() }, { key: "lock", value: function () { var _lock = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee3(node) { return regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) { switch (_context3.prev = _context3.next) { case 0: return _context3.abrupt("return", new Promise(function (res) { node.unlockPool = node.unlockPool || []; if (node.busy && !node.outputData) node.unlockPool.push(res);else res(); node.busy = true; })); case 1: case "end": return _context3.stop(); } } }, _callee3); })); function lock(_x2) { return _lock.apply(this, arguments); } return lock; }() }, { key: "unlock", value: function unlock(node) { node.unlockPool.forEach(function (a) { return a(); }); node.unlockPool = []; node.busy = false; } }, { key: "extractInputData", value: function () { var _extractInputData = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee5(node) { var _this3 = this; var obj, _arr, _i, key, input, conns, connData; return regeneratorRuntime.wrap(function _callee5$(_context5) { while (1) { switch (_context5.prev = _context5.next) { case 0: obj = {}; _arr = Object.keys(node.inputs); _i = 0; case 3: if (!(_i < _arr.length)) { _context5.next = 14; break; } key = _arr[_i]; input = node.inputs[key]; conns = input.connections; _context5.next = 9; return Promise.all(conns.map( /*#__PURE__*/ function () { var _ref = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee4(c) { var prevNode, outputs; return regeneratorRuntime.wrap(function _callee4$(_context4) { while (1) { switch (_context4.prev = _context4.next) { case 0: prevNode = _this3.data.nodes[c.node]; _context4.next = 3; return _this3.processNode(prevNode); case 3: outputs = _context4.sent; if (outputs) { _context4.next = 8; break; } _this3.abort(); _context4.next = 9; break; case 8: return _context4.abrupt("return", outputs[c.output]); case 9: case "end": return _context4.stop(); } } }, _callee4); })); return function (_x4) { return _ref.apply(this, arguments); }; }())); case 9: connData = _context5.sent; obj[key] = connData; case 11: _i++; _context5.next = 3; break; case 14: return _context5.abrupt("return", obj); case 15: case "end": return _context5.stop(); } } }, _callee5); })); function extractInputData(_x3) { return _extractInputData.apply(this, arguments); } return extractInputData; }() }, { key: "processWorker", value: function () { var _processWorker = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee6(node) { var inputData, component, outputData; return regeneratorRuntime.wrap(function _callee6$(_context6) { while (1) { switch (_context6.prev = _context6.next) { case 0: _context6.next = 2; return this.extractInputData(node); case 2: inputData = _context6.sent; component = this.components.get(node.name); outputData = {}; _context6.prev = 5; _context6.next = 8; return component.worker.apply(component, [node, inputData, outputData].concat(_toConsumableArray(this.args))); case 8: _context6.next = 14; break; case 10: _context6.prev = 10; _context6.t0 = _context6["catch"](5); this.abort(); this.trigger('warn', _context6.t0); case 14: return _context6.abrupt("return", outputData); case 15: case "end": return _context6.stop(); } } }, _callee6, this, [[5, 10]]); })); function processWorker(_x5) { return _processWorker.apply(this, arguments); } return processWorker; }() }, { key: "processNode", value: function () { var _processNode = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee7(node) { return regeneratorRuntime.wrap(function _callee7$(_context7) { while (1) { switch (_context7.prev = _context7.next) { case 0: if (!(this.state === State.ABORT || !node)) { _context7.next = 2; break; } return _context7.abrupt("return", null); case 2: _context7.next = 4; return this.lock(node); case 4: if (!node.outputData) { node.outputData = this.processWorker(node); } this.unlock(node); return _context7.abrupt("return", node.outputData); case 7: case "end": return _context7.stop(); } } }, _callee7, this); })); function processNode(_x6) { return _processNode.apply(this, arguments); } return processNode; }() }, { key: "forwardProcess", value: function () { var _forwardProcess = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee10(node) { var _this4 = this; return regeneratorRuntime.wrap(function _callee10$(_context10) { while (1) { switch (_context10.prev = _context10.next) { case 0: if (!(this.state === State.ABORT)) { _context10.next = 2; break; } return _context10.abrupt("return", null); case 2: _context10.next = 4; return Promise.all(Object.keys(node.outputs).map( /*#__PURE__*/ function () { var _ref2 = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee9(key) { var output; return regeneratorRuntime.wrap(function _callee9$(_context9) { while (1) { switch (_context9.prev = _context9.next) { case 0: output = node.outputs[key]; _context9.next = 3; return Promise.all(output.connections.map( /*#__PURE__*/ function () { var _ref3 = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee8(c) { var nextNode; return regeneratorRuntime.wrap(function _callee8$(_context8) { while (1) { switch (_context8.prev = _context8.next) { case 0: nextNode = _this4.data.nodes[c.node]; _context8.next = 3; return _this4.processNode(nextNode); case 3: _context8.next = 5; return _this4.forwardProcess(nextNode); case 5: case "end": return _context8.stop(); } } }, _callee8); })); return function (_x9) { return _ref3.apply(this, arguments); }; }())); case 3: return _context9.abrupt("return", _context9.sent); case 4: case "end": return _context9.stop(); } } }, _callee9); })); return function (_x8) { return _ref2.apply(this, arguments); }; }())); case 4: return _context10.abrupt("return", _context10.sent); case 5: case "end": return _context10.stop(); } } }, _callee10, this); })); function forwardProcess(_x7) { return _forwardProcess.apply(this, arguments); } return forwardProcess; }() }, { key: "copy", value: function copy(data) { data = Object.assign({}, data); data.nodes = Object.assign({}, data.nodes); Object.keys(data.nodes).forEach(function (key) { data.nodes[key] = Object.assign({}, data.nodes[key]); }); return data; } }, { key: "validate", value: function () { var _validate = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee11(data) { var checking, recursion, recurrentNode; return regeneratorRuntime.wrap(function _callee11$(_context11) { while (1) { switch (_context11.prev = _context11.next) { case 0: checking = Validator.validate(this.id, data); recursion = new Recursion(data.nodes); if (checking.success) { _context11.next = 6; break; } _context11.next = 5; return this.throwError(checking.msg); case 5: return _context11.abrupt("return", _context11.sent); case 6: recurrentNode = recursion.detect(); if (!recurrentNode) { _context11.next = 11; break; } _context11.next = 10; return this.throwError('Recursion detected', recurrentNode); case 10: return _context11.abrupt("return", _context11.sent); case 11: return _context11.abrupt("return", true); case 12: case "end": return _context11.stop(); } } }, _callee11, this); })); function validate(_x10) { return _validate.apply(this, arguments); } return validate; }() }, { key: "processStartNode", value: function () { var _processStartNode = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee12(id) { var startNode; return regeneratorRuntime.wrap(function _callee12$(_context12) { while (1) { switch (_context12.prev = _context12.next) { case 0: if (id) { _context12.next = 2; break; } return _context12.abrupt("return"); case 2: startNode = this.data.nodes[id]; if (startNode) { _context12.next = 7; break; } _context12.next = 6; return this.throwError('Node with such id not found'); case 6: return _context12.abrupt("return", _context12.sent); case 7: _context12.next = 9; return this.processNode(startNode); case 9: _context12.next = 11; return this.forwardProcess(startNode); case 11: case "end": return _context12.stop(); } } }, _callee12, this); })); function processStartNode(_x11) { return _processStartNode.apply(this, arguments); } return processStartNode; }() }, { key: "processUnreachable", value: function () { var _processUnreachable = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee13() { var data, i, node; return regeneratorRuntime.wrap(function _callee13$(_context13) { while (1) { switch (_context13.prev = _context13.next) { case 0: data = this.data; _context13.t0 = regeneratorRuntime.keys(data.nodes); case 2: if ((_context13.t1 = _context13.t0()).done) { _context13.next = 12; break; } i = _context13.t1.value; // process nodes that have not been reached node = data.nodes[i]; if (!(typeof node.outputData === 'undefined')) { _context13.next = 10; break; } _context13.next = 8; return this.processNode(node); case 8: _context13.next = 10; return this.forwardProcess(node); case 10: _context13.next = 2; break; case 12: case "end": return _context13.stop(); } } }, _callee13, this); })); function processUnreachable() { return _processUnreachable.apply(this, arguments); } return processUnreachable; }() }, { key: "process", value: function () { var _process = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee14(data) { var startId, _len, args, _key, _args14 = arguments; return regeneratorRuntime.wrap(function _callee14$(_context14) { while (1) { switch (_context14.prev = _context14.next) { case 0: startId = _args14.length > 1 && _args14[1] !== undefined ? _args14[1] : null; if (this.processStart()) { _context14.next = 3; break; } return _context14.abrupt("return"); case 3: if (this.validate(data)) { _context14.next = 5; break; } return _context14.abrupt("return"); case 5: this.data = this.copy(data); for (_len = _args14.length, args = new Array(_len > 2 ? _len - 2 : 0), _key = 2; _key < _len; _key++) { args[_key - 2] = _args14[_key]; } this.args = args; _context14.next = 10; return this.processStartNode(startId); case 10: _context14.next = 12; return this.processUnreachable(); case 12: return _context14.abrupt("return", this.processDone() ? 'success' : 'aborted'); case 13: case "end": return _context14.stop(); } } }, _callee14, this); })); function process(_x12) { return _process.apply(this, arguments); } return process; }() }]); return Engine; }(Context); var Node = /*#__PURE__*/ function () { function Node(name) { _classCallCheck(this, Node); _defineProperty(this, "name", void 0); _defineProperty(this, "id", void 0); _defineProperty(this, "position", [0.0, 0.0]); _defineProperty(this, "inputs", new Map()); _defineProperty(this, "outputs", new Map()); _defineProperty(this, "controls", new Map()); _defineProperty(this, "data", {}); _defineProperty(this, "meta", {}); this.name = name; this.id = Node.incrementId(); } _createClass(Node, [{ key: "_add", value: function _add(list, item, prop) { if (list.has(item.key)) throw new Error("Item with key '".concat(item.key, "' already been added to the node")); if (item[prop] !== null) throw new Error('Item has already been added to some node'); item[prop] = this; list.set(item.key, item); } }, { key: "addControl", value: function addControl(control) { this._add(this.controls, control, 'parent'); return this; } }, { key: "removeControl", value: function removeControl(control) { control.parent = null; this.controls.delete(control.key); } }, { key: "addInput", value: function addInput(input) { this._add(this.inputs, input, 'node'); return this; } }, { key: "removeInput", value: function removeInput(input) { input.removeConnections(); input.node = null; this.inputs.delete(input.key); } }, { key: "addOutput", value: function addOutput(output) { this._add(this.outputs, output, 'node'); return this; } }, { key: "removeOutput", value: function removeOutput(output) { output.removeConnections(); output.node = null; this.outputs.delete(output.key); } }, { key: "getConnections", value: function getConnections() { var ios = [].concat(_toConsumableArray(this.inputs.values()), _toConsumableArray(this.outputs.values())); var connections = ios.reduce(function (arr, io) { return [].concat(_toConsumableArray(arr), _toConsumableArray(io.connections)); }, []); return connections; } }, { key: "update", value: function update() {} }, { key: "toJSON", value: function toJSON() { return { 'id': this.id, 'data': this.data, 'inputs': Array.from(this.inputs).reduce(function (obj, _ref) { var _ref2 = _slicedToArray(_ref, 2), key = _ref2[0], input = _ref2[1]; return obj[key] = input.toJSON(), obj; }, {}), 'outputs': Array.from(this.outputs).reduce(function (obj, _ref3) { var _ref4 = _slicedToArray(_ref3, 2), key = _ref4[0], output = _ref4[1]; return obj[key] = output.toJSON(), obj; }, {}), 'position': this.position, 'name': this.name }; } }], [{ key: "incrementId", value: function incrementId() { if (!this.latestId) this.latestId = 1;else this.latestId++; return this.latestId; } }, { key: "resetId", value: function resetId() { this.latestId = 0; } }, { key: "fromJSON", value: function fromJSON(json) { var node = new Node(json.name); node.id = json.id; node.data = json.data; node.position = json.position; node.name = json.name; Node.latestId = Math.max(node.id, Node.latestId); return node; } }]); return Node; }(); _defineProperty(Node, "latestId", 0); var Component$1 = /*#__PURE__*/ function (_ComponentWorker) { _inherits(Component$$1, _ComponentWorker); function Component$$1(name) { var _this; _classCallCheck(this, Component$$1); _this = _possibleConstructorReturn(this, _getPrototypeOf(Component$$1).call(this, name)); _defineProperty(_assertThisInitialized(_this), "editor", null); _defineProperty(_assertThisInitialized(_this), "data", {}); return _this; } _createClass(Component$$1, [{ key: "build", value: function () { var _build = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee(node) { return regeneratorRuntime.wrap(function _callee$(_context) { while (1) { switch (_context.prev = _context.next) { case 0: _context.next = 2; return this.builder(node); case 2: return _context.abrupt("return", node); case 3: case "end": return _context.stop(); } } }, _callee, this); })); function build(_x) { return _build.apply(this, arguments); } return build; }() }, { key: "createNode", value: function () { var _createNode = _asyncToGenerator( /*#__PURE__*/ regeneratorRuntime.mark(function _callee2() { var data, node, _args2 = arguments; return regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) { switch (_context2.prev = _context2.next) { case 0: data = _args2.length > 0 && _args2[0] !== undefined ? _args2[0] : {}; node = new Node(this.name); node.data = data; _context2.next = 5; return this.build(node); case 5: return _context2.abrupt("return", node); case 6: case "end": return _context2.stop(); } } }, _callee2, this); })); function createNode() { return _createNode.apply(this, arguments); } return createNode; }() }]); return Component$$1; }(Component); var Control = /*#__PURE__*/ function () { function Control(key) { _classCallCheck(this, Control); _defineProperty(this, "key", void 0); _defineProperty(this, "data", {}); _defineProperty(this, "parent", null); if (this.constructor === Control) throw new TypeError('Can not construct abstract class'); if (!key) throw new Error('The key parameter is missing in super() of Control '); this.key = key; } _createClass(Control, [{ key: "getNode", value: function getNode() { if (this.parent === null) throw new Error('Control isn\'t added to Node/Input'); if (this.parent instanceof Node) return this.parent; if (!this.parent.node) throw new Error('Control hasn\'t be added to Input or Node'); return this.parent.node; } }, { key: "getData", value: function getData(key) { return this.getNode().data[key]; } }, { key: "putData", value: function putData(key, data) { this.getNode().data[key] = data; } }]); return Control; }(); var Connection = /*#__PURE__*/ function () { function Connection(output, input) { _classCallCheck(this, Connection); _defineProperty(this, "output", void 0); _defineProperty(this, "input", void 0); _defineProperty(this, "data", {}); this.output = output; this.input = input; this.data = {}; this.input.addConnection(this); } _createClass(Connection, [{ key: "remove", value: function remove() { this.input.removeConnection(this); this.output.removeConnection(this); } }]); return Connection; }(); var IO = /*#__PURE__*/ function () { function IO(key, name, socket, multiConns) { _classCallCheck(this, IO); _defineProperty(this, "node", null); _defineProperty(this, "multipleConnections", void 0); _defineProperty(this, "connections", []); _defineProperty(this, "key", void 0); _defineProperty(this, "name", void 0); _defineProperty(this, "socket", void 0); this.node = null; this.multipleConnections = multiConns; this.connections = []; this.key = key; this.name = name; this.socket = socket; } _createClass(IO, [{ key: "removeConnection", value: function removeConnection(connection) { this.connections.splice(this.connections.indexOf(connection), 1); } }, { key: "removeConnections", value: function removeConnections() { var _this = this; this.connections.map(function (connection) { return _this.removeConnection(connection); }); } }]); return IO; }(); var Input = /*#__PURE__*/ function (_IO) { _inherits(Input, _IO); function Input(key, title, socket) { var _this; var multiConns = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false; _classCallCheck(this, Input); _this = _possibleConstructorReturn(this, _getPrototypeOf(Input).call(this, key, title, socket, multiConns)); _defineProperty(_assertThisInitialized(_this), "control", null); return _this; } _createClass(Input, [{ key: "hasConnection", value: function hasConnection() { return this.connections.length > 0; } }, { key: "addConnection", value: function addConnection(connection) { if (!this.multipleConnections && this.hasConnection()) throw new Error('Multiple connections not allowed'); this.connections.push(connection); } }, { key: "addControl", value: function addControl(control) { this.control = control; control.parent = this; } }, { key: "showControl", value: function showControl() { return !this.hasConnection() && this.control !== null; } }, { key: "toJSON", value: function toJSON() { return { 'connections': this.connections.map(function (c) { return { node: c.output.node && c.output.node.id, output: c.output.key, data: c.data }; }) }; } }]); return Input; }(IO); var EditorEvents = /*#__PURE__*/ function (_Events) { _inherits(EditorEvents, _Events); function EditorEvents() { _classCallCheck(this, EditorEvents); return _possibleConstructorReturn(this, _getPrototypeOf(EditorEvents).call(this, { nodecreate: [], nodecreated: [], noderemove: [], noderemoved: [], connectioncreate: [], connectioncreated: [], connectionremove: [], connectionremoved: [], translatenode: [], nodetranslate: [], nodetranslated: [], nodedraged: [], selectnode: [], nodeselect: [], nodeselected: [], rendernode: [], rendersocket: [], rendercontrol: [], renderconnection: [], updateconnection: [], keydown: [], keyup: [], translate: [], translated: [], zoom: [], zoomed: [], click: [], mousemove: [], contextmenu: [], import: [], export: [], process: [] })); } return EditorEvents; }(Events); var Drag = /*#__PURE__*/ function () { function Drag(el) { var onTranslate = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {}; var onStart = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : function () {}; var onDrag = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : function () {}; _classCallCheck(this, Drag); this.pointerStart = null; this.el = el; this.onTranslate = onTranslate; this.onStart = onStart; this.onDrag = onDrag; this.initEvents(el); } _createClass(Drag, [{ key: "initEvents", value: function initEvents(el) { el.style.touchAction = 'none'; el.addEventListener('pointerdown', this.down.bind(this)); window.addEventListener('pointermove', this.move.bind(this)); window.addEventListener('pointerup', this.up.bind(this)); } }, { key: "down", value: function down(e) { e.stopPropagation(); this.pointerStart = [e.pageX, e.pageY]; this.onStart(e); } }, { key: "move", value: function move(e) { if (!this.pointerStart) return; e.preventDefault(); var _ref = [e.pageX, e.pageY], x = _ref[0], y = _ref[1]; var delta = [x - this.pointerStart[0], y - this.pointerStart[1]]; var zoom = this.el.getBoundingClientRect().width / this.el.offsetWidth; this.onTranslate(delta[0] / zoom, delta[1] / zoom, e); } }, { key: "up", value: function up(e) { if (!this.pointerStart) return; this.pointerStart = null; this.onDrag(e); } }]); return Drag; }(); var Zoom = /*#__PURE__*/ function () { function Zoom(container, el, intensity, onzoom) { _classCallCheck(this, Zoom); this.el = el; this.intensity = intensity; this.onzoom = onzoom; this.distance = null; container.addEventListener('wheel', this.wheel.bind(this)); container.addEventListener('touchmove', this.move.bind(this)); container.addEventListener('touchend', this.end.bind(this)); container.addEventListener('touchcancel', this.end.bind(this)); container.addEventListener('dblclick', this.dblclick.bind(this)); } _createClass(Zoom, [{ key: "wheel", value: function wheel(e) { e.preventDefault(); var rect = this.el.getBoundingClientRect(); var delta = (e.wheelDelta ? e.wheelDelta / 120 : -e.deltaY / 3) * this.intensity; var ox = (rect.left - e.clientX) * delta; var oy = (rect.top - e.clientY) * delta; this.onzoom(delta, ox, oy, 'wheel'); } }, { key: "touches", value: function touches(e) { var _ref = [e.touches[0].clientX, e.touches[0].clientY], x1 = _ref[0], y1 = _ref[1]; var _ref2 = [e.touches[1].clientX, e.touches[1].clientY], x2 = _ref2[0], y2 = _ref2[1]; var distance = Math.sqrt(Math.pow(x1 - x2, 2) + Math.pow(y1 - y2, 2)); return { cx: (x1 + x2) / 2, cy: (y1 + y2) / 2, distance: distance }; } }, { key: "move", value: function move(e) { if (e.touches.length < 2) return; var rect = this.el.getBoundingClientRect(); var _this$touches = this.touches(e), cx = _this$touches.cx, cy = _this$touches.cy, distance = _this$touches.distance; if (this.distance !== null) { var delta = distance / this.distance - 1; var ox = (rect.left - cx) * delta; var oy = (rect.top - cy) * delta; this.onzoom(delta, ox, oy, 'touch'); } this.distance = distance; } }, { key: "end", value: function end() { this.distance = null; } }, { key: "dblclick", value: function dblclick(e) { e.preventDefault(); var rect = this.el.getBoundingClientRect(); var delta = 4 * this.intensity; var ox = (rect.left - e.clientX) * delta; var oy = (rect.top - e.clientY) * delta; this.onzoom(delta, ox, oy, 'dblclick'); } }]); return Zoom; }(); var Area = /*#__PURE__*/ function (_Emitter) { _inherits(Area, _Emitter); function Area(container, emitter) { var _this; _classCallCheck(this, Area); _this = _possibleConstructorReturn(this, _getPrototypeOf(Area).call(this, emitter)); _defineProperty(_assertThisInitialized(_this), "el", void 0); _defineProperty(_assertThisInitialized(_this), "container", void 0); _defineProperty(_assertThisInitialized(_this), "transform", { k: 1, x: 0, y: 0 }); _defineProperty(_assertThisInitialized(_this), "mouse", { x: 0, y: 0 }); _defineProperty(_assertThisInitialized(_this), "_startPosition", null); var el = _this.el = document.createElement('div'); _this.container = container; el.style.transformOrigin = '0 0'; new Zoom(container, el, 0.1, _this.onZoom.bind(_assertThisInitialized(_this))); new Drag(container, _this.onTranslate.bind(_assertThisInitialized(_this)), _this.onStart.bind(_asse