npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

synthetic-redux

v1.1.2

Published

Sets up Redux boilerplate: actions, reducers and redux-saga for most common redux use cases

Downloads

11

Readme

synthetic-redux

Sets up Redux boilerplate: actions, reducers and redux-saga for common API communication use cases

JavaScript Redux License: MIT semantic-release

Given an action type and reducer key the library generates:

  1. Redux Actions: Success, Error & Reset action types
  2. Reducers: Updates Store with loading, success and error states
  3. Redux-Saga: Generates saga-effect that communicates with API and handles success and error responses

Purpose

An application can have multiple API calls. Redux + Redux-Saga is a popular tool to handle these side effects. The redux bits become repetitive over the numerous API calls. This library The use-case the library solves for is -

  1. API call needs to be made
  2. Success response should be reflected in the Redux Store
  3. Error response should be reflected in the Redux Store
  4. Reset action must be provided to reset the Redux Store
  5. Differentiate between Success and Error responses
  6. Handle exceptions in communication (eg. network error)
  7. Reflect exception in the Redux Store

Synthetic Redux

Provides an abstraction over 3 bits of boilerplate-ish code:

  1. SyntheticAction - Access to success, error & reset actions and their generators
  2. SyntheticReducers - Access to loading, error and success States from Redux Store
  3. SyntheticSaga - Generates redux-saga effect that handles Success & Error API responses

API

Initialize =>

const synRedux = new SyntheticRedux(
  {type: <action>, url: <string>, payload: <any> }, 
  reducerKey
);

Cheatsheet

  1. Kick off synthetic action => synRedux.ignite()

  2. Access synthetic reducer => synRedux.reducer

  3. Access synthetic sagaEffect => synRedux.sagaEffect

  4. Set custom defaults for synthetic action(optional) =>

  synRedux.ignite = (customUrl) => synRedux.actions.ignite({
    url: customUrl,
    errorHandler: (err) => CustomLogger.error(err)
  });

Example Usage


const FETCH_TODOS = 'FETCH_TODOS';
const ADD_TODO = 'ADD_TODO';

export const listTodos = new SyntheticRedux({
  payload: {filter: { isDeleted: false }},
  type: FETCH_TODOS,
  url: '/api/v1/todo/list',
}, 'list');

export const addTodo = new SyntheticRedux({
  type: ADD_TODO,
  url: '/api/v1/todo',
}, 'newTodo');

addTodo.igniteWrapper = payload => addTodo.actions.ignite({ payload });

// RootReducer.js
const RootReducer = combineReducers({
  newTodo: addTodo.reducer,
  todos: listTodos.reducer,
});

// RootSaga.js
export default function* RootSaga() {
  const allSagas = [
    addTodo.sagaEffect,
    listTodos.sagaEffect,
  ]
  yield all(allSagas.map(fork));
}

// React Component
export default TodoList = () => {
  const listResponse = useSelector(state => state.todos.list);
  const addResponse = useSelector(state => state.todos.newTodo)
  const dispatch = useDispatch();
  const onAdd = (payload) => {
      dispatch(addTodo.igniteWrapper(payload));
  };
  
  React.useEffect(() => {
    dispatch(listTodos.ignite());
  }, [dispatch]);
  
  React.useEffect(() => {
      if(addResponse?.success) {
          dispatch(addResponse.reset())
      }
  }, [dispatch])
  
  if (listResponse[CATEGORY_NAMES].IGNITE) {
    return <LoadingState/>;
  } else if (listResponse.error) {
    return <ErrorHandler error={listResponse.error}/>;
  } else {
    return <ShowTodos list={listResponse.list} onAdd={onAdd}/>;
  }
};

// React Component

Customizing building blocks of Synthetic Redux:

Synthetic Actions

Redux requires actions as the basis of asynchronous communication. The modus operandi for redux actions is to define:

  1. an Action type (e.g. in Type.js)
  2. a function that generates an object using type: <action> and some payload

Synthetic Actions take in a Base Action Type and generate:

  1. <action>_SUCCESS <action>_ERROR <action>_RESET types
  2. functions that generate the desired Action Object

API

Kick off the action -> synAction.ignite();
Access base action string -> synAction.igniteName; // string Access suffix actions -> synAction.suffixNames; // [string] Access suffix action generators -> synAction.suffixSyntheticActions; // [ { type: string, generator: fn } ]

Example

const FETCH_TODOS = 'FETCH_TODOS';
export const synAction = new SyntheticAction({ 
  type: FETCH_TODOS, 
  url: '/api/v1/todo/list', 
});

Synthetic Reducer

Companion reducer piece to SyntheticActions. Takes in a SyntheticAction and reducer key & returns Redux State handler.

Example

const synReducer = SyntheticReducer(synAction, 'list')
const RootReducer = combineReducers({
  todos: synReducer
});

/* Usage in React Component */
const listResponse = useSelector(state => state.todos.list);
if (listResponse[CATEGORY_NAMES].IGNITE) { return <LoadingState />; }
else if (listResponse.error) { return <ErrorHandler error={listResponse.error} />; }
else { return <ShowTodos list={listResponse.list} />; }

Synthetic Redux-Saga Effect

Companion redux-saga with SyntheticActions and SyntheticReducer Given a SyntheticAction it returns a sagaEffect. The sagaEffect comes embedded with Error & Success Handling

Opinions

  1. Uses takeLatest to execute the effect
  2. Requires the API to respond with { error: <any> } to indicate error
  3. Expects action to be set with an url and payload(opt) for the API call

API

const sagaEffect = SyntheticSagaEffect(synAction);
const todoSaga = yield all([sagaEffect]);
export default function* RootSaga() {
  const allSagas = [todoSaga];
  yield all(allSagas.map(fork));
}