master e6f34cd92404 cached
9 files
9.8 KB
2.8k tokens
10 symbols
1 requests
Download .txt
Repository: calvinfroedge/redux-modifiers
Branch: master
Commit: e6f34cd92404
Files: 9
Total size: 9.8 KB

Directory structure:
gitextract_6wxp96t_/

├── .babelrc
├── .gitignore
├── .npmignore
├── README.md
├── package.json
├── src/
│   ├── index.js
│   └── utility.js
├── test/
│   └── redux.spec.js
└── webpack.config.js

================================================
FILE CONTENTS
================================================

================================================
FILE: .babelrc
================================================
{
  "presets": ["es2015", "react", "babel-preset-stage-0"]
}


================================================
FILE: .gitignore
================================================
*.sw*
node_modules
dist
lib
es


================================================
FILE: .npmignore
================================================
*.sw*


================================================
FILE: README.md
================================================
# Write better Redux code faster v0.0.5

<em>Big changes from 0.0.4! API has been completely rewritten on top of [ImmutableJS](http://facebook.github.io/immutable-js).</em>

![Codeship build status](https://codeship.com/projects/857492d0-ec53-0132-251c-1a6982ed746d/status?branch=master)

A collection of generic functions on top of [ImmutableJS](http://facebook.github.io/immutable-js) and [Redux Actions](https://github.com/acdlite/redux-actions) for simplifying your reducers. Declare your reducers and state as plain old javascript objects, but take advantage of `Immutable` guarantees and data structure traversal utilities.

Example reducer:

```js
import { reducer, push, updateIn, removeIn } from 'redux-modifiers'

const reducer = reducer({
  'ADD_ITEM_TO_LIST': push,
  'UPDATE': updateIn,
  'ADD_NESTED_ITEM': (state, action)=>{
    let { selected, value } = action.payload; //Index of nested item (could be deeply nested, i.e. [0, 'key', 1])
    return state.updateIn(selected, item => item.push(value) ); //Using ImmutableJS API
  },
  'REMOVE': removeIn
}, []);
```

You can call `toJS` on any structure you get out of the reducer to convert it back to vanilla js, i.e. in a react component where you want to use spread operators, normal object accessors, etc. Anything you put in the reducer will automatically be converted to an ImmutableJS structure, which means you can do things like adding items to state from plain javascript objects without worrying about references sticking around.

## Notes

### FSA
`redux-modifiers` does expect that actions are dispatched as [Flux Standard Actions](https://github.com/acdlite/flux-standard-action). Essentially, this means every action looks like:

```js
{
  type: YOUR_ACTION_TYPE,
  payload: YOUR_PAYLOAD
}
```

### State and ImmutableJS
`state` is converted to an `Immutable` data structure, so you are free to use any `ImmutableJS` function you like on state. If you find you perform a particular option frequently, consider submitting a *pull request* and adding it to `redux-modifiers`!

# Targeting specific parts of state

Use `updateIn`, to target specific parts of state, passing the update function the path that you want to update. Example state:

```js
{
  foo: [
    {
      id: 1,
      name: 'Calvin'
    }
  ]
}
```

Example reducer function:

```js
'UPDATE': updateIn
```

Example dispatch:

```js
dispatch({selected: ['foo', 'name'], value: 'Calvin Froedge'});
```


# API

### push(state, action)

Payload can take any value, but you must call `push` on an array (`List` in ImmutableJS).

```js
'ADD': push
```

### updateIn(state, action)

Payload must include a selection path `selected` and a `value` or `fn`. State (or targeted key) will be replaced with value if `value`, or `fn` will be applied to the existing value.

Example payload:
```
{selected: [0, 'nested_array', 1], fn: value => value * 2}
```

### removeIn(state, action)

Payload must include a selection path. Example payload:
```
[0, 'nested_array', 1]
```


================================================
FILE: package.json
================================================
{
  "name": "redux-modifiers",
  "version": "0.0.6",
  "description": "A collection of generic functions for writing redux reducers to operate on various data structures",
  "main": "lib/index.js",
  "jsnext:main": "es/index.js",
  "scripts": {
    "clean": "rimraf lib dist es",
    "test": "cross-env BABEL_ENV=commonjs mocha --compilers js:babel-register --recursive",
    "build:commonjs": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs ./node_modules/babel-cli/bin/babel.js src --out-dir lib",
    "build:es": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=es ./node_modules/babel-cli/bin/babel.js src --out-dir es",
    "build:umd": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=development ./node_modules/webpack/bin/webpack.js src/index.js dist/redux-modifiers.js",
    "build:umd:min": "./node_modules/cross-env/bin/cross-env.js BABEL_ENV=commonjs NODE_ENV=production ./node_modules/webpack/bin/webpack.js src/index.js dist/redux-modifiers.min.js",
    "build": "npm run build:commonjs && npm run build:es && npm run build:umd && npm run build:umd:min",
    "prepublish": "npm run clean && npm run build"
  },
  "repository": {
    "type": "git",
    "url": "git+https://github.com/calvinfroedge/redux-modifiers.git"
  },
  "keywords": [
    "react",
    "redux",
    "helpers",
    "state",
    "modifiers"
  ],
  "author": "Calvin Froedge <calvinfroedge@gmail.com>",
  "license": "MIT",
  "bugs": {
    "url": "https://github.com/calvinfroedge/redux-modifiers/issues"
  },
  "homepage": "https://github.com/calvinfroedge/redux-modifiers#readme",
  "dependencies": {
    "immutable": "^3.8.1",
    "redux-actions": "^0.9.1"
  },
  "devDependencies": {
    "babel-cli": "^6.7.5",
    "babel-core": "^6.7.4",
    "babel-loader": "^6.2.4",
    "babel-plugin-transform-runtime": "^6.6.0",
    "babel-preset-es2015": "^6.6.0",
    "babel-preset-react": "^6.5.0",
    "babel-preset-stage-0": "^6.5.0",
    "babel-register": "^6.7.2",
    "cross-env": "^1.0.7",
    "expect": "^1.16.0",
    "jsdom": "^8.1.0",
    "mocha": "^2.4.5",
    "mocha-jsdom": "^1.1.0",
    "redux": "^3.4.0",
    "redux-actions": "^0.9.1",
    "rimraf": "^2.5.2",
    "webpack": "^1.12.14"
  }
}


================================================
FILE: src/index.js
================================================
import Immutable from 'immutable'
import { handleActions } from 'redux-actions'
import { checkPayload, checkUpdate, modifier, isUndefined } from './utility'

/**
 * Create a reducer
 */
export function reducer(handlers, state){
  return handleActions(handlers, Immutable.fromJS(state));
}

/**
 * Push item to state 
 */
export function push(state, action){
  checkPayload(action);

  let value = action.payload;
  return state.push(Immutable.fromJS(value));
}

/**
 * Update a specific key or index
 */
export function update(state, action){
  checkPayload(action);
  checkUpdate(action);

  let { key, value, fn } = action.payload;

  if(isUndefined(key)) throw new Error('"key" must be present in payload!');

  return state.update(key, modifier(value, fn));
}

/**
 * Update at a selection path
 */
export function updateIn(state, action){
  checkPayload(action);
  checkUpdate(action);

  let { selected, value, fn } = action.payload;

  if(isUndefined(selected)) throw new Error('"selected" must be present in payload!');

  return state.updateIn(selected, modifier(value, fn));
}

/**
 * Remove a specific index or key
 */
export function remove(state, action){
  checkPayload(action);

  return state.remove(action.payload);
}

/**
 * Remove at a selection path
 */
export function removeIn(state, action){
  checkPayload(action);

  return state.removeIn(action.payload);
}


================================================
FILE: src/utility.js
================================================
import Immutable from 'immutable'

export function isUndefined(check){
  return typeof(check) == 'undefined';
}

export function checkPayload(action){
  if(isUndefined(action.payload)) throw new Error("Action must contain a payload!");
}

export function checkUpdate(action){
  let { payload } = action;
  let { value, fn } = payload;

  if(isUndefined(value) && isUndefined(value)) throw new Error("Either 'value' or 'fn' must be present in payload!");

  if(!isUndefined(value) && !isUndefined(fn)) throw new Error("Both 'value' and 'fn' cannot be present in payload!");
}

export function modifier(value, fn){
  return !isUndefined(value) ? val => Immutable.fromJS(value) : fn;
}


================================================
FILE: test/redux.spec.js
================================================
import expect from 'expect'
import { reducer, push, update, updateIn, remove, removeIn } from '../src'
import { createAction as action } from 'redux-actions'
import { createStore } from 'redux'
import { List, Map } from 'immutable'

describe('Test with actual reducer', ()=>{
  var store;

  let getJSON = ()=>{
    return [
      {
        foo: 'bar',
        nested: [
          {bar: 'bop'}
        ]
      }
    ]
  }

  beforeEach(()=>{
    let testReducer = reducer({
      'push': push,
      'update': update,
      'updateIn': updateIn,
      'remove': remove,
      'removeIn': removeIn
    }, getJSON());
    store = createStore(testReducer);
  });

  it('Push should create an immutable list, with an item that is an immutable map', ()=>{
    store.dispatch(
      action('push')(
        {foo: 'bar'}
      )
    );
    let state = store.getState();
    expect(List.isList(state)).toBe(true);
    expect(Map.isMap(state.last())).toBe(true);
  });

  it('Should update a nested item with updateIn', ()=>{
    let path = [0, 'nested', 0, 'bar']
    store.dispatch(
      action('updateIn')(
        {selected: path, value: 'baz'}
      )
    );
    let state = store.getState();
    expect(state.getIn(path)).toBe('baz');
  });

  it('Should remove a nested item with removeIn', ()=>{
    let path = [0, 'nested', 0];
    store.dispatch(
      action('removeIn')(path)
    );
    let state = store.getState();
    expect(state.getIn(path)).toBe(undefined);
  });

  it('Should remove an item', ()=>{
    store.dispatch(
      action('remove')(0)
    );

    let state = store.getState();
    expect(state.size).toBe(0);
  });

  it('Should update an item with update', ()=>{
    store.dispatch(
      action('update')({
        key: 0,
        value: false
      })
    );

    let state = store.getState();
    expect(state.first()).toBe(false);
  });
});


================================================
FILE: webpack.config.js
================================================
'use strict'; //This file was lifted from Redux source code. Thanks!

var webpack = require('webpack')

var env = process.env.NODE_ENV
var config = {
  module: {
    loaders: [
      { test: /\.js$/, loaders: ['babel-loader'], exclude: /node_modules/ }
    ]
  },
  output: {
    library: 'ReduxModifiers',
    libraryTarget: 'umd'
  },
  plugins: [
    new webpack.optimize.OccurenceOrderPlugin(),
    new webpack.DefinePlugin({
      'process.env.NODE_ENV': JSON.stringify(env)
    })
  ]
};

if (env === 'production') {
  config.plugins.push(
    new webpack.optimize.UglifyJsPlugin({
      compressor: {
        pure_getters: true,
        unsafe: true,
        unsafe_comps: true,
        screw_ie8: true,
        warnings: false
      }
    })
  )
}

module.exports = config
Download .txt
gitextract_6wxp96t_/

├── .babelrc
├── .gitignore
├── .npmignore
├── README.md
├── package.json
├── src/
│   ├── index.js
│   └── utility.js
├── test/
│   └── redux.spec.js
└── webpack.config.js
Download .txt
SYMBOL INDEX (10 symbols across 2 files)

FILE: src/index.js
  function reducer (line 8) | function reducer(handlers, state){
  function push (line 15) | function push(state, action){
  function update (line 25) | function update(state, action){
  function updateIn (line 39) | function updateIn(state, action){
  function remove (line 53) | function remove(state, action){
  function removeIn (line 62) | function removeIn(state, action){

FILE: src/utility.js
  function isUndefined (line 3) | function isUndefined(check){
  function checkPayload (line 7) | function checkPayload(action){
  function checkUpdate (line 11) | function checkUpdate(action){
  function modifier (line 20) | function modifier(value, fn){
Condensed preview — 9 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (11K chars).
[
  {
    "path": ".babelrc",
    "chars": 61,
    "preview": "{\n  \"presets\": [\"es2015\", \"react\", \"babel-preset-stage-0\"]\n}\n"
  },
  {
    "path": ".gitignore",
    "chars": 31,
    "preview": "*.sw*\nnode_modules\ndist\nlib\nes\n"
  },
  {
    "path": ".npmignore",
    "chars": 6,
    "preview": "*.sw*\n"
  },
  {
    "path": "README.md",
    "chars": 3007,
    "preview": "# Write better Redux code faster v0.0.5\n\n<em>Big changes from 0.0.4! API has been completely rewritten on top of [Immuta"
  },
  {
    "path": "package.json",
    "chars": 2221,
    "preview": "{\n  \"name\": \"redux-modifiers\",\n  \"version\": \"0.0.6\",\n  \"description\": \"A collection of generic functions for writing red"
  },
  {
    "path": "src/index.js",
    "chars": 1383,
    "preview": "import Immutable from 'immutable'\nimport { handleActions } from 'redux-actions'\nimport { checkPayload, checkUpdate, modi"
  },
  {
    "path": "src/utility.js",
    "chars": 683,
    "preview": "import Immutable from 'immutable'\n\nexport function isUndefined(check){\n  return typeof(check) == 'undefined';\n}\n\nexport "
  },
  {
    "path": "test/redux.spec.js",
    "chars": 1868,
    "preview": "import expect from 'expect'\nimport { reducer, push, update, updateIn, remove, removeIn } from '../src'\nimport { createAc"
  },
  {
    "path": "webpack.config.js",
    "chars": 781,
    "preview": "'use strict'; //This file was lifted from Redux source code. Thanks!\n\nvar webpack = require('webpack')\n\nvar env = proces"
  }
]

About this extraction

This page contains the full source code of the calvinfroedge/redux-modifiers GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 9 files (9.8 KB), approximately 2.8k tokens, and a symbol index with 10 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!