Skip to content
/ vivy Public

A state container for JavaScript apps based on Redux.

License

Notifications You must be signed in to change notification settings

fatalxiao/vivy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Vivy

NPM Version License

Vivy is a JavaScript state container built on redux that simplifies development by adopting a syntax similar to Redux.

In Vivy, the state, actions, and reducers are combined into a single Object called the model. Both actions and reducers within the model can be invoked using the dispatch function. Consequently, there's no need to define specific action types in Vivy. Additionally, redundant actions become unnecessary as you can directly dispatch reducers.

Vivy is designed with expandability in mind. You can easily handle routing using vivy-router, and effortlessly load components and models on-demand with vivy-async-component. The vivy-api facilitates API requests, while vivy-subscription allows you to observe changes in history or other events and update the state by dispatching a reducer or action. Furthermore, vivy-i18n assists you in implementing internationalization (i18n) functionality.

Installation

Using NPM:

$ npm install vivy

Examples

Examples in repository

$ cd ./examples/[EXAMPLE_NAME]
$ npm run start

Example names:

Complete and real project example

React bindings

Plugin Version Description
react‑vivy NPM Version React bindings for Vivy based on react-redux.

Plugins

Plugin Version Description
vivy‑router NPM Version A router plugin based on connected-react-router.
vivy‑async‑component NPM Version A plugin which loading async component and async Vivy model to easily split chunks by route.
vivy‑api NPM Version Handle apis in Vivy model to make api calling easier.
vivy‑subscription NPM Version Handle subscriptions in Vivy model to watch history or something else.
vivy‑i18n NPM Version Handle i18ns in Vivy model to implement i18n.

Documentation

Basic usage

import React from 'react';
import {render} from 'react-dom';
import {Provider} from 'react-vivy';

// Import Vivy
import Vivy from 'vivy';

// Import Vivy model
import yourVivyModel from 'path_to_your_vivy_model';

// Create Vivy instance
const vivy = Vivy();

// Get Vivy Store
const store = vivy.createStore();

// Register  Vivy model
store.registerModel(yourVivyModel);

// Render
render(
    <Provider store={store}>
        <Root/>
    </Provider>,
    document.getElementById('app-container')
);

Vivy model

A Vivy model is an Object combined state, actions, globalReducers and reducers.

const yourVivyModel = {

    // An unique key registered to store.
    nameSpace: 'yourVivyModel',

    // Any type of redux state value.
    state: STATE_VALUE,

    // Vivy model action.
    actions: {

        // Define a model action. Payload here is an object passing by dispatch
        ACTION_NAME: payload => (dispatch, getState) => {

            // Get state value by getState.
            const state = getState();
            const STATE_VALUE = state.MODEL_NAME_SPACE

            // Dispatch an action
            dispatch({
                type: 'MODEL_NAME_SPACE/OTHER_ACTION_NAME',
                // payload ...
            });

            // Dispatch a global reducer.
            dispatch({
                type: 'GLOBAL_REDUCER_NAME',
                // payload ...
            });

            // Dispatch a reducer
            dispatch({
                type: 'MODEL_NAME_SPACE/REDUCER_NAME',
                // payload ...
            });

        },

        // Register another model action.
        OTHER_ACTION_NAME: payload => (dispatch, getState) => {
            // dispatch some actions or reducers.
        }

        // Other actions ...

    },

    // Vivy model global reducer.
    globalReducers: {

        // Register a global reducer.
        // The reducer will be registered to global without current model namespace.
        // 
        // Example:
        //  dispatch({
        //      type: 'GLOBAL_REDUCER_NAME',
        //      // payloads ...
        //  });
        GLOBAL_REDUCER_NAME: (state, payload) => {
            return {
                ...state,
                // Do something by payload.
            };
        },

        // Other global reducers ...

    },

    // Vivy model reducer.
    reducers: {

        // Register a reducer.
        //
        // Example:
        //  store.dispatch({
        //      type: 'MODEL_NAME_SPACE/GLOBAL_REDUCER_NAME',
        //      // payloads ...
        //  });
        REDUCER_NAME: (state, payload) => {
            return {
                ...state,
                // Do something by payload.
            };
        },

        // Other reducers ...

    }

}

Vivy store dispatcher

In Vivy, you can use 4 ways to dispatch an action.

  1. Use hook "useModel" from react-vivy.
import {useModel} from 'react-vivy';

const App = () => {

    // ...

    /**
     * Get state and actions/reducers from model using hook "useModel".
     */
    const [modelState, modelActions] = useModel('MODEL_OR_NAME_SPACE');

    /**
     * Call the action or reducer.
     */
    modelActions.someAction();

    // ...

};

