alt
Version:
A flux implementation
237 lines (192 loc) • 7.21 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _transmitter = require('transmitter');
var _transmitter2 = _interopRequireDefault(_transmitter);
var _functions = require('../functions');
var fn = _interopRequireWildcard(_functions);
function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }
var StoreMixin = {
waitFor: function () {
function waitFor() {
for (var _len = arguments.length, sources = Array(_len), _key = 0; _key < _len; _key++) {
sources[_key] = arguments[_key];
}
if (!sources.length) {
throw new ReferenceError('Dispatch tokens not provided');
}
var sourcesArray = sources;
if (sources.length === 1) {
sourcesArray = Array.isArray(sources[0]) ? sources[0] : sources;
}
var tokens = sourcesArray.map(function (source) {
return source.dispatchToken || source;
});
this.dispatcher.waitFor(tokens);
}
return waitFor;
}(),
exportAsync: function () {
function exportAsync(asyncMethods) {
this.registerAsync(asyncMethods);
}
return exportAsync;
}(),
registerAsync: function () {
function registerAsync(asyncDef) {
var _this = this;
var loadCounter = 0;
var asyncMethods = fn.isFunction(asyncDef) ? asyncDef(this.alt) : asyncDef;
var toExport = Object.keys(asyncMethods).reduce(function (publicMethods, methodName) {
var desc = asyncMethods[methodName];
var spec = fn.isFunction(desc) ? desc(_this) : desc;
var validHandlers = ['success', 'error', 'loading'];
validHandlers.forEach(function (handler) {
if (spec[handler] && !spec[handler].id) {
throw new Error(String(handler) + ' handler must be an action function');
}
});
publicMethods[methodName] = function () {
for (var _len2 = arguments.length, args = Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
var state = _this.getInstance().getState();
var value = spec.local && spec.local.apply(spec, [state].concat(args));
var shouldFetch = spec.shouldFetch ? spec.shouldFetch.apply(spec, [state].concat(args))
/*eslint-disable*/
: value == null;
/*eslint-enable*/
var intercept = spec.interceptResponse || function (x) {
return x;
};
var makeActionHandler = function () {
function makeActionHandler(action, isError) {
return function (x) {
var fire = function () {
function fire() {
loadCounter -= 1;
action(intercept(x, action, args));
if (isError) throw x;
return x;
}
return fire;
}();
return _this.alt.trapAsync ? function () {
return fire();
} : fire();
};
}
return makeActionHandler;
}();
// if we don't have it in cache then fetch it
if (shouldFetch) {
loadCounter += 1;
/* istanbul ignore else */
if (spec.loading) spec.loading(intercept(null, spec.loading, args));
return spec.remote.apply(spec, [state].concat(args)).then(makeActionHandler(spec.success), makeActionHandler(spec.error, 1));
}
// otherwise emit the change now
_this.emitChange();
return value;
};
return publicMethods;
}, {});
this.exportPublicMethods(toExport);
this.exportPublicMethods({
isLoading: function () {
function isLoading() {
return loadCounter > 0;
}
return isLoading;
}()
});
}
return registerAsync;
}(),
exportPublicMethods: function () {
function exportPublicMethods(methods) {
var _this2 = this;
fn.eachObject(function (methodName, value) {
if (!fn.isFunction(value)) {
throw new TypeError('exportPublicMethods expects a function');
}
_this2.publicMethods[methodName] = value;
}, [methods]);
}
return exportPublicMethods;
}(),
emitChange: function () {
function emitChange() {
this.getInstance().emitChange();
}
return emitChange;
}(),
on: function () {
function on(lifecycleEvent, handler) {
if (lifecycleEvent === 'error') this.handlesOwnErrors = true;
var bus = this.lifecycleEvents[lifecycleEvent] || (0, _transmitter2['default'])();
this.lifecycleEvents[lifecycleEvent] = bus;
return bus.subscribe(handler.bind(this));
}
return on;
}(),
bindAction: function () {
function bindAction(symbol, handler) {
if (!symbol) {
throw new ReferenceError('Invalid action reference passed in');
}
if (!fn.isFunction(handler)) {
throw new TypeError('bindAction expects a function');
}
// You can pass in the constant or the function itself
var key = symbol.id ? symbol.id : symbol;
this.actionListeners[key] = this.actionListeners[key] || [];
this.actionListeners[key].push(handler.bind(this));
this.boundListeners.push(key);
}
return bindAction;
}(),
bindActions: function () {
function bindActions(actions) {
var _this3 = this;
fn.eachObject(function (action, symbol) {
var matchFirstCharacter = /./;
var assumedEventHandler = action.replace(matchFirstCharacter, function (x) {
return 'on' + String(x[0].toUpperCase());
});
if (_this3[action] && _this3[assumedEventHandler]) {
// If you have both action and onAction
throw new ReferenceError('You have multiple action handlers bound to an action: ' + (String(action) + ' and ' + String(assumedEventHandler)));
}
var handler = _this3[action] || _this3[assumedEventHandler];
if (handler) {
_this3.bindAction(symbol, handler);
}
}, [actions]);
}
return bindActions;
}(),
bindListeners: function () {
function bindListeners(obj) {
var _this4 = this;
fn.eachObject(function (methodName, symbol) {
var listener = _this4[methodName];
if (!listener) {
throw new ReferenceError(String(methodName) + ' defined but does not exist in ' + String(_this4.displayName));
}
if (Array.isArray(symbol)) {
symbol.forEach(function (action) {
_this4.bindAction(action, listener);
});
} else {
_this4.bindAction(symbol, listener);
}
}, [obj]);
}
return bindListeners;
}()
};
exports['default'] = StoreMixin;
module.exports = exports['default'];