UNPKG

react-query

Version:

Hooks for managing, caching and syncing asynchronous and remote data in React

253 lines (214 loc) 7.29 kB
"use strict"; exports.__esModule = true; exports.Mutation = void 0; exports.getDefaultState = getDefaultState; var _logger = require("./logger"); var _notifyManager = require("./notifyManager"); var _removable = require("./removable"); var _retryer = require("./retryer"); // CLASS class Mutation extends _removable.Removable { constructor(config) { super(); this.options = { ...config.defaultOptions, ...config.options }; this.mutationId = config.mutationId; this.mutationCache = config.mutationCache; this.logger = config.logger || _logger.defaultLogger; this.observers = []; this.state = config.state || getDefaultState(); this.meta = config.meta; this.updateCacheTime(this.options.cacheTime); this.scheduleGc(); } setState(state) { this.dispatch({ type: 'setState', state }); } addObserver(observer) { if (this.observers.indexOf(observer) === -1) { this.observers.push(observer); // Stop the mutation from being garbage collected this.clearGcTimeout(); this.mutationCache.notify({ type: 'observerAdded', mutation: this, observer }); } } removeObserver(observer) { this.observers = this.observers.filter(x => x !== observer); this.scheduleGc(); this.mutationCache.notify({ type: 'observerRemoved', mutation: this, observer }); } optionalRemove() { if (!this.observers.length) { if (this.state.status === 'loading') { this.scheduleGc(); } else { this.mutationCache.remove(this); } } } continue() { if (this.retryer) { this.retryer.continue(); return this.retryer.promise; } return this.execute(); } async execute() { const executeMutation = () => { var _this$options$retry; this.retryer = (0, _retryer.createRetryer)({ fn: () => { if (!this.options.mutationFn) { return Promise.reject('No mutationFn found'); } return this.options.mutationFn(this.state.variables); }, onFail: () => { this.dispatch({ type: 'failed' }); }, onPause: () => { this.dispatch({ type: 'pause' }); }, onContinue: () => { this.dispatch({ type: 'continue' }); }, retry: (_this$options$retry = this.options.retry) != null ? _this$options$retry : 0, retryDelay: this.options.retryDelay, networkMode: this.options.networkMode }); return this.retryer.promise; }; const restored = this.state.status === 'loading'; try { var _this$mutationCache$c3, _this$mutationCache$c4, _this$options$onSucce, _this$options2, _this$options$onSettl, _this$options3; if (!restored) { var _this$mutationCache$c, _this$mutationCache$c2, _this$options$onMutat, _this$options; this.dispatch({ type: 'loading', variables: this.options.variables }); // Notify cache callback (_this$mutationCache$c = (_this$mutationCache$c2 = this.mutationCache.config).onMutate) == null ? void 0 : _this$mutationCache$c.call(_this$mutationCache$c2, this.state.variables, this); const context = await ((_this$options$onMutat = (_this$options = this.options).onMutate) == null ? void 0 : _this$options$onMutat.call(_this$options, this.state.variables)); if (context !== this.state.context) { this.dispatch({ type: 'loading', context, variables: this.state.variables }); } } const data = await executeMutation(); // Notify cache callback (_this$mutationCache$c3 = (_this$mutationCache$c4 = this.mutationCache.config).onSuccess) == null ? void 0 : _this$mutationCache$c3.call(_this$mutationCache$c4, data, this.state.variables, this.state.context, this); await ((_this$options$onSucce = (_this$options2 = this.options).onSuccess) == null ? void 0 : _this$options$onSucce.call(_this$options2, data, this.state.variables, this.state.context)); await ((_this$options$onSettl = (_this$options3 = this.options).onSettled) == null ? void 0 : _this$options$onSettl.call(_this$options3, data, null, this.state.variables, this.state.context)); this.dispatch({ type: 'success', data }); return data; } catch (error) { try { var _this$mutationCache$c5, _this$mutationCache$c6, _this$options$onError, _this$options4, _this$options$onSettl2, _this$options5; // Notify cache callback (_this$mutationCache$c5 = (_this$mutationCache$c6 = this.mutationCache.config).onError) == null ? void 0 : _this$mutationCache$c5.call(_this$mutationCache$c6, error, this.state.variables, this.state.context, this); if (process.env.NODE_ENV !== 'production') { this.logger.error(error); } await ((_this$options$onError = (_this$options4 = this.options).onError) == null ? void 0 : _this$options$onError.call(_this$options4, error, this.state.variables, this.state.context)); await ((_this$options$onSettl2 = (_this$options5 = this.options).onSettled) == null ? void 0 : _this$options$onSettl2.call(_this$options5, undefined, error, this.state.variables, this.state.context)); throw error; } finally { this.dispatch({ type: 'error', error: error }); } } } dispatch(action) { const reducer = state => { switch (action.type) { case 'failed': return { ...state, failureCount: state.failureCount + 1 }; case 'pause': return { ...state, isPaused: true }; case 'continue': return { ...state, isPaused: false }; case 'loading': return { ...state, context: action.context, data: undefined, error: null, isPaused: !(0, _retryer.canFetch)(this.options.networkMode), status: 'loading', variables: action.variables }; case 'success': return { ...state, data: action.data, error: null, status: 'success', isPaused: false }; case 'error': return { ...state, data: undefined, error: action.error, failureCount: state.failureCount + 1, isPaused: false, status: 'error' }; case 'setState': return { ...state, ...action.state }; } }; this.state = reducer(this.state); _notifyManager.notifyManager.batch(() => { this.observers.forEach(observer => { observer.onMutationUpdate(action); }); this.mutationCache.notify({ mutation: this, type: 'updated', action }); }); } } exports.Mutation = Mutation; function getDefaultState() { return { context: undefined, data: undefined, error: null, failureCount: 0, isPaused: false, status: 'idle', variables: undefined }; }