(n.) Something that is the absolute core and driving force behind something.
Simple state management inspired on Redux.
Motivation: I've been using Redux in several projects recently and don't get me wrong, I love it, but I've found that at some point, if my app scales, my Redux files (actions/reducers/store) start to get messy and a bit annoying to handle. So inspired by the basic concepts of Redux, I decided to create this library where I've simplified that workflow and aim to have a better and easier file structure. I hope you like it and any feedback or collaboration is more than welcome.
npm install thrux --save
or with yarn
yarn add thrux
import { register } from 'thrux';
const state = {
dispatcher: (payload, state)=> console.log('New State', payload),
map: rawValue => rawValue.data,
error: err => console.err('An error happened', err)
};
register({state});
Create the dictionary of methods that will be used for each action.
Param | Type | Description |
---|---|---|
dispatcher | Function | Update the current state. This could return an Object or a Promise and update the state async. |
map | Function | (optional) A map function to sanitize the value handle by the dispatcher function. |
error | Function | (optional) Error handler. |
import { createDict } from 'thrux';
const postJson = data => ({
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify(data),
});
const counter = {
INCREASE: createDict((payload, state) => state + 1),
DECREASE: createDict((payload, state) => state - 1),
}
const user = {
SIGN_IN: createDict(({ username, pass }) =>
fetch('./sign_in_url', postJson({ username, pass }))
.then(user => ({ username: user.name, pass: user.password }))),
};
You can define an INIT action with a function that sets the initial value of your state after register
import { createDict } from 'thrux';
const counter = {
INIT : createDict(() => 1),
INCREASE: createDict((payload, state) => state + 1),
DECREASE: createDict((payload, state) => state - 1),
}
Initialize Thrux store.
Param | Type | Description |
---|---|---|
options | Object | Initialize any module: { middlewares: [], dicts: {}, observers: {}, store: {} } |
import { init } from 'thrux';
init({ store: { test: 0 } });
Triggers INIT
action (a.k.a. initialize the state manually)
Param | Type | Description |
---|---|---|
key | String or [Array of Strings] | (optional) State(s) that want to initialize |
import { initState } from 'thrux';
initState('counter');
initState(['counter', 'user']);
Register your dictionaries.
Param | Type | Description |
---|---|---|
dictionaries | Object | List of states and their respective dictionaries |
import { register } from 'thrux';
register({ counter, user });
Dispatch the action that will update your state.
Param | Type | Description |
---|---|---|
stateAction | String or [Array of Strings] | String(s) that represents the state(s) and the action(s) that you want to dispatch: 'state:ACTION' |
data | Any | (optional) Whatever data your dispatcher function is prepared to handle |
import { dispatch } from 'thrux';
dispatch('counter:INCREASE');
dispatch(['counter:INCREASE', 'counter2:INCREASE']);
dispatch('user:SIGN_IN', { user:'Thram', pass:'password' });
returns: [Object]
Retrieve the state value.
Param | Type | Description |
---|---|---|
stateKey | String or [Array of Strings] | (optional) String(s) that represents the state(s) |
import { state } from 'thrux';
const allStates = state();
const someStates = state(['counter','user']);
const userStates = state('user');
Observe when the state changed.
Param | Type | Description |
---|---|---|
stateKey | String | String that represents the state |
listener | Function | Function that gets trigger when the state changes |
import { observe } from 'thrux';
observe('user', (state, actionKey) => console.log(actionKey, state.profile));
You can observe specific parts of the state for changes
import { observe } from 'thrux';
observe('user.profile', (profile, actionKey) => console.log(actionKey, profile));
observe('user.profile.name', (name, actionKey) => console.log(actionKey, name));
Remove an observe listener.
Param | Type | Description |
---|---|---|
stateKey | String | String that represents the state |
listener | Function | Function that gets trigger when the state changes |
import { observe, removeObserver } from 'thrux';
const logProfile = (auth) => console.log(auth.profile);
observe('user', logProfile);
removeObserver('user', logProfile); // logProfile won't trigger
Remove all observe listeners.
Param | Type | Description |
---|---|---|
stateKey | String or [Array of Strings] | String that represents the state |
import { clearObservers } from 'thrux';
clearObservers('user');
clearObservers(['counter1', 'counter2']);
Add some middleware function. It won't modified the state.
Param | Type | Description |
---|---|---|
middleware | Function or [Array of Functions] | Function(s) that trigger when the state changes with the following params: {state, action, prev, payload, next} |
import { addMiddleware } from 'thrux';
// Add logger
addMiddleware(({ state, action, prev, payload, next }) => console.log({ state, action, prev, payload, next }));
addMiddleware([({ prev }) => console.log('prev', prev), ({ next }) => console.log('next', next)]);
Retrieve the state(s) actions keys.
Param | Type | Description |
---|---|---|
stateKey | String or [Array of Strings] | (optional) String(s) that represents the state(s) |
import { getActions } from 'thrux';
const actions = getActions('user'); // ['user:INIT', 'user:SIGN_IN']
Clear Thrux store.
import { clear } from 'thrux';
init({ store: { test: 0 } }); // { test:0 }
clear(); // { }
Reset Thrux all your modules to your initial values.
import { init, register, reset } from 'thrux';
init({ store: { test: 0 } }); // { test:0 }
register({ counter }); // { test:0, counter: 0 }
reset(); // { test:0 }