export default App;
  1. Use store.dispatch function.
dispatch({
    type: 'MODEL_NAME_SPACE/ACTION_OR_REDUCER_NAME',
    OTHER_PROPS
});
  1. Use store.dispatch chain function.
dispatch.MODEL_NAME_SPACE.ACTION_OR_REDUCER_NAME({
    OTHER_PROPS
});
  1. Use bindModelActionCreators to create an action dispatcher.
import {bindModelActionCreators} from 'vivy';

const App = () => {

    // ...

    ACTION_OR_REDUCER_NAME({
        OTHER_PROPS
    });

    // ...

}

export default connect(state => ({
    // states
}), dispatch => bindModelActionCreators({
    ACTION_OR_REDUCER_NAME: 'MODEL_NAME_SPACE/ACTION_OR_REDUCER_NAME'
}, dispatch))(App);

Use Vivy in Component

import React from 'react';
import {useModel} from 'react-vivy';

const App = () => {

    /**
     * Get state and actions/reducers from model using hook "useModel".
     */
    const [{value}, {updateValue}] = useModel('MODEL_OR_NAME_SPACE');

    return (
        <input value={value}
               onChange={e => updateValue({
                   value: e.target.value
               })}/>
    );

};

export default App;

For more hooks usage documents, please check react-vivy.

Methods

registerReducer

registerReducer(vivyStore, nameSpace, reducer)

Example:

import {registerReducer} from 'vivy';

// Register a Redux reudcer to your Vivy store
registerReducer(YOUR_VIVY_STORE, YOUR_REDUCER_NAME_SAPCE, YOUR_REDUX_REDUCER);

registerReducers

registerReducers(vivyStore, reducers)

Example:

import {registerReducers} from 'vivy';

// Register Redux reudcers to your Vivy store
registerReducers(YOUR_VIVY_STORE, {
    YOUR_REDUCER_NAME_SAPCE_1: YOUR_REDUX_REDUCER_1,
    YOUR_REDUCER_NAME_SAPCE_2: YOUR_REDUX_REDUCER_2,
    // other reducers...
});

registerModel

registerModel(vivyStore, model)

Example:

import {registerModel} from 'vivy';

// Register a Vivy model to your Vivy store
registerModel(YOUR_VIVY_STORE, YOUR_VIVY_MODEL);

registerModels

registerModels(vivyStore, models)

Example:

import {registerModels} from 'vivy';

// Register Vivy models to your Vivy store
registerModels(YOUR_VIVY_STORE, [
    YOUR_VIVY_MODEL_1,
    YOUR_VIVY_MODEL_2,
    // other models...
]);

unregisterReducer

unregisterReducer(vivyStore, nameSpace)

Example:

import {unregisterReducer} from 'vivy';

// Unregister a Redux reducer from your Vivy store
unregisterReducer(YOUR_VIVY_STORE, YOUR_REDUCER_NAME_SAPCE);

unregisterReducers

unregisterReducers(vivyStore, nameSpaces)

Example:

import {unregisterReducers} from 'vivy';

// Unregister Redux reducers from your Vivy store
unregisterReducers(YOUR_VIVY_STORE, [
    YOUR_REDUCER_NAME_SAPCE_1,
    YOUR_REDUCER_NAME_SAPCE_2,
    // other reducers name space...
]);

unregisterModel

unregisterModel(vivyStore, model)

Example:

import {unregisterModel} from 'vivy';

// Unregister a Vivy model from your Vivy store
unregisterModel(YOUR_VIVY_STORE, YOUR_VIVY_MODEL);

unregisterModels

unregisterModels(vivyStore, models)

Example:

import {unregisterModels} from 'vivy';

// Unregister Vivy models from your Vivy store
unregisterModels(YOUR_VIVY_STORE, [
    YOUR_VIVY_MODEL_1,
    YOUR_VIVY_MODEL_2,
    // other models...
]);

bindModelActionCreators

bindModelActionCreators(modelActionCreators, dispatch)

Example:

import React from 'react';
import {connect} from 'react-vivy';
import {bindModelActionCreators} from 'vivy';

const App = ({
    MODEL_STATE, MODEL_ACTION
}) => (
    <div>App</div>
);

export default connect(state => ({
    MODEL_STATE: state.MODEL_NAMESPACE,
}), dispatch => bindModelActionCreators({
    MODEL_ACTION: 'MODEL_NAMESPACE/MODEL_ACTION_KEY',
}, dispatch))(App);