Comparing version 0.0.3 to 0.0.4
@@ -6,3 +6,3 @@ // @ts-check | ||
/** | ||
* Immer takes a state, and runs a function agains it. | ||
* Immer takes a state, and runs a function against it. | ||
* That function can freely mutate the state, as it will create copies-on-write. | ||
@@ -59,3 +59,3 @@ * This means that the original state will stay unchanged, and once the function finishes, the modified state is returned | ||
// returns the current source of trugth for a base object | ||
// returns the current source of truth for a base object | ||
function getCurrentSource(base) { | ||
@@ -133,5 +133,5 @@ const copy = copies.get(base) | ||
function isProxy(value) { | ||
return !!value[isProxySymbol] | ||
return !!value && !!value[isProxySymbol] | ||
} | ||
module.exports = immer |
{ | ||
"name": "immer", | ||
"version": "0.0.3", | ||
"version": "0.0.4", | ||
"description": "Create your next immutable state by mutating the current one", | ||
"main": "immer.js", | ||
"types": "./index.d.ts", | ||
"scripts": { | ||
@@ -7,0 +8,0 @@ "test": "jest" |
# Immer | ||
_Your personally assistance for creating your next immutable state_ | ||
--- | ||
Immer (German for: always) is a tiny package that allows you work with immutable state in a more convenient way. | ||
It is based on [_copy-on-write_](https://en.wikipedia.org/wiki/Copy-on-write) mechanism. | ||
The basic idea is that you will modify (a proxy of) the current state, and once that is completed, the copy will be finalized and form the next state. | ||
As soon as a piece of the state is modified, it is copied. That is what one typically does by hand (in for example Redux reducers). | ||
The basic idea is that you will apply all your changes to a _draftState_. Which is a proxy of the _currentState_, and once all your mutations are completed, immer will produce the _nextState_ based on the mutations to the draft state. This means that you can interact with your data by simply modifying it, while keeping all the benefits of immutable data. | ||
_This means that you can interact with your data by using mutations, will keeping all the benefits of immutable data_ | ||
<center> | ||
![immer.png](immer.png) | ||
Using immer is like having a personal assistant; he takes a letter (the current state), and gives you a copy (draft) to jod changes onto. Once you are done the assistant will take your draft and produce the real immutable, final letter for you (the next state). | ||
</center> | ||
## API | ||
The immer package exposes a single function: | ||
`immer(currentState, fn: (state) => void): nextState` | ||
`immer(currentState, fn: (draftState) => void): nextState` | ||
@@ -29,9 +39,9 @@ ## Example | ||
const nextState = immer(baseState, state => { | ||
state.push({ todo: "Tweet about it" }) | ||
state[1].done = true | ||
const nextState = immer(baseState, draftState => { | ||
draftState.push({ todo: "Tweet about it" }) | ||
draftState[1].done = true | ||
}) | ||
``` | ||
The interesting thing about `immer` is that `baseState` will be untouched, but that `nextState` will reflect all changes made to `state`. | ||
The interesting thing about `immer` is that `baseState` will be untouched, but that `nextState` will reflect all changes made to `draftState`. | ||
@@ -54,2 +64,10 @@ ```javascript | ||
## Benefits | ||
* Use the language© to construct create your next state | ||
* Strongly typed, no string based paths etc | ||
* Deep updates are trivial | ||
* Small, dependency free library with minimal api surface | ||
* No accidental mutations of current state, but intentional mutations of a draft state | ||
## Reducer Example | ||
@@ -60,2 +78,4 @@ | ||
_Note, this is just a sample application of the `immer` package. Immer is design to just simply Redux reducers. It can be used in any context where you have an immutable data tree that you want to clone and modify (with structural sharing)_ | ||
```javascript | ||
@@ -107,6 +127,7 @@ const todo = (state, action) => { | ||
const todos = (state = [], action) => | ||
immer(state, state => { | ||
// immer produces nextState from draftState and returns it | ||
immer(state, draftState => { | ||
switch (action.type) { | ||
case 'ADD_TODO': | ||
state.push({ | ||
draftState.push({ | ||
id: action.id, | ||
@@ -118,3 +139,3 @@ text: action.text, | ||
case 'TOGGLE_TODO': | ||
const todo = state.find(todo => todo.id === action.id) | ||
const todo = draftState.find(todo => todo.id === action.id) | ||
todo.completed = !todo.completed | ||
@@ -136,2 +157,10 @@ return | ||
* Make sure to modify the state you get passed in in the callback function, not the original base state that was passed as first argument to `immer`! | ||
* Make sure to modify the state you get passed in in the callback function, not the original base state that was passed as first argument to `immer`! | ||
* Since immer uses proxies, reading huge amounts of data from state comes with an overhead. If this ever becomes an issue (measure before optimize!), do the current state analysis before entering the `immer` block or read form the `currentState` rather than the `draftState` | ||
## Changelog | ||
### 0.0.4 (31-12-2017) | ||
* Added typescript typings [#11](https://github.com/mweststrate/immer/pull/11) by [@benbraou](https://github.com/benbraou) | ||
* Fixed bug when setting properties to `undefined`. Fixes [#12](https://github.com/mweststrate/immer/issues/12) through [#13](https://github.com/mweststrate/immer/pull/13) by [@benbraou](https://github.com/benbraou) |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
11799
160