Share your code. npm Orgs help your team discover, share, and reuse code. Create a free org »

    redux-scfldpublic

    Redux Scaffold Generator

    Install

    $ npm install -g redux-scfld

    Requirements

    • redux
    • redux-base
    • redux-thunk

    Convention

    Redux Scaffold works with actions, reducers, initial states and types through the concept of Redux Scaffold Entity (RSE). That's meaning all RSE grouped by RSE Namespace.

    For a every single RSE exists a single action and a single type and for every RSE Namespace exists single initial state and reducer. Redux Scaffold generates RSE from RSE Full Name of following format {RSENamespace}:{RSEName}.

    For example:

    recently-posts:load-page or recentlyPosts:loadPage has recentlyPost as RSE Namespace and loadPage as RSE Name. Through this approach will be generated action, reducer, type and initial state.

    Redux Scaffold action with parameter type has also parameter status which can be STATUS_PROCESS, STATUS_SUCCESS and STATUS_FAILURE in compare of usual behavior of Redux.

    Let's scaffold

    npm install -g redux-scfld
    cd ~/projects/my-project
    redux init --path src/redux

    Config

    Inside of ~/projects/my-project you will find a file .reduxrc

    {
      "useCamelCasedPaths": false,
      "reduxPath": "src/redux",
      "actionsPath": "src/redux/actions",
      "typesPath": "src/redux/types",
      "statesPath": "src/redux/states",
      "storeTemplatePath": "src/templates/store.dot",
      "actionTemplatePath": "src/templates/action.dot",
      "actionsIndexTemplatePath": "src/templates/action-index.dot",
      "typesTemplatePath": "src/templates/types.dot",
      "stateTemplatePath": "src/templates/state.dot",
      "statesIndexTemplatePath": "src/templates/state-index.dot"
    }

    Here is property useCamelCasedPaths affects naming behavior between camelCase and dash-case. As template engine used doT.

    Structure

    Let's create an action, reducer, type and initial state of RSE.

    redux add config:load config:save posts:fetchPage

    After this command will be generated following files

    +---src
        |
        \---redux
            |   createStore.js
            |
            |   
            +---actions
            |   |   index.js
            |   |
            |   +---config   
            |   |       load.js
            |   |       save.js
            |   \---posts
            |           fetchPage.js
            |           
            |
            +---state
            |       index.js
            |       config.js
            |       posts.js
            |
            |
            +---templates
            |       store.dot
            |       action.dot
            |       action-index.dot
            |       state.dot
            |       state-index.dot
            |       types.dot
            |           
            |           
            \---types
                    index.js
    

    Actions

    src/redux/actions/posts/fetchPage.js, src/redux/actions/config/load.js, src/redux/actions/posts/save.js will contain

    import action from 'redux-base/createAction';
    import {
      NAMESPACE_CONFIG,
      CONFIG_LOAD,
    } from '../../types';
     
    export default action(NAMESPACE_CONFIG, CONFIG_LOAD, (getState, ...args) => {
      /** Action code HERE */
    });

    app/actions/index.js contains

    export { default as configLoad } from './config/load.js';
    export { default as configSave } from './config/save.js';
    export { default as postsFetchPage } from './posts/fetchPage.js';

    IMPORTANT: Instead of original Redux actions, Redux Scaffold Actions has only one type, but one namespace and 3 statuses: STATUS_PROCESS, STATUS_SUCCESS, STATUS_FAILURE

    IMPORTANT: You should avoid editing of generated index files. See templates generation

    Types

    // Statuses
    export const STATUS_PROCESS = 'STATUS_PROCESS';
    export const STATUS_SUCCESS = 'STATUS_SUCCESS';
    export const STATUS_FAILURE = 'STATUS_FAILURE';
     
    // Generated Namespaces
    export const NAMESPACE_CONFIG = 'config';
    export const NAMESPACE_POSTS = 'posts';
     
    export const NAMESPACES = [
        NAMESPACE_CONFIG,
        NAMESPACE_POSTS,
    ];
     
    // Generated types
    export const CONFIG_LOAD = 'CONFIG_LOAD';
    export const CONFIG_SAVE = 'CONFIG_SAVE';
    export const POSTS_FETCH_PAGE = 'POSTS_FETCH_PAGE';

    IMPORTANT: You should avoid editing of generated index files. See templates generation

    Initial states

    State is represented by separate files for each namespace and will be generated automatically for each namespace.

    Store

    Also will be generated src/redux/createStore.js file with basic store setup. You can edit this file for own purposes.

    /*! Generated by redux-scfld */
    import { createStore, applyMiddleware } from 'redux';
    import thunkMiddleware from 'redux-thunk';
    import { createLogger } from 'redux-logger';
    import createReducer from 'redux-base/createReducer';
    import defaultState from './states';
     
    const loggerMiddleware = createLogger({
      collapsed: true,
      level: 'info',
      stateTransformer({ series, seasons }) {
        return { series, seasons };
      },
      actionTransformer(action) {
        return { type: `${action.type}_${action.status || ''}` };
      },
    });
     
    const reducer = createReducer(defaultState);
     
    const middleware = [
      thunkMiddleware,
      loggerMiddleware,
    ].filter(Boolean);
     
    export default function create(initialState = defaultState) {
      const store = createStore(
        reducer,
        initialState,
        applyMiddleware(...middleware));
     
      store.dispatchAll = function dispatchAll(actions) {
        return Promise.all(actions.map(action => store.dispatch(action())));
      };
     
      store.dispatchEach = async function dispatchEach(actions) {
        for(const action of actions) {
          await store.dispatch(action());
        }
      };
     
      return store;
    }

    Action dispatching

    'use strict';
    import { postsFetchPage } from './src/redux/actions'
    import createStore from './store'
     
    const store = createStore();
    store.dispatch(postsFetchPage());

    Templates

    Template files are using tiny and fast doT.js template engine. From template you can access to it.entity and it.entities variables, see default templates for example.

    interface Entity {
      namespace
      NAMESPACE
      fullName
      FullName
      name
      Name
      TYPE
      filename
      path
      actionFolder
      actionPath
      reducerPath
      statePath
    }
    interface Entities {
      [entity.namespace]: {
        [entity.name]: entity
      }
    }

    Commands

    $ redux init src/redux - Generate Redux-Scfld config file .reduxrc and save templates to src/redux/templates

    $ redux add <entities> - Adds entities separated by whitespace with Action, Type and Reducer and generates their indexes

    $ redux del <entities> - Deletes entities separated by whitespace with Action, Type and Reducer or all namespaces and generates their indexes

    $ redux config - Display current config

    $ redux sync - Sync indexes of Actions, Types and Reducers (does not affect already generated not indexes files)

    $ redux list - List of entities

    $ redux namespaces - List of namespaces

    $ redux types - List of types

    $ redux --help - Display help information

    Demo project

    (Powered by redux-scfld: React-Redux demo)[https://github.com/3axap4eHko/react-redux-demo]

    License

    The MIT License Copyright (c) 2016-2018 Ivan Zakharchenko

    install

    npm i redux-scfld

    Downloadsweekly downloads

    0

    version

    3.4.0

    license

    MIT

    repository

    githubgithub

    last publish

    collaborators

    • avatar