UNPKG

core-native

Version:

A lightweight framework based on React Native + Redux + Redux Saga, in strict TypeScript.

86 lines (72 loc) 2.35 kB
import {type Action as ReduxAction, combineReducers, type Reducer} from "redux"; // Redux State interface LoadingState { [loading: string]: number; } export interface State { loading: LoadingState; app: { [key: string]: object; }; } // Redux Action const SET_STATE_ACTION = "@@framework/setState"; export interface Action<P> extends ReduxAction<string> { payload: P; name?: typeof SET_STATE_ACTION; } // Redux Action: SetState (to update state.app) interface SetStateActionPayload { module: string; state: any; } // state must be complete module state, not partial export function setStateAction(module: string, state: object, type: string): Action<SetStateActionPayload> { return { type, name: SET_STATE_ACTION, payload: {module, state}, }; } function setStateReducer(state: State["app"] = {}, action: Action<any>): State["app"] { // Use action.name for set state action, make type specifiable to make tracking/tooling easier if (action.name === SET_STATE_ACTION) { const {module, state: moduleState} = action.payload as SetStateActionPayload; return {...state, [module]: moduleState}; } return state; } // Redux Action: Loading (to update state.loading) interface LoadingActionPayload { identifier: string; show: boolean; } export const LOADING_ACTION = "@@framework/loading"; export function loadingAction(show: boolean, identifier: string = "global"): Action<LoadingActionPayload> { return { type: LOADING_ACTION, payload: {identifier, show}, }; } function loadingReducer(state: LoadingState = {}, action: Action<LoadingActionPayload>): LoadingState { if (action.type === LOADING_ACTION) { const payload = action.payload as LoadingActionPayload; const count = state[payload.identifier] || 0; return { ...state, [payload.identifier]: count + (payload.show ? 1 : -1), }; } return state; } // Root Reducer export function rootReducer(): Reducer<State> { return combineReducers<State>({ loading: loadingReducer, app: setStateReducer, }); } // Helper function, to determine if show loading export function showLoading(state: State, identifier: string = "global") { return state.loading[identifier] > 0; }