88 lines
2.1 KiB
TypeScript
88 lines
2.1 KiB
TypeScript
import {
|
|
IReduxed,
|
|
TAsyncified,
|
|
TReduxed,
|
|
TResolvedActions,
|
|
TAllActions,
|
|
TReduxHandlers,
|
|
} from './types'
|
|
import {createRemoteClient} from './remote'
|
|
|
|
export function createActions<T, ActionType extends string>(
|
|
client: TAsyncified<T>,
|
|
type: ActionType,
|
|
) {
|
|
const service = Object.keys(client).reduce((obj, method: any) => {
|
|
obj[method] = function makeAction(...args: any[]) {
|
|
const payload = ((client as any)[method])(...args)
|
|
return {
|
|
payload,
|
|
type,
|
|
method,
|
|
status: 'pending',
|
|
}
|
|
}
|
|
return obj
|
|
}, {} as any)
|
|
|
|
return service as TReduxed<T, ActionType>
|
|
}
|
|
|
|
export interface IState {
|
|
loading: number
|
|
error: string
|
|
}
|
|
|
|
export function createReducer<ActionType extends string, State extends IState>(
|
|
actionType: ActionType,
|
|
defaultState: State,
|
|
) {
|
|
|
|
const self = {
|
|
withHandler<R extends IReduxed<ActionType>>(
|
|
handleAction: (state: State, action: TResolvedActions<R>) => State,
|
|
): (state: State | undefined, action: TAllActions<R>) => State {
|
|
return (state: State = defaultState, action: TAllActions<R>): State => {
|
|
if (action.type !== actionType) {
|
|
return state
|
|
}
|
|
if (action.status === 'pending') {
|
|
return {
|
|
...state,
|
|
loading: state.loading + 1,
|
|
error: '',
|
|
}
|
|
}
|
|
if (action.status === 'rejected') {
|
|
return {
|
|
...state,
|
|
loading: state.loading - 1,
|
|
error: action.payload.message,
|
|
}
|
|
}
|
|
return handleAction({
|
|
...state,
|
|
loading: state.loading - 1,
|
|
error: '',
|
|
}, action)
|
|
}
|
|
},
|
|
withMapping<R extends IReduxed<ActionType>>(
|
|
handlers: TReduxHandlers<R, State>,
|
|
) {
|
|
return self.withHandler<R>((state, action) => {
|
|
if (action.method in handlers) {
|
|
const newState = handlers[action.method](state, action)
|
|
return {
|
|
...state,
|
|
...newState,
|
|
}
|
|
}
|
|
return state
|
|
})
|
|
},
|
|
}
|
|
|
|
return self
|
|
}
|