177 lines
4.6 KiB
Markdown
177 lines
4.6 KiB
Markdown
# updeep [![NPM version][npm-image]][npm-url] [![Build Status][travis-image]][travis-url] [![Dependency Status][daviddm-image]][daviddm-url]
|
|
> Easily update nested frozen objects and arrays in a declarative and immutable
|
|
> manner.
|
|
|
|
## About
|
|
|
|
Updating deeply nested objects/arrays is a bit of a pain.
|
|
updeep makes it painless by allowing you to declare the updates you would like
|
|
to make and it will take care of the rest.
|
|
It will recursively return the same instance if no changes have been made,
|
|
making it ideal for using reference equality checks to detect changes (like
|
|
[PureRenderMixin]). Because of this, everything returned by updeep is frozen.
|
|
|
|
updeep requires [lodash], but works very well with [lodash-fp] or [Ramda]. As a
|
|
matter of fact, many of the helpers functions are [curried][currying] [lodash]
|
|
functions with their parameters reversed (as [lodash-fp] do).
|
|
|
|
Note that the parameters may be backwards from what you are used to. updeep
|
|
supports [partial application][currying], so the parameter order is:
|
|
`updeep(updates, obj)`.
|
|
|
|
## API and Examples
|
|
|
|
### Full example
|
|
```js
|
|
var u = require('updeep');
|
|
|
|
var person = {
|
|
name: {
|
|
first: 'Bill',
|
|
last: 'Sagat',
|
|
},
|
|
children: ['Marty', 'Ashley'],
|
|
email: 'bill@example.com',
|
|
version: 1
|
|
};
|
|
|
|
var inc = function(i) { return i + 1; }
|
|
|
|
var newPerson = u({
|
|
name: {
|
|
first: 'Bob',
|
|
},
|
|
children: { 0: 'Mary-Kate' },
|
|
email: 'bob@example.com',
|
|
version: inc
|
|
}, person);
|
|
|
|
// => {
|
|
// name: {
|
|
// first: 'Bob',
|
|
// last: 'Sagat',
|
|
// },
|
|
// children: ['Mary-Kate', 'Ashley'],
|
|
// email: 'bob@example.com',
|
|
// version: 2
|
|
// }
|
|
```
|
|
|
|
### Simple update
|
|
|
|
```js
|
|
u({ x: { b: 3 } }, { x: { a: 0, b: 0 } });
|
|
// => { x: { a: 0, b: 3 } }
|
|
```
|
|
|
|
### Multiple updates, including an array
|
|
|
|
```js
|
|
u({ x: { b: 3 }, y: { 1: 4 } }, { x: { a: 0, b: 0 }, y: [0, 0] });
|
|
// => { x: { a: 0, b: 3 }, y: [0, 4] }
|
|
```
|
|
|
|
### Use a function
|
|
|
|
```js
|
|
function inc(i) { return i + 1; }
|
|
u({ x: { b: inc } }, { x: { a: 0, b: 0 } });
|
|
// => { x: { a: 0, b: 1 } }
|
|
```
|
|
|
|
### Partial application
|
|
|
|
```js
|
|
var setBTo3 = u({ b: 3 });
|
|
setBTo3({ a: 0, b: 0 });
|
|
// => { a: 0, b: 3 })
|
|
```
|
|
|
|
### Remove a property
|
|
|
|
```js
|
|
u({ x: u.omit('b') }, { x: { a: 0, b: 0 } });
|
|
// => { x: { a: 0 } }
|
|
```
|
|
|
|
### Reject an item from an array
|
|
|
|
```js
|
|
function even(i) { return i % 2 === 0 };
|
|
u({ x: u.reject(even) }, { x: [1, 2, 3, 4] });
|
|
// => { x: [1, 3] }
|
|
```
|
|
|
|
### With a default
|
|
|
|
```js
|
|
u({ x: withDefault([], { 0: 3 }) }, {});
|
|
// => { x: [3] }
|
|
```
|
|
|
|
### ES6 computed properties
|
|
|
|
```js
|
|
var key = 'b';
|
|
u({ x: { [key]: 3 } }, { x: { a: 0, b: 0 } });
|
|
// => { x: { a: 0, b: 3 } }
|
|
```
|
|
|
|
See the [tests] for more examples.
|
|
|
|
## Install
|
|
|
|
```sh
|
|
$ npm install --save updeep
|
|
```
|
|
|
|
Requires [lodash] as a peer dependency, so make sure you have it installed as
|
|
well.
|
|
|
|
## Configuration
|
|
|
|
If `NODE_ENV` is `"production"`, updeep will not attempt to freeze objects.
|
|
This may yield a slight performance gain.
|
|
|
|
## Motivation
|
|
|
|
While creating reducers for use with [redux], I wanted something that made it
|
|
easy to work with frozen objects. Native javascript objects have some nice
|
|
advantages over things like [Immutable.js][immutablejs] such as debugging and
|
|
destructuring. I wanted something more powerful than [icepick] and more
|
|
composable than [React.addons.update].
|
|
|
|
If you're manipulating massive amounts of data frequently, you may want to
|
|
benchmark, as [Immutable.js][immutablejs] should be more efficient in that
|
|
case.
|
|
|
|
## Contributing
|
|
|
|
1. Fork it.
|
|
1. Create your feature branch (`git checkout -b my-new-feature`).
|
|
1. Run `gulp` to run tests and lint.
|
|
1. Commit your changes (`git commit -am 'Added some feature'`).
|
|
1. Push to the branch (`git push origin my-new-feature`).
|
|
1. Create new Pull Request.
|
|
|
|
## License
|
|
|
|
MIT ©2015 [Aaron Jensen](https://twitter.com/aaronjensen)
|
|
|
|
[npm-image]: https://badge.fury.io/js/updeep.svg
|
|
[npm-url]: https://npmjs.org/package/updeep
|
|
[travis-image]: https://travis-ci.org/aaronjensen/updeep.svg?branch=master
|
|
[travis-url]: https://travis-ci.org/aaronjensen/updeep
|
|
[daviddm-image]: https://david-dm.org/aaronjensen/updeep.svg?theme=shields.io
|
|
[daviddm-url]: https://david-dm.org/aaronjensen/updeep
|
|
[lodash]: http://lodash.com
|
|
[lodash-fp]: https://github.com/lodash/lodash-fp
|
|
[Ramda]: http://ramdajs.com/
|
|
[PureRenderMixin]: https://facebook.github.io/react/docs/pure-render-mixin.html
|
|
[redux]: https://github.com/gaearon/redux
|
|
[immutablejs]: https://github.com/facebook/immutable-js
|
|
[icepick]: https://github.com/aearly/icepick
|
|
[React.addons.update]: https://facebook.github.io/react/docs/update.html
|
|
[tests]: https://github.com/aaronjensen/updeep/blob/master/test/index.js
|
|
[currying]: http://www.datchley.name/currying-vs-partial-application/
|