{"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"keywords":["immutability"],"dist-tags":{"latest":"2.2.2"},"author":{"name":"Moshe Kolodny"},"description":"mutate a copy of data without changing the original source","readme":"immutability-helper\n===\n\n[![NPM version][npm-image]][npm-url]\n[![Build status][travis-image]][travis-url]\n[![Test coverage][coveralls-image]][coveralls-url]\n[![Downloads][downloads-image]][downloads-url]\n\nMutate a copy of data without changing the original source\n\nThis is a drop-in replacement for [`react-addons-update`](https://facebook.github.io/react/docs/update.html):\n\n```js\n// import update from 'react-addons-update';\nimport update from 'immutability-helper';\n\nconst state1 = ['x'];\nconst state2 = update(state1, {$push: ['y']}); // ['x', 'y']\n```\n\nNote that this module has nothing to do with React. However, since this module is most commonly used with React, the docs will focus on how it can be used with React.\n\n## Overview\n\nReact lets you use whatever style of data management you want, including mutation. However, if you can use immutable data in performance-critical parts of your application it's easy to implement a fast [`shouldComponentUpdate()`](https://facebook.github.io/react/docs/react-component.html#shouldcomponentupdate) method to significantly speed up your app.\n\nDealing with immutable data in JavaScript is more difficult than in languages designed for it, like [Clojure](http://clojure.org/). However, we've provided a simple immutability helper, `update()`, that makes dealing with this type of data much easier, *without* fundamentally changing how your data is represented. You can also take a look at Facebook's [Immutable.js](https://facebook.github.io/immutable-js/docs/) and React’s [Using Immutable Data Structures](https://facebook.github.io/react/docs/optimizing-performance.html#using-immutable-data-structures) section for more detail on Immutable.js.\n\n### The Main Idea\n\nIf you mutate data like this:\n\n```js\nmyData.x.y.z = 7;\n// or...\nmyData.a.b.push(9);\n```\n\nYou have no way of determining which data has changed since the previous copy has been overwritten. Instead, you need to create a new copy of `myData` and change only the parts of it that need to be changed. Then you can compare the old copy of `myData` with the new one in `shouldComponentUpdate()` using triple-equals:\n\n```js\nconst newData = deepCopy(myData);\nnewData.x.y.z = 7;\nnewData.a.b.push(9);\n```\n\nUnfortunately, deep copies are expensive, and sometimes impossible. You can alleviate this by only copying objects that need to be changed and by reusing the objects that haven't changed. Unfortunately, in today's JavaScript this can be cumbersome:\n\n```js\nconst newData = extend(myData, {\n  x: extend(myData.x, {\n    y: extend(myData.x.y, {z: 7}),\n  }),\n  a: extend(myData.a, {b: myData.a.b.concat(9)})\n});\n```\n\nWhile this is fairly performant (since it only makes a shallow copy of `log n` objects and reuses the rest), it's a big pain to write. Look at all the repetition! This is not only annoying, but also provides a large surface area for bugs.\n\n## `update()`\n\n`update()` provides simple syntactic sugar around this pattern to make writing this code easier. This code becomes:\n\n```js\nimport update from 'immutability-helper';\n\nconst newData = update(myData, {\n  x: {y: {z: {$set: 7}}},\n  a: {b: {$push: [9]}}\n});\n```\n\nWhile the syntax takes a little getting used to (though it's inspired by [MongoDB's query language](http://docs.mongodb.org/manual/core/crud-introduction/#query)) there's no redundancy, it's statically analyzable and it's not much more typing than the mutative version.\n\nThe `$`-prefixed keys are called *commands*. The data structure they are \"mutating\" is called the *target*.\n\n## Available Commands\n\n  * `{$push: array}` `push()` all the items in `array` on the target.\n  * `{$unshift: array}` `unshift()` all the items in `array` on the target.\n  * `{$splice: array of arrays}` for each item in `arrays` call `splice()` on the target with the parameters provided by the item. ***Note:** The items in the array are applied sequentially, so the order matters. The indices of the target may change during the operation.*\n  * `{$set: any}` replace the target entirely.\n  * `{$unset: array of strings}` remove the list of keys in `array` from the target object.\n  * `{$merge: object}` merge the keys of `object` with the target.\n  * `{$apply: function}` passes in the current value to the function and updates it with the new returned value.\n\n## Examples\n\n### Simple push\n\n```js\nconst initialArray = [1, 2, 3];\nconst newArray = update(initialArray, {$push: [4]}); // => [1, 2, 3, 4]\n```\n`initialArray` is still `[1, 2, 3]`.\n\n### Nested collections\n\n```js\nconst collection = [1, 2, {a: [12, 17, 15]}];\nconst newCollection = update(collection, {2: {a: {$splice: [[1, 1, 13, 14]]}}});\n// => [1, 2, {a: [12, 13, 14, 15]}]\n```\nThis accesses `collection`'s index `2`, key `a`, and does a splice of one item starting from index `1` (to remove `17`) while inserting `13` and `14`.\n\n### Updating a value based on its current one\n\n```js\nconst obj = {a: 5, b: 3};\nconst newObj = update(obj, {b: {$apply: function(x) {return x * 2;}}});\n// => {a: 5, b: 6}\n// This is equivalent, but gets verbose for deeply nested collections:\nconst newObj2 = update(obj, {b: {$set: obj.b * 2}});\n```\n\n### (Shallow) Merge\n\n```js\nconst obj = {a: 5, b: 3};\nconst newObj = update(obj, {$merge: {b: 6, c: 7}}); // => {a: 5, b: 6, c: 7}\n```\n\n### [Autovivification](https://en.wikipedia.org/wiki/Autovivification)\n\nAutovivification is the auto creation of new arrays and objects when needed. In the context\nof javascript that would mean something like this\n\n```js\nconst state = {}\nstate.a.b.c = 1; // state would equal { a: { b: { c: 1 } } }\n```\n\nSince javascript doesn't have this \"feature\", the same applies to `immutability-helper`. The reason\nwhy this is practically impossible in javascript and by extension `immutability-helper` is the following:\n\n```js\nvar state = {}\nstate.thing[0] = 'foo' // What type should state.thing have? Should it be an object or array?\nstate.thing2[1] = 'foo2' // What about thing2? This must be an object!\nstate.thing3 = ['thing3'] // This is regular js, this works without autovivification\nstate.thing3[1] = 'foo3' // Hmm, notice that state.thing2 is an object, yet this is an array\nstate.thing2.slice // should be undefined\nstate.thing2.slice // should be a function\n```\n\nIf you need to set something deeply nested and don't want to have to set each layer down the line,\nconsider using this technique which is shown with a contrived example:\n\n```js\nvar state = {}\nvar desiredState = {\n  foo: [\n    {\n      bar: ['x', 'y', 'z']\n    },\n  ],\n};\n\nvar state2 = update(state, {\n  foo: {$apply: foo =>\n    update(foo || [], {\n      0: {$apply: fooZero =>\n        update(fooZero || {}, {\n          bar: {$apply: bar =>\n            update(bar || [], {$push: ['x', 'y', 'z']})\n          }\n        })\n      }\n    })\n  }\n})\n\nconsole.log(JSON.stringify(state2) === JSON.stringify(desiredState)) // true\n// note that state could have been declared as any of the following and it would still output true:\n// var state = { foo: [] }\n// var state = { foo: [ {} ] }\n// var state = { foo: [ {bar: []} ] }\n```\n\n---\n\n## Adding your own commands\n\nThe main difference this module has with `react-addons-update` is that\nyou can extend this to give it more functionality:\n\n```js\nupdate.extend('$addtax', function(tax, original) {\n  return original + (tax * original);\n});\nconst state = { price: 123 };\nconst withTax = update(state, {\n  price: {$addtax: 0.8},\n});\nassert(JSON.stringify(withTax) === JSON.stringify({ price: 221.4 }));\n```\n\nNote that `original` in the function above is the original object, so if you plan making a\nmutation, you must first shallow clone the object. Another option is to\nuse `update` to make the change `return update(original, { foo: {$set: 'bar'} })`\n\nIf you don't want to mess around with the globally exported `update` function you can make a copy and work with that copy:\n\n```js\nimport { newContext } from 'immutability-helper';\nconst myUpdate = newContext();\nmyUpdate.extend('$foo', function(value, original) {\n  return 'foo!';\n});\n```\n\n[npm-image]: https://img.shields.io/npm/v/immutability-helper.svg?style=flat-square\n[npm-url]: https://npmjs.org/package/immutability-helper\n[travis-image]: https://img.shields.io/travis/kolodny/immutability-helper.svg?style=flat-square\n[travis-url]: https://travis-ci.org/kolodny/immutability-helper\n[coveralls-image]: https://img.shields.io/coveralls/kolodny/immutability-helper.svg?style=flat-square\n[coveralls-url]: https://coveralls.io/r/kolodny/immutability-helper\n[downloads-image]: http://img.shields.io/npm/dm/immutability-helper.svg?style=flat-square\n[downloads-url]: https://npmjs.org/package/immutability-helper\n","repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"users":{"krickray":true,"zorak":true,"usingthesystem":true,"atulmy":true},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"license":"MIT","versions":{"1.0.0":{"name":"immutability-helper","version":"1.0.0","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"50f7ee7b2fcaa367a74f299a320ab4f5c0df19b6","_id":"immutability-helper@1.0.0","_shasum":"7d0e0ed6f1534480e16caae07e3bd2a4f8c5c5b3","_from":".","_npmVersion":"3.3.12","_nodeVersion":"5.5.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"7d0e0ed6f1534480e16caae07e3bd2a4f8c5c5b3","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-1.0.0.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"packages-6-west.internal.npmjs.com","tmp":"tmp/immutability-helper-1.0.0.tgz_1456368275767_0.7994816896971315"},"directories":{}},"2.0.0":{"name":"immutability-helper","version":"2.0.0","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"6171d78adf8aa5a8809293d777b8eee1136f6cac","_id":"immutability-helper@2.0.0","_shasum":"371657666eacf96f731f9f97e5cccd920b13a5d4","_from":".","_npmVersion":"3.3.12","_nodeVersion":"5.5.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"371657666eacf96f731f9f97e5cccd920b13a5d4","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.0.0.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/immutability-helper-2.0.0.tgz_1459483686808_0.0009736423380672932"},"directories":{}},"2.1.0":{"name":"immutability-helper","version":"2.1.0","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"954aa16a302a8db9d465ea15ec5296ddae87ac5f","_id":"immutability-helper@2.1.0","_shasum":"35a4bc77e4deb120b8c37079a980f9bad834ba2d","_from":".","_npmVersion":"2.14.3","_nodeVersion":"3.3.1","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"35a4bc77e4deb120b8c37079a980f9bad834ba2d","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.1.0.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/immutability-helper-2.1.0.tgz_1483319579820_0.7485366004984826"},"directories":{}},"2.1.1":{"name":"immutability-helper","version":"2.1.1","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"1dc63ab1d52dca4bef2da4897328669f21e5f3f3","_id":"immutability-helper@2.1.1","_shasum":"d80e7577fae14cddde99d8946666d79973e7ba13","_from":".","_npmVersion":"3.8.6","_nodeVersion":"6.0.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"d80e7577fae14cddde99d8946666d79973e7ba13","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.1.1.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/immutability-helper-2.1.1.tgz_1483893887524_0.09297690633684397"},"directories":{}},"2.1.2":{"name":"immutability-helper","version":"2.1.2","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"782d8d9f21b1e136d446e3e8df60e4fc16f6c330","_id":"immutability-helper@2.1.2","_shasum":"734506440d7209b74664dcadaa8ba14e73f2185b","_from":".","_npmVersion":"3.8.6","_nodeVersion":"6.0.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"734506440d7209b74664dcadaa8ba14e73f2185b","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.1.2.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"packages-12-west.internal.npmjs.com","tmp":"tmp/immutability-helper-2.1.2.tgz_1487773133960_0.684672563103959"},"directories":{}},"2.2.0":{"name":"immutability-helper","version":"2.2.0","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"989b4b6c5e8b073671136ebc7f25260bc0f0bab1","_id":"immutability-helper@2.2.0","_shasum":"c4385ad4f68315843efaf0cff3575ee82ffa405f","_from":".","_npmVersion":"4.1.2","_nodeVersion":"7.7.4","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"dist":{"shasum":"c4385ad4f68315843efaf0cff3575ee82ffa405f","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.2.0.tgz"},"_npmOperationalInternal":{"host":"packages-18-east.internal.npmjs.com","tmp":"tmp/immutability-helper-2.2.0.tgz_1493526904185_0.1429081643000245"},"directories":{}},"2.2.1":{"name":"immutability-helper","version":"2.2.1","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"d63e208b1b64cea52861b2e440497181919d3ea1","_id":"immutability-helper@2.2.1","_shasum":"a876a31d6ed3cffca8016edcbe9162df25a25e47","_from":".","_npmVersion":"4.0.5","_nodeVersion":"7.4.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"a876a31d6ed3cffca8016edcbe9162df25a25e47","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.2.1.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/immutability-helper-2.2.1.tgz_1495488152626_0.7548743481747806"},"directories":{}},"2.2.2":{"name":"immutability-helper","version":"2.2.2","description":"mutate a copy of data without changing the original source","main":"index.js","scripts":{"test-cov":"nyc npm test && nyc report --reporter=lcov","test-travis":"nyc npm test && nyc report --reporter=lcov","test":"mocha test.js"},"keywords":["immutability"],"author":{"name":"Moshe Kolodny"},"license":"MIT","devDependencies":{"coveralls":"^2.11.6","expect":"^1.14.0","mocha":"^2.4.5","nyc":"^5.6.0"},"dependencies":{"invariant":"^2.2.0"},"repository":{"type":"git","url":"git+https://github.com/kolodny/immutability-helper.git"},"bugs":{"url":"https://github.com/kolodny/immutability-helper/issues"},"homepage":"https://github.com/kolodny/immutability-helper#readme","gitHead":"004bef05045f8e67a3ecea3064d9fcf60f5daf85","_id":"immutability-helper@2.2.2","_shasum":"e7e9da728b3de2fad34a216f4157b326dbccc892","_from":".","_npmVersion":"4.0.5","_nodeVersion":"7.4.0","_npmUser":{"name":"kolodny","email":"kolodny.github@gmail.com"},"dist":{"shasum":"e7e9da728b3de2fad34a216f4157b326dbccc892","tarball":"http://nexus.dui88.com:8081/nexus/content/groups/npm-all/immutability-helper/-/immutability-helper-2.2.2.tgz"},"maintainers":[{"name":"kolodny","email":"kolodny.github@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages","tmp":"tmp/immutability-helper-2.2.2.tgz_1495492220674_0.40736707486212254"},"directories":{}}},"name":"immutability-helper","time":{"modified":"2017-05-22T22:30:21.781Z","created":"2016-02-25T02:44:38.267Z","1.0.0":"2016-02-25T02:44:38.267Z","2.0.0":"2016-04-01T04:08:09.011Z","2.1.0":"2017-01-02T01:13:02.066Z","2.1.1":"2017-01-08T16:44:49.650Z","2.1.2":"2017-02-22T14:18:55.996Z","2.2.0":"2017-04-30T04:35:04.985Z","2.2.1":"2017-05-22T21:22:33.706Z","2.2.2":"2017-05-22T22:30:21.781Z"},"readmeFilename":"README.md","homepage":"https://github.com/kolodny/immutability-helper#readme"}