UNPKG

events-observer

Version:
309 lines (265 loc) 10.4 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() : typeof define === 'function' && define.amd ? define(factory) : (global.EventsObserver = factory()); }(this, (function () { 'use strict'; var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; var classCallCheck = function (instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }; var createClass = 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); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); var _order = Symbol('_order'); var _processPromise = Symbol('_processPromise'); var OrderServer = function () { function OrderServer() { classCallCheck(this, OrderServer); this[_order] = []; this[_processPromise] = new Promise(function (resolve) { return resolve(); }); } createClass(OrderServer, [{ key: 'push', value: function push(name, element) { this[_order].push(name); this[name] = element; } }, { key: 'delete', value: function _delete(name) { var _this = this; this[_processPromise].then(function () { var index = _this[_order].findIndex(function (_name) { return _name === name; }); _this[_order].splice(index, 1); delete _this[name]; }); } }, { key: 'check', value: function check(name) { return this.hasOwnProperty(name); } }, { key: 'getItem', value: function getItem(name) { return this[name]; } }, { key: 'eachInOrder', value: async function eachInOrder(callback) { var resolve = function resolve() {}; this[_processPromise] = new Promise(function (_resolve) { // open closure to resolve after async operations resolve = _resolve; }); var _iteratorNormalCompletion = true; var _didIteratorError = false; var _iteratorError = undefined; try { for (var _iterator = this[_order][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) { name = _step.value; await callback(name, this[name]); } } catch (err) { _didIteratorError = true; _iteratorError = err; } finally { try { if (!_iteratorNormalCompletion && _iterator.return) { _iterator.return(); } } finally { if (_didIteratorError) { throw _iteratorError; } } } resolve(); } }]); return OrderServer; }(); var _separator = Symbol('_separator'); var _state = Symbol('_handlersState'); var _prefix = Symbol('_prefix'); var _handlerCounter = Symbol('_handlerCounter'); var _createHandlerId = Symbol('_createHandlerId'); var _createHandlerObject = Symbol('_createHandlerObject'); var _parsePath = Symbol('_parsePath'); var _walkRecursive = Symbol('_walkRecursive'); var _callTreeRecursive = Symbol('_callTreeRecursive'); var Observer = function () { function Observer() { var separator = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : '.'; var prefix = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : '__handler_id_'; classCallCheck(this, Observer); this[_separator] = separator; this[_state] = new OrderServer(); this[_prefix] = prefix; this[_handlerCounter] = 0; } createClass(Observer, [{ key: _createHandlerId, value: function value() { return this[_prefix] + this[_handlerCounter]++; } }, { key: _createHandlerObject, value: function value(handler, callLimit) { return { handlerId: this[_createHandlerId](), handler: handler, callLimit: callLimit, callCounter: 0 }; } }, { key: _parsePath, value: function value(eventPath) { var pathArray = void 0; if (typeof eventPath !== 'string') { throw new Error('Event path type isn\'t correct (' + (typeof eventPath === 'undefined' ? 'undefined' : _typeof(eventPath)) + '), expected type - string'); } pathArray = eventPath.split(this[_separator]); if (pathArray.findIndex(function (value) { return value === ''; }) !== -1) { throw new Error('Event path can\'t consists of empty values'); } return pathArray; } }, { key: _walkRecursive, value: function value(_ref) { var path = _ref.path, createIfEmpty = _ref.createIfEmpty, state = _ref.state, destinationCallback = _ref.destinationCallback, params = _ref.params; var isLast = path.length <= 1, eventName = path.shift(), // returns first element hasEvent = state.check(eventName); if (!hasEvent && createIfEmpty) { state.push(eventName, new OrderServer()); hasEvent = true; } if (isLast) { hasEvent && destinationCallback({ state: state, eventName: eventName, params: params }); } else { state = state.getItem(eventName); this[_walkRecursive]({ path: path, createIfEmpty: createIfEmpty, state: state, destinationCallback: destinationCallback, params: params }); } } }, { key: _callTreeRecursive, value: function value(_ref2) { var state = _ref2.state, eventName = _ref2.eventName, params = _ref2.params; // to avoid context issue var _callTreeRecursive = function _callTreeRecursive(_ref3) { var state = _ref3.state, eventName = _ref3.eventName, params = _ref3.params; return new Promise(async function (resolve) { state = eventName && state[eventName] ? state[eventName] : state; await state.eachInOrder(async function (name, element) { if (element.handler) { await element.handler(params); ++element.callCounter; if (element.callLimit && element.callCounter >= element.callLimit) { state.delete(name); } } else { // it is event, try recursion again await _callTreeRecursive({ state: element, params: params }); } }); resolve(); }); }; _callTreeRecursive({ state: state, eventName: eventName, params: params }); } }, { key: 'on', value: function on(event, handler) { var callLimit = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : null; var path = this[_parsePath](event), handlerObject = this[_createHandlerObject](handler, callLimit); this[_walkRecursive]({ path: path, createIfEmpty: true, state: this[_state], destinationCallback: function destinationCallback(_ref4) { var state = _ref4.state, eventName = _ref4.eventName; var newState = state.getItem(eventName); newState.push(handlerObject.handlerId, handlerObject); } }); } }, { key: 'off', value: function off(event) { var path = this[_parsePath](event); this[_walkRecursive]({ path: path, state: this[_state], destinationCallback: function destinationCallback(_ref5) { var state = _ref5.state, eventName = _ref5.eventName; state.delete(eventName); } }); } }, { key: 'once', value: function once(event, handler) { this.on(event, handler, 1); } }, { key: 'trigger', value: function trigger(event, params) { var path = this[_parsePath](event); this[_walkRecursive]({ path: path, state: this[_state], params: params, destinationCallback: this[_callTreeRecursive] }); } }]); return Observer; }(); return Observer; })));