import { ActionCallback, ActionDispatcher, AsyncActionCreator, AsyncActionDispatcher, AvailableCreator, AvailableType, PromiseCreator, } from "../types"; function asyncActionFactory( type: string, promise: T, args: Parameters ): AsyncActionDispatcher>> { return (dispatch) => { dispatch({ type, payload: { loading: true, parameters: args, }, }); return new Promise((resolve, reject) => { promise(...args) .then((val) => { dispatch({ type, payload: { loading: false, item: val, parameters: args, }, }); resolve(); }) .catch((err) => { dispatch({ type, error: true, payload: { loading: false, item: err, parameters: args, }, }); reject(err); }); }); }; } export function createAsyncAction( type: string, promise: T ) { return (...args: Parameters) => asyncActionFactory(type, promise, args); } // Create a action which combine multiple ActionDispatcher and execute them at once function combineActionFactory( dispatchers: AvailableType[] ): ActionDispatcher { return (dispatch) => { dispatchers.forEach((fn) => { if (typeof fn === "function") { fn(dispatch); } else { dispatch(fn); } }); }; } export function createCombineAction(fn: T) { return (...args: Parameters) => combineActionFactory(fn(...args)); } function combineAsyncActionFactory( dispatchers: AsyncActionDispatcher[] ): AsyncActionDispatcher { return (dispatch) => { const promises = dispatchers.map((v) => v(dispatch)); return Promise.all(promises) as Promise; }; } export function createAsyncCombineAction(fn: T) { return (...args: Parameters) => combineAsyncActionFactory(fn(...args)); } export function callbackActionFactory( dispatchers: AsyncActionDispatcher[], success: ActionCallback, error?: ActionCallback ): ActionDispatcher { return (dispatch) => { const promises = dispatchers.map((v) => v(dispatch)); Promise.all(promises) .then(() => { const action = success(); if (action !== undefined) { dispatch(action); } }) .catch(() => { const action = error && error(); if (action !== undefined) { dispatch(action); } }); }; } export function createCallbackAction( fn: T, success: ActionCallback, error?: ActionCallback ) { return (...args: Parameters) => callbackActionFactory(fn(args), success, error); }