• Stars
    star
    297
  • Rank 140,075 (Top 3 %)
  • Language
    TypeScript
  • Created almost 6 years ago
  • Updated 7 months ago

Reviews

There are no reviews yet. Be the first to send feedback to the community and the maintainers!

Repository Details

๐Ÿ– A concise & flexible state model for Redux/MobX/Vuex, etc.

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 or usm-redux, you should 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;
  }
}
  • When use usm-mobx or usm-vuex, you just use @computed, Since it is an observable model, its dependency collection is automatic:

For example,

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

  @state
  number = 0;

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

- @computed((that) => [that.count.sum, that.number])
+ @computed
  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.

More Repositories

1

mutative

Efficient immutable updates, 2-6x faster than naive handcrafted reducer, and more than 10x faster than Immer.
TypeScript
1,601
star
2

fronts

A progressive micro frontends framework for building Web applications
TypeScript
517
star
3

reactant

A framework for building React applications
TypeScript
250
star
4

iflow

Concise & powerful state management framework for Javascript.
JavaScript
79
star
5

use-mutative

A 2-6x faster alternative to useState with spread operation
TypeScript
45
star
6

data-transport

A simple and responsible universal transport
TypeScript
41
star
7

mutability

A JavaScript library for transactional mutable updates
TypeScript
28
star
8

react-native-css-tree

Inheritable dynamic style tree.
JavaScript
26
star
9

tees

Universal test framework for front-end with WebDriver, Puppeteer and Enzyme
JavaScript
24
star
10

origin-storage

A same-origin storage(IndexedDB/WebSQL/localStorage) for cross-domain access
TypeScript
22
star
11

crius

A testing tool for behavior-driven development
TypeScript
22
star
12

react-native-px2dp

Pixels convert to density-independent pixels.
JavaScript
22
star
13

ssh-webpack-plugin

Webpack SSH deployment plugin.
JavaScript
19
star
14

jsdoc-tests

A JSDoc test tool for documentation-driven quality
TypeScript
12
star
15

typescript-tutorial

TypeScript
10
star
16

fronts-example

TypeScript
9
star
17

react-iflow

Connector for React and iFlow.
JavaScript
9
star
18

capturer

Log tracker for debugging
TypeScript
7
star
19

marten

A Process Controller Library
JavaScript
7
star
20

openapi-client-codegen

Node.js library that generates Typescript function chaining clients based on the OpenAPI specification.
TypeScript
7
star
21

awesome-micro-frontends

Awesome lists about micro frontends.
6
star
22

use-immutable

A hook for creating the immutable state with mutations on React
TypeScript
5
star
23

be-type

be-type is based on ECMAScript2015+ proxy feature
JavaScript
3
star
24

invariance

Utils for immutable data structures Records & Tuples
TypeScript
3
star
25

usm-redux-demo

Todo + Counter example with usm-redux and react-navigation
TypeScript
3
star
26

glaive

Trying to build a new dependency module injector
JavaScript
3
star
27

reactant-examples

Just reactant examples
TypeScript
3
star
28

usm-examples

Todo Examples for USM
JavaScript
3
star
29

crius-react-example

React test example with crius-test
JavaScript
2
star
30

installation

An installation template tool
TypeScript
2
star
31

iflow-docs-cn

The Chinese version of iFlow documents.
2
star
32

alias-webpack-plugin

Webpack alias batch relative paths configuration plugin
JavaScript
2
star
33

crius-examples

JavaScript
1
star
34

reactant-todomvc

Reactant TodoMVC Example
TypeScript
1
star
35

reactant-base-example

Just reactant base example
TypeScript
1
star
36

use-transport

A React hook with simple and responsible universal transports
TypeScript
1
star
37

unadlib.github.io

unadlib's Notes
HTML
1
star
38

acting

๐ŸŽActing is a tiny agent model tool.
TypeScript
1
star