react-query
Version:
Hooks for managing, caching and syncing asynchronous and remote data in React
228 lines (196 loc) • 6.09 kB
JavaScript
import _extends from "@babel/runtime/helpers/esm/extends";
import { getLogger } from './logger';
import { notifyManager } from './notifyManager';
import { Retryer } from './retryer';
import { noop } from './utils'; // TYPES
// CLASS
export var Mutation = /*#__PURE__*/function () {
function Mutation(config) {
this.options = _extends({}, config.defaultOptions, config.options);
this.mutationId = config.mutationId;
this.mutationCache = config.mutationCache;
this.observers = [];
this.state = config.state || getDefaultState();
}
var _proto = Mutation.prototype;
_proto.setState = function setState(state) {
this.dispatch({
type: 'setState',
state: state
});
};
_proto.addObserver = function addObserver(observer) {
if (this.observers.indexOf(observer) === -1) {
this.observers.push(observer);
}
};
_proto.removeObserver = function removeObserver(observer) {
this.observers = this.observers.filter(function (x) {
return x !== observer;
});
};
_proto.cancel = function cancel() {
if (this.retryer) {
this.retryer.cancel();
return this.retryer.promise.then(noop).catch(noop);
}
return Promise.resolve();
};
_proto.continue = function _continue() {
if (this.retryer) {
this.retryer.continue();
return this.retryer.promise;
}
return this.execute();
};
_proto.execute = function execute() {
var _this = this;
var data;
var restored = this.state.status === 'loading';
var promise = Promise.resolve();
if (!restored) {
this.dispatch({
type: 'loading',
variables: this.options.variables
});
promise = promise.then(function () {
return _this.options.onMutate == null ? void 0 : _this.options.onMutate(_this.state.variables);
}).then(function (context) {
if (context !== _this.state.context) {
_this.dispatch({
type: 'loading',
context: context,
variables: _this.state.variables
});
}
});
}
return promise.then(function () {
return _this.executeMutation();
}).then(function (result) {
data = result; // Notify cache callback
_this.mutationCache.config.onSuccess == null ? void 0 : _this.mutationCache.config.onSuccess(data, _this.state.variables, _this.state.context, _this);
}).then(function () {
return _this.options.onSuccess == null ? void 0 : _this.options.onSuccess(data, _this.state.variables, _this.state.context);
}).then(function () {
return _this.options.onSettled == null ? void 0 : _this.options.onSettled(data, null, _this.state.variables, _this.state.context);
}).then(function () {
_this.dispatch({
type: 'success',
data: data
});
return data;
}).catch(function (error) {
// Notify cache callback
_this.mutationCache.config.onError == null ? void 0 : _this.mutationCache.config.onError(error, _this.state.variables, _this.state.context, _this); // Log error
getLogger().error(error);
return Promise.resolve().then(function () {
return _this.options.onError == null ? void 0 : _this.options.onError(error, _this.state.variables, _this.state.context);
}).then(function () {
return _this.options.onSettled == null ? void 0 : _this.options.onSettled(undefined, error, _this.state.variables, _this.state.context);
}).then(function () {
_this.dispatch({
type: 'error',
error: error
});
throw error;
});
});
};
_proto.executeMutation = function executeMutation() {
var _this2 = this,
_this$options$retry;
this.retryer = new Retryer({
fn: function fn() {
if (!_this2.options.mutationFn) {
return Promise.reject('No mutationFn found');
}
return _this2.options.mutationFn(_this2.state.variables);
},
onFail: function onFail() {
_this2.dispatch({
type: 'failed'
});
},
onPause: function onPause() {
_this2.dispatch({
type: 'pause'
});
},
onContinue: function onContinue() {
_this2.dispatch({
type: 'continue'
});
},
retry: (_this$options$retry = this.options.retry) != null ? _this$options$retry : 0,
retryDelay: this.options.retryDelay
});
return this.retryer.promise;
};
_proto.dispatch = function dispatch(action) {
var _this3 = this;
this.state = reducer(this.state, action);
notifyManager.batch(function () {
_this3.observers.forEach(function (observer) {
observer.onMutationUpdate(action);
});
_this3.mutationCache.notify(_this3);
});
};
return Mutation;
}();
export function getDefaultState() {
return {
context: undefined,
data: undefined,
error: null,
failureCount: 0,
isPaused: false,
status: 'idle',
variables: undefined
};
}
function reducer(state, action) {
switch (action.type) {
case 'failed':
return _extends({}, state, {
failureCount: state.failureCount + 1
});
case 'pause':
return _extends({}, state, {
isPaused: true
});
case 'continue':
return _extends({}, state, {
isPaused: false
});
case 'loading':
return _extends({}, state, {
context: action.context,
data: undefined,
error: null,
isPaused: false,
status: 'loading',
variables: action.variables
});
case 'success':
return _extends({}, state, {
data: action.data,
error: null,
status: 'success',
isPaused: false
});
case 'error':
return _extends({}, state, {
data: undefined,
error: action.error,
failureCount: state.failureCount + 1,
isPaused: false,
status: 'error'
});
case 'setState':
return _extends({}, state, action.state);
default:
return state;
}
}