Skip to content

Commit

Permalink
feat: add Immutable v4 compatibility (#61)
Browse files Browse the repository at this point in the history
* fix: pass type check for Record in Immutable v4
* fix: extracting keys from Record in Immutable v4
* refactor: change warning to better reflect Immutable v4 types
* docs: better reflect both Immutable v3 and v4 types
* docs: replace Immutable.Iterable with Immutable.Collection

BREAKING CHANGE:

* build: change dependency type for immutable and extend version supported
  • Loading branch information
Velenir authored and gajus committed Mar 14, 2017
1 parent 50e3656 commit db26f25
Show file tree
Hide file tree
Showing 4 changed files with 13 additions and 12 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@

`redux-immutable` is used to create an equivalent function of Redux [`combineReducers`](http://redux.js.org/docs/api/combineReducers.html) that works with [Immutable.js](https://facebook.github.io/immutable-js/) state.

When Redux [`createStore`](https://github.com/reactjs/redux/blob/master/docs/api/createStore.md) `reducer` is created using `redux-immutable` then `initialState` must be an instance of [`Immutable.Iterable`](https://facebook.github.io/immutable-js/docs/#/Iterable).
When Redux [`createStore`](https://github.com/reactjs/redux/blob/master/docs/api/createStore.md) `reducer` is created using `redux-immutable` then `initialState` must be an instance of [`Immutable.Collection`](https://facebook.github.io/immutable-js/docs/#/Collection).

## Problem

When [`createStore`](https://github.com/reactjs/redux/blob/v3.0.6/docs/api/createStore.md) is invoked with `initialState` that is an instance of `Immutable.Iterable` further invocation of reducer will [produce an error](https://github.com/reactjs/redux/blob/v3.0.6/src/combineReducers.js#L31-L38):
When [`createStore`](https://github.com/reactjs/redux/blob/v3.0.6/docs/api/createStore.md) is invoked with `initialState` that is an instance of `Immutable.Collection` further invocation of reducer will [produce an error](https://github.com/reactjs/redux/blob/v3.0.6/src/combineReducers.js#L31-L38):

> The initialState argument passed to createStore has unexpected type of "Object".
> Expected argument to be an object with the following keys: "data"
Expand All @@ -21,7 +21,7 @@ This is because Redux `combineReducers` [treats `state` object as a plain JavaSc

## Usage

Create a store with `initialState` set to an instance of [`Immutable.Iterable`](https://facebook.github.io/immutable-js/docs/#/Iterable):
Create a store with `initialState` set to an instance of [`Immutable.Collection`](https://facebook.github.io/immutable-js/docs/#/Collection):

```js
import {
Expand Down Expand Up @@ -58,7 +58,7 @@ const rootReducer = combineReducers({foo: fooReducer}, StateRecord);
// state now must always have 'foo' property with its default value returned from fooReducer(undefined, action)
```

In general, `getDefaultState` function must return an instance of `Immutable.Iterable` that implements `get`, `set` and `withMutations` methods. Such iterables are `List`, `Map`, `OrderedMap` and `Record`.
In general, `getDefaultState` function must return an instance of `Immutable.Record` or `Immutable.Collection` that implements `get`, `set` and `withMutations` methods. Such collections are `List`, `Map` and `OrderedMap`.

### Using with `react-router-redux`

Expand Down
7 changes: 4 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@
"url": "http://gajus.com"
},
"license": "BSD-3-Clause",
"dependencies": {
"immutable": "^3.8.1"
},
"peerDependencies": {
"immutable": "^3.8.1 || ^4.0.0-rc.1"
},
"devDependencies": {
"babel-cli": "^6.18.0",
"babel-plugin-add-module-exports": "^0.2.1",
Expand All @@ -35,6 +35,7 @@
"eslint-config-canonical": "^6.0.0",
"flow-runtime": "0.0.6",
"husky": "^0.12.0",
"immutable": "^3.8.1 || ^4.0.0-rc.1",
"mocha": "^3.2.0",
"semantic-release": "^6.3.2"
},
Expand Down
6 changes: 3 additions & 3 deletions src/utilities/getUnexpectedInvocationParameterMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,11 +10,11 @@ export default (state: Object, reducers: Object, action: Object) => {

const stateName = getStateName(action);

if (!Immutable.Iterable.isIterable(state)) {
return 'The ' + stateName + ' is of unexpected type. Expected argument to be an instance of Immutable.Iterable with the following properties: "' + reducerNames.join('", "') + '".';
if (Immutable.isImmutable ? !Immutable.isImmutable(state) : !Immutable.Iterable.isIterable(state)) {
return 'The ' + stateName + ' is of unexpected type. Expected argument to be an instance of Immutable.Collection or Immutable.Record with the following properties: "' + reducerNames.join('", "') + '".';
}

const unexpectedStatePropertyNames = state.keySeq().toArray().filter((name) => {
const unexpectedStatePropertyNames = state.toSeq().keySeq().toArray().filter((name) => {
return !reducers.hasOwnProperty(name);
});

Expand Down
4 changes: 2 additions & 2 deletions tests/utilities/getUnexpectedInvocationParameterMessage.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,11 @@ describe('utilities', () => {
expect(expectedErrorMessage).to.equal('Store does not have a valid reducer. Make sure the argument passed to combineReducers is an object whose values are reducers.');
});
});
context('state is not an instance of Immutable.Iterable', () => {
context('state is not an instance of Immutable.Collection or Immutable.Record', () => {
it('returns error', () => {
const expectedErrorMessage = getUnexpectedInvocationParameterMessage({}, validReducers, validAction);

expect(expectedErrorMessage).to.equal('The initialState argument passed to createStore is of unexpected type. Expected argument to be an instance of Immutable.Iterable with the following properties: "foo".');
expect(expectedErrorMessage).to.equal('The initialState argument passed to createStore is of unexpected type. Expected argument to be an instance of Immutable.Collection or Immutable.Record with the following properties: "foo".');
});
});
context('state defines properties that are not present in the reducer map', () => {
Expand Down

0 comments on commit db26f25

Please sign in to comment.