Giter Site home page Giter Site logo

usm's Introduction

USM

Node CI npm

USM is a universal state modular library, supports Redux(4.x), MobX(6.x), Vuex(4.x) and Angular(2.0+).

Motivation

usm provides a generic state model that is class-first, which help us to be OOP at almost no cost and is compatible with the ecology of every state library.

When you don't want to learn the paradigm of any state library, usm can help you use any state library. When your project's business code is based on usm, the architecture will be more flexible.

Support

Libraries/Frameworks None Redux MobX Vuex Angular2+
Status

Installation

To install usm:

yarn add usm # npm install --save usm

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

Usage

  • Use @state to decorate a module state.

  • Use @action to decorate a module method for state changes.

  • Use createStore to create a store.

import { state, action, createStore } from 'usm';
// You can also use `usm-redux`, `usm-mobx`, or`usm-vuex`.

class Counter {
  @state
  count = { sum: 0 };

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

const counter = new Counter();

const store = createStore({
  modules: [counter],
});

counter.increase();

const newState = Object.values(store.getState())[0] as Counter;
expect(newState.count).toEqual({ sum: 1 });

Examples

APIs

@state

Define a shared state for a module, and you can use @state for decoration. When use usm-redux, the state is not allowed to be undefined.

For example,

class Counter {
  @state
  number = 0;
}

@action

All operations that change state must be in a method decorated by @action.

For example,

class Counter {
  @state
  number = 0;

  @action
  increase() {
    this.number += 1;
  }
}

@computed/@computed()

It is used for computing derived data.

When use usm-mobx or usm-vuex, you just use @computed, Since it is an observable model, its dependency collection is automatic, And When use usm or usm-redux, you also use @computed, Since it is an signal model, its dependency collection is also automatic.

For example,

class Counter {
  @state
  count = { sum: 0 };

  @state
  number = 0;

  @action
  increase() {
    this.number += 1;
  }

  @computed
  get sum() {
    return this.count.sum + this.number;
  }
}
  • If you want to manually control dependencies with usm or usm-redux, you can use @computed(depsCallback), The return value of the depsCallback is an array of dependent value collections that tells the module that its getter will recompute when there is a change in any of the values in the value collections:

For example,

class Counter {
  @state
  count = { sum: 0 };

  @state
  number = 0;

  @action
  increase() {
    this.number += 1;
  }

  @computed((that) => [that.count.sum, that.number])
  get sum() {
    return this.count.sum + this.number;
  }
}

createStore()

Creates a usm store that holds the complete shared state.

Arguments

  • options(object)
    • modules(array): an array with all modules instances
    • [strict] (boolean): enable strict mode
  • [preloadedState] (any): preloaded state
  • [plugins/middleware] (any[]): vuex's plugins or redux's middleware

For example,

class Counter {
  @state
  number = 0;

  @action
  increase() {
    this.number += 1;
  }
}

const counter = new Counter();

const store = createStore({
  modules: [counter],
});

subscribe()

You can use subscribe() to subscribe state changes in any class module.

For example,

class Counter {
  constructor() {
    subscribe(this, () => {
      //
    });
  }

  @state
  count = { sum: 0 };
}

watch()

You can use watch() to observe a specific state changes in any class module.

For example,

class Counter {
  constructor() {
    watch(
      this,
      () => this.count.sum,
      (newValue, oldValue) => {
        //
      }
    );
  }

  @state
  count = { sum: 0 };
}

You can pass the option { multiple: true }, which will support watching multiple values.

For example,

class Counter {
  constructor() {
    watch(
      this,
      () => [this.count0, this.count1],
      ([newCount0, newCount1], [oldCount0, oldCount0]) => {
        //
      },
      {
        multiple: true,
      }
    );
  }

  @state
  count0 = 0;

  @state
  count1 = 0;
}

watch option supports passing in isEqual function for custom equal.

usm's People

Contributors

dependabot[bot] avatar unadlib avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

usm's Issues

example use @computed decorator

how to use a computed decorator?

i tried but got an error
@computed accessToken = this.token

and the error
Cannot set property accessToken of #<Auth> which has only a getter

any nextjs examples?

Hello, thanks for creating this amazing library. I just wanted to test it out with nextjs & not sure, what I've done wrong, but I'm getting this error:
image

Is there any nextjs example with usm-redux?
Thanks

"watch" deep equality

I have been using the watch function like so:

import { app } from '../store' // App is a module class

watch(
    app,
    () => app.customer,
    () => {
        // Do something with data
    }
);

However, I want to now watch for two properties at the same time

watch(
    app,
    () => [app.customer, app.announcement],
    () => {
        // Do something with data
    }
);

The watch function seems to use a === check for equality but I don't think this captures all the changes that may occur. What if a nested property changes, I don't believe the current logic will catch it.

Vuex-usm Examples

可以给一个 vuex-usm 的使用文档么 ~
Need a vuex-usm usage document support ~

usm-redux可以嵌入到传统redux里面吗?

例如,我目前维护的项目是用redux写的,以后的新的模块我想用usm-redux写。redux里面的combineReducers可以把usm-redux写的模块嵌入到进去吗?例如类似这样:

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

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

// reducers
class TodoList extends Module {
  @state todos = [];
  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;
  }
}

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

const todos = new TodoList

const todoApp = combineReducers({
  // 将usm-redux模块转为redux模块
  todos: toReduxReducer(todos),
  visibilityFilter
})

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.