UNPKG

@xailabs/altx

Version:

Flux flavor based on alt.js

116 lines (95 loc) 4.7 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = bindCalls; var _decorators = require('alt-utils/lib/decorators'); var _flatten = require('../utils/flatten'); var _flatten2 = _interopRequireDefault(_flatten); var _logging = require('../utils/logging'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /** * Decorates a store with any number of call definitions. */ function bindCalls() { for (var _len = arguments.length, args = Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } return function decorate(storeClass) { var calls = (0, _flatten2.default)(args); calls.forEach(function (call) { return decorateStoreWithCall(storeClass, call); }); return storeClass; }; } /** * Decorates a store with a single call definition. * Attaches the dataSource specified in the call definition using alt's datasource decorator. * Creates and binds a handler function for all reducers and actions specified in the call definition. */ function decorateStoreWithCall(storeClass, callDefinition) { var actionNames = Object.keys(callDefinition.actions).reduce(function (result, key) { // remove ACTION_CONSTANT variants generated by alt if (result.indexOf(key.toLowerCase()) === -1) { result.push(key); } return result; }, []); actionNames.forEach(function (reducerName) { bindReducerHandler(reducerName, storeClass, callDefinition); }); } /** * Attaches a single reducer handling to the store. * A new handler method will be created on the store for each action associated * with a reducer (defaults to the action names: loading, error, success). Each handler will pass * the current state and the action payload to the reducer with the same name * and mutate the store with the new state returned by the reducer. * Any sideEffects defined in the call will be executed with a ({state, prevState, payload}) signature. */ function bindReducerHandler(reducerName, storeClass, callDefinition) { var handlerName = '_' + callDefinition.name + '_' + reducerName; if (storeClass.prototype[handlerName]) throw new Error('Duplicate handler "' + handlerName + '"'); storeClass.prototype[handlerName] = function handleCallAction(payload) { var reducer = callDefinition.hasOwnProperty('reducers') && callDefinition.reducers[reducerName]; var sideEffect = callDefinition.hasOwnProperty('sideEffects') && callDefinition.sideEffects[reducerName]; var logging = callDefinition.hasOwnProperty('logging') && callDefinition.logging; var logger = callDefinition.hasOwnProperty('logger') && callDefinition.logger; var isError = payload instanceof Error; if (isError) { if (payload.response && payload.response.body && payload.response.body.message) { logger.error(reducerName, payload.response.body.message); } // logger.debug(payload); } else if (logging || (0, _logging.getLevel)() === _logging.logLevel.FORCE) { logger[isError ? 'error' : 'log'](reducerName, payload && payload.toJS ? payload.toJS() : payload); } var currentState = this.state; var nextState = currentState; if (reducer) { //console.log(`[${handlerName}]`, payload, callDefinition); try { nextState = reducer(currentState, payload); } catch (error) { console.error('Error in reducer (' + callDefinition.name + ', ' + reducerName + ')', error); } } if (reducer && !nextState) console.warn('reducer "' + reducerName + '" in call "' + callDefinition.name + '" did not return a new state. Either you forgot to return it, or you should consider using a sideEffect instead of a reducer if no return value is needed.'); if (nextState) { this.setState(nextState); } if (sideEffect) { setTimeout(function () { try { sideEffect({ state: nextState, prevState: currentState, payload: payload }); } catch (error) { console.error('Error in sideEffect (' + callDefinition.name + ', ' + reducerName + ')', error); } }); } }; var action = callDefinition.actions[reducerName]; var bindActionHandler = (0, _decorators.bind)(action); bindActionHandler(storeClass, handlerName, Object.getOwnPropertyDescriptor(storeClass.prototype, handlerName)); };