redux-code
Version:
Redux helpers for actions and reducers
61 lines (60 loc) • 2.11 kB
JavaScript
/* eslint-disable @typescript-eslint/ban-types */
/* eslint-disable @typescript-eslint/no-explicit-any */
function processResult(type, result) {
// Support redux-thunk
if (result instanceof Function)
return (dispatch) => {
const action = processResult(type, dispatch(result))
return dispatch(action)
}
// Support promises with redux-thunk
if (result instanceof Promise)
return (dispatch) =>
result.then((value) => {
const action = processResult(type, value)
return dispatch(action)
})
if (result === undefined) return { type }
if (result.type !== undefined) return result
return { type, payload: result }
}
/**
* Create an action creator
* @param type an action type
* @param action a source to create an action creator
*/
export function createAction(type, action) {
const creator = (...args) => processResult(type, action(...args))
creator.type = type
creator.toString = () => type
return creator
}
export function createActions(prefix, ...mixins) {
const source = Object.assign(
{},
...mixins.map((mix) =>
Array.isArray(mix) ? Object.fromEntries(mix.map((val) => [val, identity])) : mix,
),
)
const actions = {}
// eslint-disable-next-line prefer-const
for (let [name, payload] of Object.entries(source)) {
const actionType = `${prefix || ''}${name}`
const action = payload instanceof Function ? payload.bind(actions) : () => payload
actions[name] = createAction(actionType, action)
actions[name].type = actionType
}
return actions
}
/**
* Just a helper to create identity actions
* createActions('prefix/', {update:identity, save:identity})
*/
export const identity = (arg) => arg
// export function wrapAsync(action: ActionCreator<any>) {
// const wrapped = function (dispatch: ThunkDispatch<any, any, any>) {}
// wrapped.pending = createAction(`${action.type}:pending`, () => undefined)
// wrapped.fulfilled = createAction(`${action.type}:fulfilled`, () => undefined)
// wrapped.rejected = createAction(`${action.type}:rejected`, (err) => err)
// return wrapped
// }