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

rechyons

v0.9.2

Published

no more verbose actions and reducers

Downloads

4

Readme

Rechyons

stability npm travis dm js-standard-style

Redux is no longer verbose

中文文档(Chinese Document)

Migrate

Because I lost my 2 factor authentic token, this project has moved to https://github.com/zhouhanseng/rechyons

Motivation

Redux has one disadvantage: it is painfully verbose. Each time we want to add a feature, we needed to type a lot of lines for

  • constants
  • action types,
  • action creators,
  • action handlers in the reducer
  • ...

Actually we bear this disadvantage for several years, and the situation seems to be getting worse. See verbose nightmare

It's time to rethink how to use redux. Why you need no Redux Saga

With rechyons, you no longer need the verbose lines above at all

Rechyons makes redux state easy to update and retrieve like normal js object,meanwhile keep its immutable.

// update
hyperstore.user.update({ name: "yourname" });

// retrieve
let username = hyperstore.user.name;

Usage

Example or a little bigger app

$ git clone [email protected]:ZhouHansen/rechyons.git
$ cd rechyons/example
$ yarn install
$ yarn start

Principle (8 minutes to read, easy than you imagine)

Install

Support both typescript and javascript

$ npm install rechyons

Antecedent

// your app tsconfig.json
{
  "compilerOptions": {
    "strict": false
  }
}

Setup redux store and rechyons

rechyons generate action and reducer for each of the state fields. Shape your initState's structure to this:

{
  moduleA: {keyA: somevalue, keyB: somevalue, keyC: somevalue},
  moduleB: {keyA: somevalue, keyB: somevalue, keyC: somevalue},
}

rechyons exports two functions rechyons.reducer() and rechyons().

rechyons.reducer() takes your init state to generate 'user/name', 'user/age', 'animal/category', 'animal/weight' four pair of action and reducer automatically. Then return the reducers to redux.combineReducers to create the store.

rechyons() swallows store.dispatch for calling the designated actions.

// store.ts
import { createStore, combineReducers } from "redux";

import rechyons from "rechyons";

let initState = {
  // moduleA
  user: {
    name: "zhc",
    age: 10,
  },
  // moduleB
  animal: {
    category: "dog",
    weight: 10,
  },
};

export let store = createStore(combineReducers(rechyons.reducer(initState)));

export default rechyons(initState, store.dispatch);

Get, bind and update state in component

rechyons(initState, store.dispatch) returns a hyperstore, hyperstore.user and hyperstore.animal both are instances of Rechyons class.

// TestComponent
import React from "react";
import { connect } from "react-redux";
import hyperstore from "./store";

export interface Props {
  name: string;
}

class TestComponent extends React.Component<Props, {}> {
  constructor(props: Props) {
    super(props);
  }

  render() {
    return (
      <div>
        <button
          data-testid="button"
          onClick={() => {
            hyperstore.user.update("name", "abc");
          }}
        >
          {this.props.name}
        </button>
      </div>
    );
  }
}

const MapStateToProps = (store) => {
  return {
    name: store[hyperstore.user.name],
  };
};

export default connect(MapStateToProps)(TestComponent);

Get data from state

store[hyperstore.user.name] equals to initState.user.name which is "zhc"; store[hyperstore.animal.weight] equals to initState.animal.weight which is 10; So we can use this to MapStateToProps()

Update state

Use hyperstore.user.update("name", "abc") or hyperstore.user.update({"name": "abc"})hyperstore.user.update("name", "abc") 对特指的 action 执行了store.dispatch({type: "user/name", "abc})

API

rechyons.reducer()

type ReducerType = { [key: string]: (state: any, action: AnyAction) => any };
type initStateType = { [key: string]: { [key: string]: any } };

rechyons.reducer: (initState: initStateType) => ReducerType

rechyons.reducer() return the reducers generated from initstate, so it only devotes to create redux store.

export let store = createStore(combineReducers(rechyons.reducer(initState)));

rechyons()

rechyons: (initState: initStateType, dispatch: Dispatch<AnyAction>) => { [key: string]: Rechyons }

Each hyperstore.someModule is a Rechyons instance

import hyperstore, { store } from "./store";
let hyperstore = rechyons(initState, store.dispatch);

// hyperstore.user is one of the Rechyons instances
console.log(hyperstore.user.name); // get the keyname output "user/name"
console.log(store[hyperstore.user.name]); // get the value output "zhc"

hyperstore.user.update({ name: "abc", age: 20 }); // change state
console.log(hyperstore.user.name); // output "abc"

Verbose nightmare

I want to add a like feature ❤ on the image people post in a social app like twitter.

export default {
  state: {
    //...
  },
  effects: {
    //... Thousands of lines
    *toggleLike({ payload }, { call, put }) {
      const { isLiked, id } = payload;
      if (isLiked) {
        yield call(services.setLike, id);
      } else {
        yield call(services.setUnLike, id);
      }
      yield put(toggleLikeSuccess({ id, isLiked }));
    },
  },
  reducer: {
    //...
  },
};

In models/somemodule.js, add a generator to commit actions in effects object.

export function toggleLikeSuccess({ id, isLiked }) {
  return {
    type: "toggleLikeSuccess",
    payload: {
      id,
      isLiked,
    },
  };
}

In actions/somemodule.js, define a new action.

export default {
  state: {
    //...
  },
  effects: {
    //... Thousands of lines
  },
  reducer: {
    //...Thousands of lines
    toggleLikeSuccess(state, { payload }) {
      const { id, isLiked } = payload;
      return {
        ...state,
        list: list.map((item) => {
          if (item.id === id) {
            const newLikeNum = isLiked ? item.like_num + 1 : item.like_num - 1;
            return {
              ...item,
              is_liked: isLiked,
              like_num: newLikeNum > 0 ? newLikeNum : 0,
            };
          }
          return item;
        }),
      };
    },
  },
};

In models/somemodule.js, add a reducer in reducer object.

const mapDispatchToProps = (dispatch) => ({
  dispatch,
  toggleLikeMyImgTxt: compose(
    dispatch,
    // ...
    actions.triggerAction("somemodule/toggleLike")
  ),
});

In components/somecomponent.js, map dispatch to props.

Life is too heavy

License

MIT