redux-timeout
Version:
Client side session timeout monitoring for redux
129 lines (108 loc) • 3.84 kB
JavaScript
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; };
var ADD_TIMEOUT = '@@reduxTimeout/ADD_TIMEOUT';
var REMOVE_TIMEOUT = '@@reduxTimeout/REMOVE_TIMEOUT';
var WATCH_ALL = '@@reduxTimeout/WATCH_ALL';
var addTimeout = function addTimeout(timeout, action, toCall) {
return {
type: ADD_TIMEOUT,
payload: {
timeout: timeout,
action: action,
toCall: toCall
}
};
};
var removeTimeout = function removeTimeout(action) {
return {
type: REMOVE_TIMEOUT,
payload: {
action: action
}
};
};
/**
* dispatches an action if an action has not been dispatched within the specified threshold
* @param {Number} threshold The time in ms to allow before dispatching an action
* @param {String | [String]} action The action, or array of actions, to monitor
* @param {Function} toCall An action creator, lib agnostic (redux-thunk, redux-promise etc.)
*/
var reduxTimeout = function reduxTimeout() {
var watch = {};
return function (store) {
return function (next) {
return function (action) {
var update = function update(action) {
// check if object is being monitored at the moment
var monitor = watch[action];
if (monitor) {
clearTimeout(monitor.timeoutId);
monitor.timeoutId = setTimeout(monitor.toCall, monitor.timeout);
}
};
var add = function add(_ref) {
var timeout = _ref.timeout;
var action = _ref.action;
var toCall = _ref.toCall;
if (typeof timeout !== 'number') {
return new Error('Expected timeout to be a number');
}
if (typeof action !== 'string' && !(action instanceof Array)) {
return new Error('Expected action to be a string or an array');
}
if ((typeof toCall === 'undefined' ? 'undefined' : _typeof(toCall)) !== 'object' && typeof toCall !== 'function') {
return new Error('Expected toCall to be an object or a function that would return an object');
}
// ensures all objects are watching the same object
var monitor = {
timeout: timeout,
toCall: toCall
};
monitor.timeoutId = setTimeout(monitor.toCall, monitor.timeout);
var addAction = function addAction(action) {
if (typeof action !== 'string') {
return new Error('Expected action to be a string');
}
watch[action] = monitor;
};
if (action instanceof Array) {
action.forEach(function (a) {
addAction(a);
});
} else {
addAction(action);
}
};
var remove = function remove(action) {
var monitor = watch[action];
if (monitor) {
clearTimeout(monitor.timeoutId);
delete watch[action];
}
};
if (action.type === REMOVE_TIMEOUT && action.payload.action) {
if (action.payload.action instanceof Array) {
action.payload.action.forEach(function (a) {
remove(a);
});
} else {
remove(action.payload.action);
}
}
if (action.type === ADD_TIMEOUT && action.payload.action) {
var payload = action.payload;
add(action.payload);
}
update(action.type);
update(WATCH_ALL);
return next(action);
};
};
};
};
module.exports = {
reduxTimeout: reduxTimeout,
addTimeout: addTimeout,
removeTimeout: removeTimeout,
WATCH_ALL: WATCH_ALL
};
;