1.5.7 • Published 4 years ago

redux-land v1.5.7

Weekly downloads
4
License
MIT
Repository
github
Last release
4 years ago

redux-land

intuitive middleware for redux.

Build Status License: MIT

Install

yarn add redux-land

or

npm install --save redux-land

Features

Usage

import { createStore, applyMiddleware } from 'redux';
import createLandMiddleware from 'redux-land';

// action types 
const INC      = "INC";
const ASYNCINC = "ASYNCINC";

// reducer
const reducer = (state = {counter: 0}, action) => {
  switch(action.type){
    case INC:
      return {...state, counter: state.counter + 1 }
    default:
      return {...state}
  }
}

function sleep(ms) {
  return new Promise(resolve => setTimeout(resolve, ms));
}

const asyncInc = async function* ({state,action}) {
  await sleep(1000);
  yield {type: INC}; // this action will be dispatched.
  await sleep(action.payload);
  yield {type: INC};// you can dispatch action, any number of times
}


const landMiddleware = createLandMiddleware({
  [ASYNCINC] : asyncInc, // object-with-dynamic-keys
});

const store = createStore(reducer,applyMiddleware(landMiddleware));

// later
store.dispatch({
  type: ASYNCINC,
  payload: 3000,
});

Usage (TypeScript)

types.ts

import { Action } from "redux";

export type State = {
  loaded: boolean;
  status: boolean;
};

export enum ActionType {
  LOADING = "LOADING",
  LOADED  = "LOADED",
  SUCCESS = "SUCCESS",
  FAILED  = "FAILED",
}

export type LOADING = Action<ActionType.LOADING>;
export type LOADED  = Action<ActionType.LOADED>;
export type SUCCESS = Action<ActionType.SUCCESS>;
export type FAILED  = Action<ActionType.FAILED>;

export enum LandActionType {
  LOAD = "LOAD"
}

export type LOAD = Action<LandActionType.LOAD> & {
  payload: string;
};

export type Actions = LOADING | LOADED | SUCCESS | FAILED | LOAD;

module.ts

import { createStore, applyMiddleware } from "redux";
import createLandMiddleware, { Land, Lands } from "redux-land";
import axios from "axios";
import {
  State,
  ActionType,
  Actions,
  LandActionType,
  LOAD
} from "./types";

const load: Land<State, LOAD, Actions> = async function*({ state, action }) {
  yield {type: ActionType.LOADING};
  try {
    const { status } = (await axios(action.payload));
    if (status >= 200 && status < 300) {
      yield {type: ActionType.SUCCESS};
    } else {
      yield {type: ActionType.FAILED};
    }
  } catch {
    yield {type: ActionType.FAILED};
  }  
  yield {type: ActionType.LOADED};
};

const lands : Lands<typeof LandActionType, State, LOAD, Actions> = {
  [LandActionType.LOAD]: load
}

const middleware = createLandMiddleware<typeof LandActionType>(lands);

const reducer = (state: State = { loaded: true, status: true }, action: Actions) => {
  switch (action.type) {
    case ActionType.LOADING:
      return { ...state, loaded: false };
    case ActionType.LOADED:
      return { ...state, loaded: true };
    case ActionType.SUCCESS:
      return { ...state, status: true };
    case ActionType.FAILED:
      return { ...state, status: false };
    default:
      return state;
  }
};

const store = createStore(reducer, applyMiddleware(middleware));

export default store;

index.ts

import store from "./module";
import { LandActionType } from "./types";

store.dispatch({
  type: LandActionType.LOAD,
  payload: "https://www.sample.com/"
});

Dependency Injection

module.ts

...

type Dep = {
  axios: typeof axios
}

const load: Land<State, LOAD, Actions, Dep> = async function*({ state, action }, { axios }) { ...

export const lands : Lands<typeof LandActionType, State, LOAD, Actions, Dep> = { ...
...

const middleware = createLandMiddleware(lands, { axios });

export const reducer = ...;

...

__tests__/module.spec.ts

...

import { lands } from '../module';
const middleware = createLandMiddleware(lands, {
  axios: (url: string) => Promise.resolve({
    status: 200,// you can test on success.
  }),
});

...

For unit test

...

const itr = load({
  state: {
    loaded: true,
    status: true,
  },
  action: {
    type: LandActionType.LOAD,
    payload: "https://www.sample.com/",
  },
},{
  axios: (url: string) => Promise.resolve({
    status: 200,// you can test on success.
  }),
});
const {value} = await itr.next();
expect(value).toEqual({type: ActionType.LOADING});
...

License

MIT

1.5.7

4 years ago

1.5.6

5 years ago

1.5.5

5 years ago

1.5.4

5 years ago

1.5.3

5 years ago

1.5.2

5 years ago

1.5.1

5 years ago

1.5.0

5 years ago

1.4.0

5 years ago

1.3.1

5 years ago

1.3.0

5 years ago

1.2.0

5 years ago

1.1.6

5 years ago

1.1.5

5 years ago

1.1.4

5 years ago

1.1.3

5 years ago

1.1.2

5 years ago

1.1.1

5 years ago

1.1.0

5 years ago

1.0.0

5 years ago