hbus
Version:
An event bus lib.
266 lines (245 loc) • 9.07 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(factory((global.HBus = {})));
}(this, (function (exports) { 'use strict';
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 Action = function Action(type, payload) {
classCallCheck(this, Action);
this.type = type;
this.payload = payload;
};
function createActionFactory(type, defaultPayload) {
var defaultPayloadIsObject = defaultPayload instanceof Object;
return function (payload) {
return new Action(type, defaultPayloadIsObject && payload instanceof Object ? Object.assign({}, defaultPayload, payload) : payload);
};
}
function createProcessor(processorMap, defaultProcessor) {
return function (state, action) {
var type = action.type;
return type in processorMap ? processorMap[type](state, action) : defaultProcessor ? defaultProcessor(state, action) : state;
};
}
var defaultComparer = function defaultComparer(oldState, newState) {
if (oldState === newState && String(oldState) === String(newState) || oldState !== oldState && newState !== newState) {
return true;
} else {
if (!(oldState instanceof Object && newState instanceof Object)) {
return false;
}
for (var oldKey in oldState) {
if (!(oldKey in newState && defaultComparer(oldState[oldKey], newState[oldKey]))) {
return false;
}
}
for (var newKey in newState) {
if (!(newKey in oldState)) {
return false;
}
}
return true;
}
};
var defaultTickMethod = function defaultTickMethod(callback) {
requestAnimationFrame(callback);
};
var ticker = {
tickMethod: defaultTickMethod,
_willTick: false,
_callbacks: new Array(),
tick: function tick(callback) {
ticker._callbacks.push(callback);
if (!ticker._willTick) {
ticker._willTick = true;
ticker.tickMethod(function () {
ticker._willTick = false;
var _callbacks = ticker._callbacks;
_callbacks.forEach(function (cb) {
cb();
});
_callbacks.length = 0;
});
}
}
};
var Bus = function () {
function Bus(processor) {
var defaultState = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
classCallCheck(this, Bus);
this.processor = processor;
this.comparer = defaultComparer;
this._stateRequestCallbacks = new Array();
this._willUpdate = false;
this._actions = new Array();
this._subscriberMap = new Map();
this._subscribers = new Array();
this._state = defaultState;
}
createClass(Bus, [{
key: "_requestUdpate",
value: function _requestUdpate() {
var _this = this;
if (!this._willUpdate) {
this._willUpdate = true;
ticker.tick(function () {
_this._willUpdate = false;
_this._update();
var _stateRequestCallbacks = _this._stateRequestCallbacks,
_state = _this._state;
_stateRequestCallbacks.forEach(function (callback) {
callback(_state);
});
_stateRequestCallbacks.length = 0;
});
}
}
}, {
key: "_update",
value: function _update() {
var processor = this.processor,
comparer = this.comparer,
_state = this._state,
_actions = this._actions,
_subscriberMap = this._subscriberMap;
// @ts-ignore
var newState = _state instanceof Object ? Object.create(_state) : _state,
t = void 0;
_actions.forEach(function (action) {
t = processor(newState, action);
if (t !== undefined) {
newState = t;
}
});
_actions.length = 0;
this._state = newState;
var hasChanged = false;
_subscriberMap.forEach(function (subscribers, propName) {
var prop = newState[propName];
if (!comparer(prop, _state[propName])) {
hasChanged = true;
subscribers.forEach(function (subscriber) {
subscriber(prop);
});
}
});
if (hasChanged || !comparer(_state, newState)) {
this._subscribers.forEach(function (subscriber) {
subscriber(newState);
});
}
}
}, {
key: "getState",
value: function getState() {
return this._state;
}
}, {
key: "requestState",
value: function requestState(callback) {
this._stateRequestCallbacks.push(callback);
this._requestUdpate();
return this;
}
}, {
key: "publish",
value: function publish(action) {
this._actions.push(action);
this._requestUdpate();
return this;
}
}, {
key: "subscribe",
value: function subscribe(subscriber) {
this._subscribers.push(subscriber);
return this;
}
}, {
key: "unsubscribe",
value: function unsubscribe(subscriber) {
var _subscribers = this._subscribers,
index = _subscribers.indexOf(subscriber);
if (index >= 0) {
_subscribers.splice(index, 1);
}
return this;
}
}, {
key: "clearSubscribers",
value: function clearSubscribers() {
this._subscribers.length = 0;
return this;
}
}, {
key: "subscribeProp",
value: function subscribeProp(propName, subscriber) {
var _subscriberMap = this._subscriberMap;
var subscribers = _subscriberMap.get(propName);
if (!subscribers) {
_subscriberMap.set(propName, subscribers = []);
}
subscribers.push(subscriber);
return this;
}
}, {
key: "unsubscribeProp",
value: function unsubscribeProp(propName, subscriber) {
var _subscriberMap = this._subscriberMap,
subscribers = _subscriberMap.get(propName);
if (subscribers) {
var index = subscribers.indexOf(subscriber);
if (index >= 0) {
subscribers.splice(index, 1);
}
}
return this;
}
}, {
key: "clearPropSubscribers",
value: function clearPropSubscribers(propName) {
this._subscriberMap.delete(propName);
return this;
}
}, {
key: "clearAllPropSubscribers",
value: function clearAllPropSubscribers() {
this._subscriberMap.clear();
return this;
}
}, {
key: "clearAllSubscribers",
value: function clearAllSubscribers() {
return this.clearSubscribers().clearAllPropSubscribers();
}
}]);
return Bus;
}();
exports.Action = Action;
exports.createActionFactory = createActionFactory;
exports.createProcessor = createProcessor;
exports.defaultComparer = defaultComparer;
exports.defaultTickMethod = defaultTickMethod;
exports.ticker = ticker;
exports.Bus = Bus;
Object.defineProperty(exports, '__esModule', { value: true });
})));