Product
Socket Now Supports uv.lock Files
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
redux-collector
Advanced tools
Easy Collection Reducers for [Redux][].
http://redux-collector.mediadrake.com/
% npm install redux-collector
Redux Collector is a Reducer Generator for Collections
import { createStore } from 'redux';
import collectify from 'redux-collector';
function counterReducer(state = 0, action) {
switch(action.type) {
case 'INCREMENT':
return state + 1;
case 'DECRAMENT':
return state - 1;
default:
return state;
}
}
export default createStore(
collectify(
counterReducer,
{
add: 'ADD_ITEM',
hydrate: 'HYDRATE_ITEMS',
remove: 'REMOVE_ITEM'
}
)
);
Then call actions using the types you created with collectify.
import store from './MyStore'
const {dispatch, subscribe, getState} = store;
subscribe(val => console.log('State is:', getState()));
dispatch({
type: 'HYDRATE_ITEMS',
data: [1, 2, 3, 4]
});
// State is : [1, 2, 3, 4]
dispatch({
type: 'ADD_ITEM',
data: 5
});
// State is : [1, 2, 3, 4, 5]
dispatch({
type: 'INCREMENT'
});
// State is : [2, 3, 4, 5, 6]
dispatch({
type: 'DECREMENT',
query: item => item >= 5
});
// State is : [1, 2, 3, 3, 4]
dispatch({
type: 'REMOVE',
query: item => item < 3
});
// State is : [3, 3, 4]
dispatch({
type: 'REMOVE',
limit: 2,
order: -1
});
// State is : [3]
The above reducers can actually be a whole lot shorter.
import { createStore } from 'redux';
import collectify from 'redux-collector';
export default createStore(
collectify(
{
defaultsTo: 0,
"INCREMENT": state => state + 1,
"DECRAMENT": state => state - 1
},
{
add: 'ADD_ITEM',
hydrate: 'HYDRATE_ITEMS',
remove: 'REMOVE_ITEM'
}
)
);
This is courtesy of [Reducify][]. Head over to their documentation and check out all the ways you can make reducers. Any argument you pass to collectify gets automatically passed to reducify.
Basically, you'll get a reducer that does everything you need to arrays. When you call collectify
you'll get a chance to declare action types for any of the following methods.
collectify([[itemReducer<Object|Function>], actionTypes<Object>]);
One primary function, wrap your item reducers with this.
itemReducer
Use reducer that you want applied to items in an array as the first (optional) argument.
actionTypes
Use this to declare the action types you want to use to manipulate your array. This is a sample configuration:
function itemReducer(state, action) {
// reducer stuff
}
const actionTypes = {
add = 'ADD_MY_ITEM',
move = 'MOVE_MY_ITEM',
swap = 'SWAP_MY_ITEMS',
addRange = 'ADD_MY_ITEMS',
remove = 'REMOVE_MY_ITEMS',
hydrate = 'HYDRATE_MY_ITEMS',
sort = 'SORT_MY_ITEMS'
};
const myReducer = collectify(itemReducer, actionTypes);
If you pass only one argument, we assume the reducer is a static reducer for an empty array and will treat the one argument as the actionTypes
argument. See Reducify static reducers.
If your Collectify reducer does not receive an action type outlined in your config, any actions you dispatch will be passed to your item reducer for every item in your array.
For example:
function itemReducer(state, action) {
switch(action.type) {
case "INCREMENT_BY_TWO":
return state + 2;
default:
return state;
}
}
const myStore = createStore(collectify(itemReducer, {hydrate: 'SET_ITEMS'}));
myStore.dispatch({
type: 'SET_ITEMS',
data: [2, 4, 6]
});
// state is [2, 4, 6]
myStore.dispatch({
type: 'INCREMENT_BY_TWO'
});
// state is [4, 6, 8]
Notice the action 'INCREMENT_BY_TWO' was applied to every item in the array.
There are two configuration options you can pass in with your action types.
This is the default or initial value of the collection.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(collectify(itemReducer, {collectionDefault: [1, 2]}));
myStore.dispatch({
type: 'PASS'
});
// state is [1, 2]
The default value for any item added with add
or addRange
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(collectify(itemReducer, {itemDefault: 10, add: 'ADD_ITEM'}));
myStore.dispatch({
type: 'ADD_ITEM'
});
// state is [10]
The actions will manipulate your array in some form or another.
This sets the data for your collection. It will override your entire array unless you pass in a skip
parameter.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
itemReducer,
{
hydrate: 'HYDRATE_ITEMS'
}
)
);
myStore.dispatch({
type: 'HYDRATE',
data: [1, 2, 3, 4] // data is required
});
This will add an item to your collection. It will default to itemDefault
if you passed one with your configuration.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
itemReducer,
{
itemDefault: 10,
add: 'ADD_ITEM'
}
)
);
myStore.dispatch({
type: 'ADD_ITEM'
});
// state is [10]
myStore.dispatch({
type: 'ADD_ITEM',
data: 11
});
// state is [10, 11]
You can pass any index argument as well.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
itemReducer,
{ add: 'ADD_ITEM' }
)
);
myStore.dispatch({
type: 'ADD_ITEM',
index: 0,
data: 2
});
// state is [2]
myStore.dispatch({
type: 'ADD_ITEM',
index: 0,
data: 3
});
// state is [3, 2]
The same as add
, except this is for adding multiple items at once.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
itemReducer,
{
itemDefault: 10,
addRange: 'ADD_MULTIPLE_ITEMS'
}
)
);
myStore.dispatch({
type: 'ADD_MULTIPLE_ITEMS'
});
// state is [10]
myStore.dispatch({
type: 'ADD_MULTIPLE_ITEMS',
data: [11, 12]
});
// state is [10, 11, 12]
You can pass any index argument as well.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
itemReducer,
{ addRange: 'ADD_MULTIPLE_ITEMS' }
)
);
myStore.dispatch({
type: 'ADD_MULTIPLE_ITEMS',
index: 0,
data: [2, 3]
});
// state is [2, 3]
myStore.dispatch({
type: 'ADD_MULTIPLE_ITEMS',
index: 0,
data: [4, 5]
});
// state is [4, 5, 2, 3]
This will remove items from your collection. If you do not pass a query, it will clear the entire collection.
const myStore = createStore(
collectify(
[1, 2, 3, 4], // this is a static reducify reducer - defaulting to this array
{
hydrate: 'HYDRATE_ITEMS',
remove: 'REMOVE_ITEMS'
}
)
);
myStore.dispatch({
type: 'REMOVE_ITEMS'
});
// state is []
myStore.dispatch({
type: 'HYDRATE_ITEMS',
data: [1, 2, 3, 4]
});
// state is [1, 2, 3, 4]
myStore.dispatch({
type: 'REMOVE_ITEMS',
query: item => item > 2
});
// state is [1, 2]
myStore.dispatch({
type: 'REMOVE_ITEMS',
query: item => item > 2
});
// state is [1, 2]
myStore.dispatch({
type: 'REMOVE_ITEMS',
limit: 1
});
// state is [2]
You can pass any index argument as well.
myStore.dispatch({
type: 'HYDRATE_ITEMS',
data: [1, 2, 3, 4]
});
myStore.dispatch({
type: 'REMOVE_ITEMS',
index: 0
});
// state is [2, 3, 4]
myStore.dispatch({
type: 'REMOVE_ITEMS',
indexes: [0, 2]
});
// state is [3]
Sort will make an effort to use the lodash method _.orderBy
. It will incorporate order if it exists in your action. Otherwise, it will just do the sorting.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
[4, 3, 2, 1],
{
hydrate: 'HYDRATE_ITEMS',
sort: 'SORT_ITEMS'
}
)
);
myStore.dispatch({
type: 'SORT_ITEMS'
});
// state is [1, 2, 3, 4]
myStore.dispatch({
type: 'HYDRATE_ITEMS',
[{num: 2}, {num: 3}, {num: 1}]
});
myStore.dispatch({
type: 'SORT_ITEMS',
sort: 'num'
});
// state is [{num: 1}, {num: 2}, {num: 3}]
myStore.dispatch({
type: 'SORT_ITEMS',
sort: item => item.num
});
// Same as above
myStore.dispatch({
type: 'SORT_ITEMS',
sort: () => Math.random()
});
// state is randomized
// we'll also make an effort to infer order arguments
myStore.dispatch({
type: 'SORT_ITEMS',
sort: {num: -1}
});
// state is [{num: 3}, {num: 2}, {num: 1}]
Move uses a from
and a to
argument to take an item or set of items and move them to another location in your array.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
[4, 3, 2, 1],
{
move: 'MOVE_ITEMS'
}
)
);
myStore.dispatch({
type: 'MOVE_ITEMS',
from: 0,
to: -1
});
// state is [3, 2, 1, 4]
myStore.dispatch({
type: 'MOVE_ITEMS',
from: [0, 1],
to: -2
});
// state is [2, 1, 4, 3]
Your to
argument should always be a single index. Full on movement mapping is a TODO.
Swap relies on an index argument to get an array of indexes. The most common use case is two indexes, but sending more than one will result in values rotating like a carousel.
function itemReducer(state, action) {
// reducer stuff
}
const myStore = createStore(
collectify(
[4, 3, 2, 1],
{
swap: 'SWAP_ITEMS'
}
)
);
myStore.dispatch({
type: 'SWAP_ITEMS',
indexes: [0, -1]
});
// state is [1, 3, 2, 4]
myStore.dispatch({
type: 'SWAP_ITEMS',
range: [0, 2]
});
// state is [2, 1, 3, 4]
### Queries
### Operations
#### Order
#### After
#### Sort
#### Limit
### Moving and Sorting
### Indexes
## Customization
### Matcher
## Gotchas
## Integration
### With Pipeline
### Without Pipeline
## Credits
Redux Collector is free software under the MIT license. It was created in sunny Santa Monica by [Matthew Drake][].
[Redux]: https://github.com/reactjs/redux
[Matthew Drake]: http://www.mediadrake.com
[Reducify]: http://reducify.mediadrake.com
[Redux Pipeline]: http://redux-pipeline.mediadrake.com
FAQs
Easy Collection Reducers for Redux
The npm package redux-collector receives a total of 1 weekly downloads. As such, redux-collector popularity was classified as not popular.
We found that redux-collector demonstrated a not healthy version release cadence and project activity because the last version was released a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Product
Socket now supports uv.lock files to ensure consistent, secure dependency resolution for Python projects and enhance supply chain security.
Research
Security News
Socket researchers have discovered multiple malicious npm packages targeting Solana private keys, abusing Gmail to exfiltrate the data and drain Solana wallets.
Security News
PEP 770 proposes adding SBOM support to Python packages to improve transparency and catch hidden non-Python dependencies that security tools often miss.