redux-observable-sans
Version:
Use redux without any boilerplate
89 lines (77 loc) • 2.9 kB
JavaScript
;
var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };
import { ofType } from 'redux-observable';
import { map } from 'rxjs/operators';
import { camelCase, constantCase } from 'change-case';
export var baseEpic = function baseEpic(type) {
var typeUc = constantCase(type);
var typeLc = camelCase(type);
return function (socket, tokenFn) {
var addToken = typeof tokenFn !== 'function' ? function (payload) {
return payload;
} : function (payload, state$, deps) {
return Object.assign(payload, tokenFn(state$, deps));
};
return function (action$, state$, deps) {
return action$.pipe(ofType(typeUc), map(function (_ref) {
var payload = _ref.payload;
var all = addToken(payload, state$, deps);
socket.emit(typeLc, all);
return _extends({}, payload, {
type: constantCase(payload.type)
});
}));
};
};
};
/**
* commandEpic
* Listens for `COMMAND` actions,
* then emits a `command` event via socket (with token if tokenFn defined)
* then emits a "CONVERTED_COMMAND" redux action
*
* eg, { type: `COMMAND`, payload: { type: `doSomething`, data: `whatevs` }}
* causes socket.emit(`command`, { type: doSomething, data: `whatevs`, token: { ... } })
* and returns { type: `DO_SOMETHING`, payload: `whatevs` }
*/
export var commandEpic = baseEpic('command');
export var commandAction = function commandAction(dispatch) {
return function (type) {
return function (payload) {
return dispatch({ type: 'COMMAND', payload: { type: type, payload: payload } });
};
};
};
/**
* queryEpic
* Listens for `QUERY` actions,
* then emits a `query` event via socket (with token if tokenFn defined)
* then emits a "CONVERTED_COMMAND" redux action
*
* eg, see commandEpic example
*/
export var queryEpic = baseEpic('query');
export var queryAction = function queryAction(dispatch) {
return function (type) {
return function (payload) {
return dispatch({ type: 'QUERY', payload: { type: type, payload: payload } });
};
};
};
export var socketEpics = function socketEpics(socket, tokenFn) {
return [commandEpic(socket, tokenFn), queryEpic(socket, tokenFn)];
};
// handle events sent form backend
export var toAction = function toAction(dispatch) {
return function (data) {
var type = constantCase(data.type);
var reduxAction = _extends({}, data, { type: type });
dispatch(reduxAction);
if (data.type === 'CommandRejected' || data.type === 'QueryRejected') {
var reduxActionFailure = _extends({}, data.payload, {
type: constantCase(data.payload.type) + '_FAILURE'
});
dispatch(reduxActionFailure);
}
};
};