Coder Social home page Coder Social logo

usm's Introduction

USM

Travis npm

USM is a universal state modular library. It can help you make more concise OOP when using some state library, and it currently supports Redux, MobX, Vuex and Angular.

You don't have to learn so many state libraries, one is enough.

Table of Contents

Support

Libraries/Frameworks None Redux MobX Vuex Angular2+
Status

Features

  • Universal State Management
  • Standardized Module Lifecycle
  • Optional Event System
  • Support Stateless Model
  • Support React/Vue/Angular

Usage

To install usm:

yarn add usm # npm install --save usm

And if you want to use Redux/MobX/Vuex, just install usm-redux/usm-mobx/usm-vuex correspondingly.

Pros

Here is the Redux todo example:

import { createStore, combineReducers } from 'redux'

// action
let nextTodoId = 0
const addTodo = text => {
  return {
    type: 'ADD_TODO',
    id: nextTodoId++,
    text
  }
}

const setVisibilityFilter = filter => {
  return {
    type: 'SET_VISIBILITY_FILTER',
    filter
  }
}

const toggleTodo = id => {
  return {
    type: 'TOGGLE_TODO',
    id
  }
}

// reducers
const todos = (state = [], action) => {
  switch (action.type) {
    case 'ADD_TODO':
      return [
        ...state,
        {
          id: action.id,
          text: action.text,
          completed: false
        }
      ]
    case 'TOGGLE_TODO':
      return state.map(todo =>
        (todo.id === action.id) 
          ? {...todo, completed: !todo.completed}
          : todo
      )
    default:
      return state
  }
}

const visibilityFilter = (state = 'SHOW_ALL', action) => {
  switch (action.type) {
    case 'SET_VISIBILITY_FILTER':
      return action.filter
    default:
      return state
  }
}

const todoApp = combineReducers({
  todos,
  visibilityFilter
})

With usm-redux it can be more concise:

import Module, { state, action } from 'usm-redux'

class TodoList extends Module {
  @state todos = []
  @state visibilityFilter = 'SHOW_ALL'
  nextTodoId = 0

  @action
  add(text, state) {
    this.nextTodoId++
    state.todos.push({
      text,
      id: this.nextTodoId,
      completed: false,
    })
  }

  @action
  toggle(id, state) {
    const todo = state.todos.find(todo => todo.id === id)
    todo.completed = !todo.completed
  }

  @action
  setVisibility(filter, state) {
    state.visibilityFilter = filter
  }
}

USM will help you a lot on object-oriented programming using Redux, Vuex, MobX, etc.

Articles

Examples

class Counter extends Module {
  @state count = 0;

  @action
  increase(state) {
    state.count += 1;
  }

  @action
  decrease(state) {
    state.count -= 1;
  }
}

const counter = Counter.create();

counter.increase();
counter.decrease();

Using different wrapper libraries:

import Module, { action, state } from 'usm'; // using Native Module/Angular
import Module, { action, state } from 'usm-redux'; // using Redux
import Module, { action, state } from 'usm-mobx'; // using MobX
import Module, { action, state } from 'usm-vuex'; // using Vuex

More examples:

APIs

Decorators

usm provides different kinds of decorators:

  • @state to wrap a variable with a state.
  • @action is used to wrap a function that changes state (the last parameter passed in by the function is always the current state object).
  • @computed is used in state computed, and it must be an computed function array(You can also use it for a getter with usm-vuex or usm-mobx).
class Shop extends Module {
  @state goods = [];
  @state status = 'close';

  @action
  operate(item, status, state) {
    state.goods.push(item);
    state.status = status;
  }
  // call -> this.operate({ name: 'fruits', amount: 10 }, 'open');

  @computed
  shortages = [
    () => this.goods,
    (goods) => goods.filter(item => item.amount < 5)
  ];
}

Module lifecycle

usm provides these lifecycle hooks:

  • moduleWillInitialize
  • moduleWillInitializeSuccess
  • moduleDidInitialize
  • moduleWillReset
  • moduleDidReset

Note:

If you need to run the USM-based module directly, you must use the module's create method, just like this:

class Something extends Module {}
const thing = Something.create();

And if the module is just initialized, the internal lifecycle hooks will not be called. If a module depends on more than one modules, these modules have to be initialized before the curent module.

class Foo extends Module {}
class Bar extends Module {}
class FoobarFactory extends Module {}
const foo = new Foo();
const bar = new Bar({
  modules: {
    foo,
  },
});
const foobarFactory = FoobarFactory.create({
  modules: {
    foo,
    bar
  },
});

USM does not provide module dependency management, you have to manage dependencies youself like the example above. And you are stronglly recommended to introduct external dependency injection libs to manage dependencies automatically, it will make you life easir. For example, using InversifyJS. If you use Angular, you will be able to use Angualr's dependency injection directly.

FAQ

1. Can I continue to use the Redux or Vuex plug-in if I use usm?

Of course, you can, but usm will soon define its own plug-in APIs to ensure that there is a universal plug-in that can be used.

usm-redux using Redux's middleware example:

class ModuleWithMiddleware extends Module {
  static _generateStore({ createStore }, { reducers }) {
    return createStore(reducers, applyMiddleware(...reduxMiddlewares));
  }
}

usm-vuex using Vuex's plugin example:

class ModuleWithPlugin extends Module {
  plugins = [...vuexPlugins];
}

2. Does it look like usm-redux is a state library of mutable type?

Yes, because Redux immutable operation is not convenient enough, so usm introduced immer. Generally, single-action items are less than 50K, then it comes with a tiny loss of performance which can be ignored most of the time. For more on performance issues that immer brings, please check it out here.

3. How do you ensure that you use usm to switch between different states libraries(usm-redux/usm-vuex/usm-mobx) and that they are running consistently?

usm is not a state library, we are trying to turn it into a standardized state library runner, usm defines only generic modules. Based on such a module, any state library based on the usm encapsulation can run well.

usm's People

Contributors

unadlib avatar futurechallenger avatar

Watchers

James Cloos avatar ishan avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.