GithubHelp home page GithubHelp logo

yanick / updux Goto Github PK

View Code? Open in Web Editor NEW
0.0 2.0 2.0 369 KB

Updeep-friendly Redux helper framework

Home Page: https://yanick.github.io/updux

JavaScript 2.76% TypeScript 94.82% Perl 2.42%
redux updeep typescript

updux's Introduction

What's Updux?

So, I'm a fan of Redux. Two days ago I discovered rematch alonside a few other frameworks built atop Redux.

It has a couple of pretty good ideas that removes some of the boilerplate. Keeping mutations and asynchronous effects close to the reducer definition? Nice. Automatically infering the actions from the said mutations and effects? Genius!

But it also enforces a flat hierarchy of reducers -- where is the fun in that? And I'm also having a strong love for Updeep, so I want reducer state updates to leverage the heck out of it.

All that to say, say hello to Updux. Heavily inspired by rematch, but twisted to work with updeep and to fit my peculiar needs. It offers features such as

  • Mimic the way VueX has mutations (reducer reactions to specific actions) and effects (middleware reacting to actions that can be asynchronous and/or have side-effects), so everything pertaining to a store are all defined in the space place.
  • Automatically gather all actions used by the updux's effects and mutations, and makes then accessible as attributes to the dispatch object of the store.
  • Mutations have a signature that is friendly to Updux and Immer.
  • Also, the mutation signature auto-unwrap the payload of the actions for you.
  • TypeScript types.

Fair warning: this package is still very new, probably very buggy, definitively very badly documented, and very subject to changes. Caveat Maxima Emptor.

Synopsis

import updux from 'updux';

import otherUpdux from './otherUpdux';

const {
    initial,
    reducer,
    actions,
    middleware,
    createStore,
} = new Updux({
    initial: {
        counter: 0,
    },
    subduxes: {
        otherUpdux,
    },
    mutations: {
        inc: ( increment = 1 ) => u({counter: s => s + increment })
    },
    effects: {
        '*' => api => next => action => {
            console.log( "hey, look, an action zoomed by!", action );
            next(action);
        };
    },
    actions: {
        customAction: ( someArg ) => ({
            type: "custom",
            payload: { someProp: someArg }
        }),
    },

});

const store = createStore();

store.dispatch.inc(3);

Description

Full documentation can be found here. Right now the best way to understand the whole thing is to go through the tutorial

Exporting upduxes

If you are creating upduxes that will be used as subduxes by other upduxes, or as ducks-like containers, I recommend that you export the Updux instance as the default export:

import Updux from 'updux';

const updux = new Updux({ ... });

export default updux;

Then you can use them as subduxes like this:

import Updux from 'updux';
import foo from './foo'; // foo is an Updux
import bar from './bar'; // bar is an Updux as well

const updux = new Updux({
    subduxes: {
        foo, bar
    }
});

Or if you want to use it:

import updux from './myUpdux';

const {
    reducer,
    actions: { doTheThing },
    createStore,
    middleware,
} = updux;

Mapping a mutation to all values of a state

Say you have a todos state that is an array of todo sub-states. It's easy enough to have the main reducer maps away all items to the sub-reducer:

const todo = new Updux({
    mutations: {
        review: () => u({ reviewed: true}),
        done: () => u({done: true}),
    },
});

const todos = new Updux({ initial: [] });

todos.addMutation(
    todo.actions.review,
    (_,action) => state => state.map( todo.upreducer(action) )
);
todos.addMutation(
    todo.actions.done,
    (id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
);

But updeep can iterate through all the items of an array (or the values of an object) via the special key *. So the todos updux above could also be written:

const todo = new Updux({
    mutations: {
        review: () => u({ reviewed: true}),
        done: () => u({done: true}),
    },
});

const todos = new Updux({
    subduxes: { '*': todo },
});

todos.addMutation(
    todo.actions.done,
    (id,action) => u.map(u.if(u.is('id',id), todo.upreducer(action))),
    true
);

The advantages being that the actions/mutations/effects of the subdux will be imported by the root updux as usual, and all actions that aren't being overridden by a sink mutation will trickle down automatically.

Usage with Immer

While Updux was created with Updeep in mind, it also plays very well with Immer.

For example, taking this basic updux:

import Updux from 'updux';

const updux = new Updux({
    initial: { counter: 0 },
    mutations: {
        add: (inc=1) => state => { counter: counter + inc }
    }
});

Converting it to Immer would look like:

import Updux from 'updux';
import { produce } from 'Immer';

const updux = new Updux({
    initial: { counter: 0 },
    mutations: {
        add: (inc=1) => produce( draft => draft.counter += inc ) }
    }
});

But since typing produce over and over is no fun, groomMutations can be used to wrap all mutations with it:

import Updux from 'updux';
import { produce } from 'Immer';

const updux = new Updux({
    initial: { counter: 0 },
    groomMutations: mutation => (...args) => produce( mutation(...args) ),
    mutations: {
        add: (inc=1) => draft => draft.counter += inc
    }
});

updux's People

Contributors

fenderchamp avatar spazm avatar yanick avatar

Watchers

 avatar  avatar

Forkers

spazm fenderchamp

updux's Issues

coduxes

  • for effects
  • for mutations
  • for selectors
  • for actions

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.