reducerless-redux
Version:
redux without reducers
135 lines (121 loc) • 4.39 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", {
value: true
});
var _PromiseState = require('./PromiseState');
var _PromiseState2 = _interopRequireDefault(_PromiseState);
var _common = require('./common');
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
var defaultSetKey = function defaultSetKey(state, key, value) {
return Object.assign({}, state, _defineProperty({}, key, value));
};
var repeating = {};
var retry = function retry(action, props) {
// retry algorithm credit: alalonde/retry-promise
var max = action.maxRetry || 1;
var backoff = action.retryBackoff || 1000;
return new Promise(function (resolve, reject) {
var attempt = function attempt(i) {
var opts = {
method: action.method || 'GET',
body: action.body
};
var finalOpts = props.getOpts ? props.getOpts(opts) : opts;
fetch(action.url, finalOpts).then(function (res) {
if (res.ok) {
return action.handleResponse ? action.handleResponse(res) : res.json();
} else {
var error = new Error(res.statusText);
error.response = res;
throw error;
}
}).then(resolve).catch(function (err) {
if (i >= max) {
reject(err);
}
setTimeout(function () {
return attempt(i + 1);
}, i * backoff);
});
};
attempt(1);
});
};
var isGet = function isGet(a) {
return !a.method || a.method.toUpperCase() === 'GET';
};
var middleware = function middleware() {
var props = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
return function (store) {
return function (next) {
return function (action) {
if (!store._refreshing) store._refreshing = {};
if (!store._pending) store._pending = {};
if (action.type && action.type !== _common.type) {
next(action);
return;
}
if (action.clearRefresh) {
store._refreshing = {};
return;
}
if (action.update && typeof action.update === 'function') {
next({
type: _common.type,
update: action.update
});
return;
}
var makeAction = function makeAction(key, value) {
return {
type: _common.type,
key: key,
value: value,
setKey: props.setKey || defaultSetKey
};
};
if (store._refreshing[action.url] && !action._refreshing) {
return Promise.resolve({ refreshing: true });
}
if (isGet(action) && store._pending[action.url]) {
return Promise.resolve({ pending: true });
}
if (action.refreshInterval) {
store._refreshing[action.url] = true;
}
return new Promise(function (resolve, reject) {
next(makeAction(action.key, _PromiseState2.default.create()));
if (isGet(action)) {
store._pending[action.url] = true;
}
retry(action, props).then(function (json) {
var result = action.transform ? action.transform(json) : json;
var ps = _PromiseState2.default.resolve(result);
next(makeAction(action.key, ps));
if (action.onFulfilled) {
action.onFulfilled(ps, store.dispatch);
}
delete store._pending[action.url];
resolve(ps);
if (action.refreshInterval && store._refreshing[action.url]) {
var newAction = Object.assign({}, action, { _refreshing: true });
setTimeout(function () {
if (store._refreshing[action.url]) {
store.dispatch(newAction);
}
}, action.refreshInterval);
}
}).catch(function (err) {
delete store._refreshing[action.url];
delete store._pending[action.url];
var ps = _PromiseState2.default.reject(err);
next(makeAction(action.key, ps));
reject(ps);
});
});
};
};
};
};
exports.default = middleware;