Skip to content
This repository has been archived by the owner on May 23, 2018. It is now read-only.

Commit

Permalink
Bugfix: Immutable reducer updates state with mutable objects
Browse files Browse the repository at this point in the history
  • Loading branch information
ivan-nejezchleb committed Apr 10, 2017
1 parent 2acff8b commit dcddef2
Show file tree
Hide file tree
Showing 4 changed files with 136 additions and 23 deletions.
8 changes: 4 additions & 4 deletions dist/es/immutable/reducer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as actionTypes from '../lib/actionTypes';
import { Record } from 'immutable';
import { Record, fromJS } from 'immutable';

// eslint-disable-next-line new-cap
var State = Record({
Expand All @@ -15,13 +15,13 @@ function router5Reducer() {

switch (action.type) {
case actionTypes.TRANSITION_START:
return state.set('transitionRoute', action.payload.route).set('transitionError', null);
return state.set('transitionRoute', fromJS(action.payload.route)).set('transitionError', null);

case actionTypes.TRANSITION_SUCCESS:
return state.set('transitionRoute', null).set('transitionError', null).set('previousRoute', action.payload.previousRoute).set('route', action.payload.route);
return state.set('transitionRoute', null).set('transitionError', null).set('previousRoute', fromJS(action.payload.previousRoute)).set('route', fromJS(action.payload.route));

case actionTypes.TRANSITION_ERROR:
return state.set('transitionRoute', action.payload.route).set('transitionError', action.payload.transitionError);
return state.set('transitionRoute', fromJS(action.payload.route)).set('transitionError', fromJS(action.payload.transitionError));

case actionTypes.CLEAR_ERRORS:
return state.set('transitionRoute', null).set('transitionError', null);
Expand Down
138 changes: 125 additions & 13 deletions dist/umd/redux-router5.js
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ var actionTypes = Object.freeze({
});

function navigateTo(name) {
var params = arguments.length <= 1 || arguments[1] === undefined ? {} : arguments[1];
var opts = arguments.length <= 2 || arguments[2] === undefined ? {} : arguments[2];
var params = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
var opts = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};

return {
type: NAVIGATE_TO,
Expand Down Expand Up @@ -143,10 +143,10 @@ var actions = Object.freeze({
return function (action) {
switch (action.type) {
case NAVIGATE_TO:
var _action$payload = action.payload;
var name = _action$payload.name;
var params = _action$payload.params;
var opts = _action$payload.opts;
var _action$payload = action.payload,
name = _action$payload.name,
params = _action$payload.params,
opts = _action$payload.opts;

router.navigate(name, params, opts);
break;
Expand Down Expand Up @@ -174,9 +174,122 @@ var actions = Object.freeze({
var typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) {
return typeof obj;
} : function (obj) {
return obj && typeof Symbol === "function" && obj.constructor === Symbol ? "symbol" : typeof obj;
return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj;
};

var asyncGenerator = function () {
function AwaitValue(value) {
this.value = value;
}

function AsyncGenerator(gen) {
var front, back;

function send(key, arg) {
return new Promise(function (resolve, reject) {
var request = {
key: key,
arg: arg,
resolve: resolve,
reject: reject,
next: null
};

if (back) {
back = back.next = request;
} else {
front = back = request;
resume(key, arg);
}
});
}

function resume(key, arg) {
try {
var result = gen[key](arg);
var value = result.value;

if (value instanceof AwaitValue) {
Promise.resolve(value.value).then(function (arg) {
resume("next", arg);
}, function (arg) {
resume("throw", arg);
});
} else {
settle(result.done ? "return" : "normal", result.value);
}
} catch (err) {
settle("throw", err);
}
}

function settle(type, value) {
switch (type) {
case "return":
front.resolve({
value: value,
done: true
});
break;

case "throw":
front.reject(value);
break;

default:
front.resolve({
value: value,
done: false
});
break;
}

front = front.next;

if (front) {
resume(front.key, front.arg);
} else {
back = null;
}
}

this._invoke = send;

if (typeof gen.return !== "function") {
this.return = undefined;
}
}

if (typeof Symbol === "function" && Symbol.asyncIterator) {
AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
return this;
};
}

AsyncGenerator.prototype.next = function (arg) {
return this._invoke("next", arg);
};

AsyncGenerator.prototype.throw = function (arg) {
return this._invoke("throw", arg);
};

AsyncGenerator.prototype.return = function (arg) {
return this._invoke("return", arg);
};

return {
wrap: function (fn) {
return function () {
return new AsyncGenerator(fn.apply(this, arguments));
};
},
await: function (value) {
return new AwaitValue(value);
}
};
}();

var _extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
Expand All @@ -199,7 +312,7 @@ var actions = Object.freeze({
};

function router5Reducer() {
var state = arguments.length <= 0 || arguments[0] === undefined ? initialState : arguments[0];
var state = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : initialState;
var action = arguments[1];

switch (action.type) {
Expand Down Expand Up @@ -329,18 +442,17 @@ var actions = Object.freeze({
}

function routeNodeSelector(routeNode) {
var reducerKey = arguments.length <= 1 || arguments[1] === undefined ? 'router' : arguments[1];
var reducerKey = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 'router';

var routerStateSelector = function routerStateSelector(state) {
return state[reducerKey] || state.get && state.get(reducerKey);
};
var lastReturnedValue = void 0;

return function (state) {
var _routerStateSelector = routerStateSelector(state);

var route = _routerStateSelector.route;
var previousRoute = _routerStateSelector.previousRoute;
var _routerStateSelector = routerStateSelector(state),
route = _routerStateSelector.route,
previousRoute = _routerStateSelector.previousRoute;

var intersection = route ? transitionPath(route, previousRoute).intersection : '';

Expand Down
12 changes: 6 additions & 6 deletions modules/immutable/reducer.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import * as actionTypes from '../lib/actionTypes';
import { Record } from 'immutable';
import { Record, fromJS } from 'immutable';

// eslint-disable-next-line new-cap
const State = Record({
Expand All @@ -13,20 +13,20 @@ function router5Reducer(state = new State(), action) {
switch (action.type) {
case actionTypes.TRANSITION_START:
return state
.set('transitionRoute', action.payload.route)
.set('transitionRoute', fromJS(action.payload.route))
.set('transitionError', null);

case actionTypes.TRANSITION_SUCCESS:
return state
.set('transitionRoute', null)
.set('transitionError', null)
.set('previousRoute', action.payload.previousRoute)
.set('route', action.payload.route);
.set('previousRoute', fromJS(action.payload.previousRoute))
.set('route', fromJS(action.payload.route));

case actionTypes.TRANSITION_ERROR:
return state
.set('transitionRoute', action.payload.route)
.set('transitionError', action.payload.transitionError);
.set('transitionRoute', fromJS(action.payload.route))
.set('transitionError', fromJS(action.payload.transitionError));

case actionTypes.CLEAR_ERRORS:
return state
Expand Down
1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@
},
"homepage": "http://router5.github.com/router5/redux-router5",
"devDependencies": {
"babel-cli": "^6.24.1",
"babel-core": "~6.9.1",
"babel-eslint": "~6.0.4",
"babel-plugin-transform-export-extensions": "~6.8.0",
Expand Down

0 comments on commit dcddef2

Please sign in to comment.