Last active
May 25, 2019 02:35
-
-
Save MattMS/2ac7e516f607722fa06e9f180cf20672 to your computer and use it in GitHub Desktop.
Messing around with Ramda to create a state-changing thing.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/* Example of something that is inspired by Redux, but totally not a replacement for it. | |
This is NOT intended to be used in anything serious; go find a proper library instead. | |
[MIT licensed](https://opensource.org/licenses/MIT) | |
So do whatever you want with any or all of this but don't blame me for anything. | |
Copyright 2019 Matt McKellar-Spence | |
*/ | |
const {append, cond, inc, join, lensIndex, lensPath, map, over, pathEq, pipe, prop, T, toPairs, toString} = require('ramda') | |
// Core | |
// ---- | |
/** Given a [string, function] pair, update the string to be a function that matches action type names. | |
This is assumed to be used in a Ramda `cond` Array. | |
Said `cond` would be expecting `{action, state}` as a parameter. | |
*/ | |
const fix_action_check = map(over(lensIndex(0), pathEq(['action', 'type']))) | |
/** Default condition to apply if none of the actions match. */ | |
const add_default_cond = append([T, prop('state')]) | |
const actions_to_cond = pipe(toPairs, fix_action_check, add_default_cond, cond) | |
/** | |
Returns a function that given a state, an action, and some changes, does the appropriate change and returns a new state. | |
To increase performance: | |
``` | |
const make_action_doer = parts => { | |
const doer = actions_to_cond(parts) | |
return action => state => doer({action, state}) | |
} | |
``` | |
*/ | |
const make_action_doer = parts => action => state => actions_to_cond(parts)({action, state}) | |
/** | |
Create a reducer that triggers on the given action type. | |
@param {string} t The `type` field of the action. | |
*/ | |
const when_action_is = t => f => action => when(propEq('type', t, action), f(action)) | |
// Some demo actions | |
// ----------------- | |
const over_prop = name => f => pipe(over(lensPath(['state', name]), f), prop('state')); | |
const inc_prop = name => over_prop(name)(inc) | |
// My state | |
// -------- | |
const over_a = over_prop('a') | |
const act = make_action_doer({ | |
dbl: over_a(a => [a, a]), | |
inc: inc_prop('a'), | |
join: over_a(join('')), | |
str: over_a(toString) | |
}) | |
// My demo usage of state | |
// ---------------------- | |
const start_state = {a: 1} | |
const stop_state = pipe( | |
act({type: 'inc'}), | |
act({type: 'str'}), | |
act({type: 'dbl'}), | |
act({type: 'join'}) | |
)(start_state) | |
// = {a: "22"} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment