react-query
Version:
Hooks for managing, caching and syncing asynchronous and remote data in React
112 lines (92 loc) • 3.75 kB
JavaScript
import { getDefaultState } from './mutation';
import { notifyManager } from './notifyManager';
import { Subscribable } from './subscribable';
// CLASS
export class MutationObserver extends Subscribable {
constructor(client, options) {
super();
this.client = client;
this.setOptions(options);
this.bindMethods();
this.updateResult();
}
bindMethods() {
this.mutate = this.mutate.bind(this);
this.reset = this.reset.bind(this);
}
setOptions(options) {
this.options = this.client.defaultMutationOptions(options);
}
onUnsubscribe() {
if (!this.listeners.length) {
var _this$currentMutation;
(_this$currentMutation = this.currentMutation) == null ? void 0 : _this$currentMutation.removeObserver(this);
}
}
onMutationUpdate(action) {
this.updateResult(); // Determine which callbacks to trigger
const notifyOptions = {
listeners: true
};
if (action.type === 'success') {
notifyOptions.onSuccess = true;
} else if (action.type === 'error') {
notifyOptions.onError = true;
}
this.notify(notifyOptions);
}
getCurrentResult() {
return this.currentResult;
}
reset() {
this.currentMutation = undefined;
this.updateResult();
this.notify({
listeners: true
});
}
mutate(variables, options) {
this.mutateOptions = options;
if (this.currentMutation) {
this.currentMutation.removeObserver(this);
}
this.currentMutation = this.client.getMutationCache().build(this.client, { ...this.options,
variables: typeof variables !== 'undefined' ? variables : this.options.variables
});
this.currentMutation.addObserver(this);
return this.currentMutation.execute();
}
updateResult() {
const state = this.currentMutation ? this.currentMutation.state : getDefaultState();
const result = { ...state,
isLoading: state.status === 'loading',
isSuccess: state.status === 'success',
isError: state.status === 'error',
isIdle: state.status === 'idle',
mutate: this.mutate,
reset: this.reset
};
this.currentResult = result;
}
notify(options) {
notifyManager.batch(() => {
// First trigger the mutate callbacks
if (this.mutateOptions) {
if (options.onSuccess) {
var _this$mutateOptions$o, _this$mutateOptions, _this$mutateOptions$o2, _this$mutateOptions2;
(_this$mutateOptions$o = (_this$mutateOptions = this.mutateOptions).onSuccess) == null ? void 0 : _this$mutateOptions$o.call(_this$mutateOptions, this.currentResult.data, this.currentResult.variables, this.currentResult.context);
(_this$mutateOptions$o2 = (_this$mutateOptions2 = this.mutateOptions).onSettled) == null ? void 0 : _this$mutateOptions$o2.call(_this$mutateOptions2, this.currentResult.data, null, this.currentResult.variables, this.currentResult.context);
} else if (options.onError) {
var _this$mutateOptions$o3, _this$mutateOptions3, _this$mutateOptions$o4, _this$mutateOptions4;
(_this$mutateOptions$o3 = (_this$mutateOptions3 = this.mutateOptions).onError) == null ? void 0 : _this$mutateOptions$o3.call(_this$mutateOptions3, this.currentResult.error, this.currentResult.variables, this.currentResult.context);
(_this$mutateOptions$o4 = (_this$mutateOptions4 = this.mutateOptions).onSettled) == null ? void 0 : _this$mutateOptions$o4.call(_this$mutateOptions4, undefined, this.currentResult.error, this.currentResult.variables, this.currentResult.context);
}
} // Then trigger the listeners
if (options.listeners) {
this.listeners.forEach(listener => {
listener(this.currentResult);
});
}
});
}
}