rete
Version:
JavaScript framework
1,843 lines (1,544 loc) • 75.6 kB
JavaScript
/*!
* rete v1.2.2
* (c) 2019 Vitaliy Stoliarov
* Released under the MIT license.
*/
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(_assertThisInitialized(_this)));
_this.container.addEventListener('pointermove'