react-query
Version:
Hooks for managing, caching and syncing asynchronous and remote data in React
1,358 lines (1,148 loc) • 40.4 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('react')) :
typeof define === 'function' && define.amd ? define(['exports', 'react'], factory) :
(global = global || self, factory(global.ReactQuery = {}, global.React));
}(this, (function (exports, React) { 'use strict';
React = React && React.hasOwnProperty('default') ? React['default'] : React;
function _extends() {
_extends = Object.assign || function (target) {
for (var i = 1; i < arguments.length; i++) {
var source = arguments[i];
for (var key in source) {
if (Object.prototype.hasOwnProperty.call(source, key)) {
target[key] = source[key];
}
}
}
return target;
};
return _extends.apply(this, arguments);
}
function _objectWithoutPropertiesLoose(source, excluded) {
if (source == null) return {};
var target = {};
var sourceKeys = Object.keys(source);
var key, i;
for (i = 0; i < sourceKeys.length; i++) {
key = sourceKeys[i];
if (excluded.indexOf(key) >= 0) continue;
target[key] = source[key];
}
return target;
}
var statusIdle = 'idle';
var statusLoading = 'loading';
var statusError = 'error';
var statusSuccess = 'success';
var _uid = 0;
var uid = function uid() {
return _uid++;
};
var cancelledError = {};
var isServer = typeof window === 'undefined';
var noop = function noop() {};
var identity = function identity(d) {
return d;
};
var Console = console || {
error: noop,
warn: noop,
log: noop
};
function useUid() {
var ref = React.useRef(null);
if (ref.current === null) {
ref.current = uid();
}
return ref.current;
}
function setConsole(c) {
Console = c;
}
function useGetLatest(obj) {
var ref = React.useRef();
ref.current = obj;
return React.useCallback(function () {
return ref.current;
}, []);
}
function functionalUpdate(updater, old) {
return typeof updater === 'function' ? updater(old) : updater;
}
function stableStringifyReplacer(_, value) {
return isObject(value) ? Object.assign.apply(Object, [{}].concat(Object.keys(value).sort().map(function (key) {
var _ref;
return _ref = {}, _ref[key] = value[key], _ref;
}))) : value;
}
function stableStringify(obj) {
return JSON.stringify(obj, stableStringifyReplacer);
}
function isObject(a) {
return a && typeof a === 'object' && !Array.isArray(a);
}
function deepIncludes(a, b) {
if (typeof a !== typeof b) {
return false;
}
if (typeof a === 'object') {
return !Object.keys(b).some(function (key) {
return !deepIncludes(a[key], b[key]);
});
}
return a === b;
}
function isDocumentVisible() {
return typeof document === 'undefined' || document.visibilityState === undefined || document.visibilityState === 'visible' || document.visibilityState === 'prerender';
}
function isOnline() {
return navigator.onLine === undefined || navigator.onLine;
}
function getQueryArgs(args) {
if (isObject(args[0])) {
if (args[0].hasOwnProperty('queryKey') && args[0].hasOwnProperty('queryFn')) {
var _args$ = args[0],
_queryKey = _args$.queryKey,
_args$$variables = _args$.variables,
variables = _args$$variables === void 0 ? [] : _args$$variables,
_queryFn = _args$.queryFn,
_args$$config = _args$.config,
_config = _args$$config === void 0 ? {} : _args$$config;
return [_queryKey, variables, _queryFn, _config];
} else {
throw new Error('queryKey and queryFn keys are required.');
}
}
if (typeof args[2] === 'function') {
var _queryKey2 = args[0],
_args$2 = args[1],
_variables = _args$2 === void 0 ? [] : _args$2,
_queryFn2 = args[2],
_args$3 = args[3],
_config2 = _args$3 === void 0 ? {} : _args$3;
return [_queryKey2, _variables, _queryFn2, _config2];
}
var queryKey = args[0],
queryFn = args[1],
_args$4 = args[2],
config = _args$4 === void 0 ? {} : _args$4;
return [queryKey, [], queryFn, config];
}
function useMountedCallback(callback) {
var mounted = React.useRef(false);
React[isServer ? 'useEffect' : 'useLayoutEffect'](function () {
mounted.current = true;
return function () {
return mounted.current = false;
};
}, []);
return React.useCallback(function () {
return mounted.current ? callback.apply(void 0, arguments) : void 0;
}, [callback]);
}
var configContext = React.createContext();
var defaultConfigRef = {
current: {
retry: 3,
retryDelay: function retryDelay(attemptIndex) {
return Math.min(1000 * Math.pow(2, attemptIndex), 30000);
},
staleTime: 0,
cacheTime: 5 * 60 * 1000,
refetchAllOnWindowFocus: true,
refetchInterval: false,
suspense: false,
queryKeySerializerFn: defaultQueryKeySerializerFn,
queryFnParamsFilter: identity,
throwOnError: false,
useErrorBoundary: undefined,
// this will default to the suspense value
onSuccess: noop,
onError: noop,
onSettled: noop,
refetchOnMount: true
}
};
function useConfigContext() {
return React.useContext(configContext) || defaultConfigRef.current;
}
function ReactQueryConfigProvider(_ref) {
var config = _ref.config,
children = _ref.children;
var configContextValue = React.useContext(configContext);
var newConfig = React.useMemo(function () {
var newConfig = _extends({}, configContextValue || defaultConfigRef.current, {}, config); // Default useErrorBoundary to the suspense value
if (typeof newConfig.useErrorBoundary === 'undefined') {
newConfig.useErrorBoundary = newConfig.suspense;
}
return newConfig;
}, [config, configContextValue]);
if (!configContextValue) {
defaultConfigRef.current = newConfig;
}
return React.createElement(configContext.Provider, {
value: newConfig
}, children);
}
function defaultQueryKeySerializerFn(queryKey) {
if (!queryKey) {
return [];
}
if (typeof queryKey === 'function') {
try {
return defaultQueryKeySerializerFn(queryKey());
} catch (_unused) {
return [];
}
}
if (typeof queryKey === 'string') {
queryKey = [queryKey];
}
var queryHash = stableStringify(queryKey);
queryKey = JSON.parse(queryHash);
return [queryHash, queryKey];
}
function _await(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _catch(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
function _async(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
function _invoke(body, then) {
var result = body();
if (result && result.then) {
return result.then(then);
}
return then(result);
}
var queryCache = makeQueryCache();
var actionInit = {};
var actionFailed = {};
var actionMarkStale = {};
var actionFetch = {};
var actionSuccess = {};
var actionError = {};
function makeQueryCache() {
var listeners = [];
var cache = {
queries: {},
isFetching: 0
};
var notifyGlobalListeners = function notifyGlobalListeners() {
cache.isFetching = Object.values(queryCache.queries).reduce(function (acc, query) {
return query.state.isFetching ? acc + 1 : acc;
}, 0);
listeners.forEach(function (d) {
return d(cache);
});
};
cache.subscribe = function (cb) {
listeners.push(cb);
return function () {
listeners.splice(listeners.indexOf(cb), 1);
};
};
cache.clear = function () {
cache.queries = {};
notifyGlobalListeners();
};
var findQueries = function findQueries(predicate, _temp) {
var _ref = _temp === void 0 ? {} : _temp,
exact = _ref.exact;
if (typeof predicate !== 'function') {
var _defaultConfigRef$cur = defaultConfigRef.current.queryKeySerializerFn(predicate),
queryHash = _defaultConfigRef$cur[0],
queryKey = _defaultConfigRef$cur[1];
predicate = function predicate(d) {
return exact ? d.queryHash === queryHash : deepIncludes(d.queryKey, queryKey);
};
}
return Object.values(cache.queries).filter(predicate);
};
cache.getQueries = findQueries;
cache.getQuery = function (queryKey) {
return findQueries(queryKey, {
exact: true
})[0];
};
cache.getQueryData = function (queryKey) {
var _cache$getQuery;
return (_cache$getQuery = cache.getQuery(queryKey)) == null ? void 0 : _cache$getQuery.state.data;
};
cache.removeQueries = function (predicate, _temp2) {
var _ref2 = _temp2 === void 0 ? {} : _temp2,
exact = _ref2.exact;
var foundQueries = findQueries(predicate, {
exact: exact
});
foundQueries.forEach(function (query) {
clearTimeout(query.staleTimeout);
delete cache.queries[query.queryHash];
});
if (foundQueries.length) {
notifyGlobalListeners();
}
};
cache.refetchQueries = _async(function (predicate, _temp3) {
var _ref3 = _temp3 === void 0 ? {} : _temp3,
exact = _ref3.exact,
throwOnError = _ref3.throwOnError,
force = _ref3.force;
var foundQueries = predicate === true ? Object.values(cache.queries) : findQueries(predicate, {
exact: exact
});
return _catch(function () {
return _await(Promise.all(foundQueries.map(function (query) {
return query.fetch({
force: force
});
})));
}, function (err) {
if (throwOnError) {
throw err;
}
});
});
cache._buildQuery = function (userQueryKey, queryVariables, queryFn, config) {
var _config$queryKeySeria = config.queryKeySerializerFn(userQueryKey),
queryHash = _config$queryKeySeria[0],
queryKey = _config$queryKeySeria[1];
var query = cache.queries[queryHash];
if (query) {
Object.assign(query, {
queryVariables: queryVariables,
queryFn: queryFn
});
Object.assign(query.config, config);
} else {
query = makeQuery({
queryKey: queryKey,
queryHash: queryHash,
queryVariables: queryVariables,
queryFn: queryFn,
config: config
}); // If the query started with data, schedule
// a stale timeout
if (query.state.data) {
query.scheduleStaleTimeout(); // Simulate a query healing process
query.heal(); // Schedule for garbage collection in case
// nothing subscribes to this query
query.scheduleGarbageCollection();
}
if (query.queryHash) {
if (!isServer) {
cache.queries[queryHash] = query;
notifyGlobalListeners();
}
}
}
return query;
};
cache.prefetchQuery = _async(function () {
var _exit = false;
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var _getQueryArgs = getQueryArgs(args),
queryKey = _getQueryArgs[0],
queryVariables = _getQueryArgs[1],
queryFn = _getQueryArgs[2],
_getQueryArgs$ = _getQueryArgs[3],
force = _getQueryArgs$.force,
config = _objectWithoutPropertiesLoose(_getQueryArgs$, ["force"]);
config = _extends({}, defaultConfigRef.current, {}, config);
var query = cache._buildQuery(queryKey, queryVariables, queryFn, config); // Don't prefetch queries that are fresh, unless force is passed
return _invoke(function () {
if (query.state.isStale || force) {
// Trigger a fetch and return the promise
return _catch(function () {
return _await(query.fetch(), function (res) {
query.wasPrefetched = true;
_exit = true;
return res;
});
}, function (err) {
if (config.throwOnError) {
throw err;
}
});
}
}, function (_result3) {
return _exit ? _result3 : query.state.data;
});
});
cache.setQueryData = function (queryKey, updater, _ref4) {
if (_ref4 === void 0) {
_ref4 = {};
}
var _ref5 = _ref4,
exact = _ref5.exact,
config = _objectWithoutPropertiesLoose(_ref5, ["exact"]);
var queries = findQueries(queryKey, {
exact: exact
});
if (!queries.length && typeof queryKey !== 'function') {
queries = [cache._buildQuery(queryKey, undefined, function () {
return new Promise(noop);
}, _extends({}, defaultConfigRef.current, {}, config))];
}
queries.forEach(function (d) {
return d.setData(updater);
});
};
function makeQuery(options) {
var reducer = options.config.queryReducer || defaultQueryReducer;
var noQueryHash = typeof options.queryHash === 'undefined';
var initialData = typeof options.config.initialData === 'function' ? options.config.initialData() : options.config.initialData;
var hasInitialData = typeof initialData !== 'undefined';
var isStale = noQueryHash ? true : !hasInitialData;
var manual = options.config.manual;
var initialStatus = noQueryHash || manual || hasInitialData ? statusSuccess : statusLoading;
var query = _extends({}, options, {
instances: [],
state: reducer(undefined, {
type: actionInit,
initialStatus: initialStatus,
initialData: initialData,
hasInitialData: hasInitialData,
isStale: isStale,
manual: manual
})
});
var dispatch = function dispatch(action) {
query.state = reducer(query.state, action);
query.instances.forEach(function (d) {
return d.onStateUpdate(query.state);
});
notifyGlobalListeners();
};
query.scheduleStaleTimeout = function () {
if (query.config.staleTime === Infinity) {
return;
}
query.staleTimeout = setTimeout(function () {
dispatch({
type: actionMarkStale
});
}, query.config.staleTime);
};
query.scheduleGarbageCollection = function () {
query.cacheTimeout = setTimeout(function () {
cache.removeQueries(function (d) {
return d.queryHash === query.queryHash;
});
}, typeof query.state.data === 'undefined' && query.state.status !== 'error' ? 0 : query.config.cacheTime);
};
query.heal = function () {
// Stop the query from being garbage collected
clearTimeout(query.cacheTimeout); // Mark the query as not cancelled
query.cancelled = null;
};
query.subscribe = function (instance) {
var found = query.instances.find(function (d) {
return d.id === instance.id;
});
if (found) {
Object.assign(found, instance);
} else {
found = _extends({
onStateUpdate: noop
}, instance);
query.instances.push(instance);
}
query.heal(); // Return the unsubscribe function
return function () {
query.instances = query.instances.filter(function (d) {
return d.id !== instance.id;
});
if (!query.instances.length) {
// Cancel any side-effects
query.cancelled = cancelledError;
if (query.cancelQueries) {
query.cancelQueries();
} // Schedule garbage collection
query.scheduleGarbageCollection();
}
};
}; // Set up the fetch function
var tryFetchData = _async(function (queryFn) {
for (var _len2 = arguments.length, args = new Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
args[_key2 - 1] = arguments[_key2];
}
return _catch(function () {
// Perform the query
var promise = queryFn.apply(void 0, query.config.queryFnParamsFilter(args));
query.cancelQueries = function () {
return promise.cancel == null ? void 0 : promise.cancel();
};
return _await(promise, function (data) {
delete query.cancelQueries;
if (query.cancelled) throw query.cancelled;
return data;
});
}, function (error) {
var _exit2 = false;
delete query.cancelQueries;
if (query.cancelled) throw query.cancelled; // If we fail, increase the failureCount
dispatch({
type: actionFailed
}); // Do we need to retry the request?
return _invoke(function () {
if ( // Only retry if the document is visible
query.config.retry === true || query.state.failureCount <= query.config.retry) {
if (!isDocumentVisible()) {
// set this flag to continue fetch retries on focus
query.shouldContinueRetryOnFocus = true;
_exit2 = true;
return new Promise(noop);
}
delete query.shouldContinueRetryOnFocus; // Determine the retryDelay
var delay = functionalUpdate(query.config.retryDelay, query.state.failureCount); // Return a new promise with the retry
_exit2 = true;
return _await(new Promise(function (resolve, reject) {
// Keep track of the retry timeout
setTimeout(_async(function () {
return query.cancelled ? reject(query.cancelled) : _catch(function () {
return _await(tryFetchData.apply(void 0, [queryFn].concat(args)), function (data) {
if (query.cancelled) return reject(query.cancelled);
resolve(data);
});
}, function (error) {
if (query.cancelled) return reject(query.cancelled);
reject(error);
});
}), delay);
}));
}
}, function (_result4) {
if (_exit2) return _result4;
throw error;
});
});
});
query.fetch = _async(function (_temp5) {
var _ref6 = _temp5 === void 0 ? {} : _temp5,
force = _ref6.force,
_ref6$__queryFn = _ref6.__queryFn,
__queryFn = _ref6$__queryFn === void 0 ? query.queryFn : _ref6$__queryFn;
// Don't refetch fresh queries that don't have a queryHash
if (!query.queryHash || !query.state.isStale && !force) {
return;
} // Create a new promise for the query cache if necessary
if (!query.promise) {
query.promise = _async(function () {
// If there are any retries pending for this query, kill them
query.cancelled = null;
return _catch(function () {
// Set up the query refreshing state
dispatch({
type: actionFetch
}); // Try to fetch
return _await(tryFetchData.apply(void 0, [__queryFn].concat(query.queryKey, query.queryVariables)), function (data) {
query.setData(data);
query.instances.forEach(function (instance) {
return instance.onSuccess && instance.onSuccess(query.state.data);
});
query.instances.forEach(function (instance) {
return instance.onSettled && instance.onSettled(query.state.data, null);
});
delete query.promise;
return data;
});
}, function (error) {
dispatch({
type: actionError,
cancelled: error === query.cancelled,
error: error
});
delete query.promise;
if (error !== query.cancelled) {
query.instances.forEach(function (instance) {
return instance.onError && instance.onError(error);
});
query.instances.forEach(function (instance) {
return instance.onSettled && instance.onSettled(undefined, error);
}); // throw error
}
});
})();
}
return query.promise;
});
query.setData = function (updater) {
// Set data and mark it as cached
dispatch({
type: actionSuccess,
updater: updater
}); // Schedule a fresh invalidation!
clearTimeout(query.staleTimeout);
query.scheduleStaleTimeout();
};
return query;
}
return cache;
}
function defaultQueryReducer(state, action) {
switch (action.type) {
case actionInit:
return {
status: action.initialStatus,
error: null,
isFetching: action.hasInitialData ? false : !action.manual,
canFetchMore: false,
failureCount: 0,
isStale: action.isStale,
data: action.initialData,
updatedAt: action.hasInitialData ? Date.now() : 0
};
case actionFailed:
return _extends({}, state, {
failureCount: state.failureCount + 1
});
case actionMarkStale:
return _extends({}, state, {
isStale: true
});
case actionFetch:
return _extends({}, state, {
status: state.status === statusError ? statusLoading : state.status,
isFetching: true,
failureCount: 0
});
case actionSuccess:
return _extends({}, state, {
status: statusSuccess,
data: functionalUpdate(action.updater, state.data),
error: null,
isStale: false,
isFetching: false,
canFetchMore: action.canFetchMore,
updatedAt: Date.now(),
failureCount: 0
});
case actionError:
return _extends({}, state, {
isFetching: false
}, !action.cancelled && {
status: statusError,
error: action.error,
isStale: true
});
default:
throw new Error();
}
}
var visibilityChangeEvent = 'visibilitychange';
var focusEvent = 'focus';
var onWindowFocus = function onWindowFocus() {
var refetchAllOnWindowFocus = defaultConfigRef.current.refetchAllOnWindowFocus;
if (isDocumentVisible() && isOnline()) {
queryCache.refetchQueries(function (query) {
if (!query.instances.length) {
return false;
}
if (query.shouldContinueRetryOnFocus) {
// delete promise, so `fetch` will create new one
delete query.promise;
return true;
}
if (typeof query.config.refetchOnWindowFocus === 'undefined') {
return refetchAllOnWindowFocus;
} else {
return query.config.refetchOnWindowFocus;
}
}).catch(Console.error);
}
};
var removePreviousHandler;
function setFocusHandler(callback) {
// Unsub the old watcher
if (removePreviousHandler) {
removePreviousHandler();
} // Sub the new watcher
removePreviousHandler = callback(onWindowFocus);
}
setFocusHandler(function (handleFocus) {
var _window;
// Listen to visibillitychange and focus
if (!isServer && ((_window = window) == null ? void 0 : _window.addEventListener)) {
window.addEventListener(visibilityChangeEvent, handleFocus, false);
window.addEventListener(focusEvent, handleFocus, false);
return function () {
// Be sure to unsubscribe if a new handler is set
window.removeEventListener(visibilityChangeEvent, handleFocus);
window.removeEventListener(focusEvent, handleFocus);
};
}
});
function useIsFetching() {
var _React$useState = React.useState({}),
state = _React$useState[0],
setState = _React$useState[1];
React.useEffect(function () {
return queryCache.subscribe(function () {
return setState({});
});
}, []);
return React.useMemo(function () {
return state && queryCache.isFetching;
}, [state]);
}
function _await$1(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
var getDefaultState = function getDefaultState() {
return {
status: statusIdle,
data: undefined,
error: null
};
};
function _catch$1(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
var actionReset = {};
function _async$1(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
var actionLoading = {};
var actionResolve = {};
var actionReject = {};
function mutationReducer(state, action) {
if (action.type === actionReset) {
return getDefaultState();
} else if (action.type === actionLoading) {
return {
status: statusLoading
};
} else if (state.status === statusLoading && action.type === actionResolve) {
return {
status: statusSuccess,
data: action.data
};
} else if (state.status === statusLoading && action.type === actionReject) {
return {
status: statusError,
error: action.error
};
} else {
throw new Error();
}
}
function useMutation(mutationFn, config) {
if (config === void 0) {
config = {};
}
var _React$useReducer = React.useReducer(mutationReducer, null, getDefaultState),
state = _React$useReducer[0],
unsafeDispatch = _React$useReducer[1];
var dispatch = useMountedCallback(unsafeDispatch);
var getMutationFn = useGetLatest(mutationFn);
var getConfig = useGetLatest(_extends({}, useConfigContext(), {}, config));
var latestMutationRef = React.useRef();
var mutate = React.useCallback(_async$1(function (variables, options) {
if (options === void 0) {
options = {};
}
var resolvedOptions = _extends({}, getConfig(), {}, options);
var mutationId = uid();
latestMutationRef.current = mutationId;
dispatch({
type: actionLoading
});
return _catch$1(function () {
return _await$1(getMutationFn()(variables), function (data) {
return _await$1(resolvedOptions.onSuccess(data), function () {
return _await$1(resolvedOptions.onSettled(data, null), function () {
if (latestMutationRef.current === mutationId) {
dispatch({
type: actionResolve,
data: data
});
}
return data;
});
});
});
}, function (error) {
Console.error(error);
return _await$1(resolvedOptions.onError(error), function () {
return _await$1(resolvedOptions.onSettled(undefined, error), function () {
if (latestMutationRef.current === mutationId) {
dispatch({
type: actionReject,
error: error
});
}
if (resolvedOptions.throwOnError) {
throw error;
}
});
});
});
}), [dispatch, getConfig, getMutationFn]);
var reset = React.useCallback(function () {
return dispatch({
type: actionReset
});
}, [dispatch]);
React.useEffect(function () {
if (getConfig().useErrorBoundary && state.error) {
throw state.error;
}
}, [getConfig, state.error]);
return [mutate, _extends({}, state, {
reset: reset
})];
}
function _await$2(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _catch$2(body, recover) {
try {
var result = body();
} catch (e) {
return recover(e);
}
if (result && result.then) {
return result.then(void 0, recover);
}
return result;
}
function _async$2(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
function useBaseQuery(queryKey, queryVariables, queryFn, config) {
if (config === void 0) {
config = {};
}
var instanceId = useUid();
config = _extends({}, useConfigContext(), {}, config);
var queryRef = React.useRef();
var newQuery = queryCache._buildQuery(queryKey, queryVariables, queryFn, config);
var useCachedQuery = queryRef.current && typeof queryRef.current.queryHash === 'undefined' && typeof newQuery.queryHash === 'undefined'; // Do not use new query with undefined queryHash, if previous query also had undefined queryHash.
// Otherwise this will cause infinite loop.
if (!useCachedQuery) {
queryRef.current = newQuery;
}
var query = queryRef.current;
var _React$useState = React.useState(),
unsafeRerender = _React$useState[1];
var rerender = useMountedCallback(unsafeRerender);
var getLatestConfig = useGetLatest(config);
var refetch = React.useCallback(_async$2(function (_ref) {
if (_ref === void 0) {
_ref = {};
}
var _ref2 = _ref,
throwOnError = _ref2.throwOnError,
rest = _objectWithoutPropertiesLoose(_ref2, ["throwOnError"]);
return _catch$2(function () {
return _await$2(query.fetch(rest));
}, function (err) {
if (throwOnError) {
throw err;
}
});
}), [query]); // Subscribe to the query and maybe trigger fetch
React.useEffect(function () {
var unsubscribeFromQuery = query.subscribe({
id: instanceId,
onStateUpdate: function onStateUpdate() {
return rerender({});
},
onSuccess: function onSuccess(data) {
return getLatestConfig().onSuccess(data);
},
onError: function onError(err) {
return getLatestConfig().onError(err);
},
onSettled: function onSettled(data, err) {
return getLatestConfig().onSettled(data, err);
}
}); // Perform the initial fetch for this query if necessary
if (!getLatestConfig().manual && // Don't auto fetch if config is set to manual query
!query.wasPrefetched && // Don't double fetch for prefetched queries
!query.wasSuspensed && // Don't double fetch for suspense
query.state.isStale && ( // Only refetch if stale
getLatestConfig().refetchOnMount || query.instances.length === 1)) {
refetch().catch(Console.error);
}
query.wasPrefetched = false;
query.wasSuspensed = false;
return unsubscribeFromQuery;
}, [getLatestConfig, instanceId, query, refetch, rerender]); // Handle refetch interval
React.useEffect(function () {
if (config.refetchInterval && (!query.refetchInterval || config.refetchInterval < query.refetchInterval)) {
clearInterval(query.refetchInterval);
query.refetchInterval = setInterval(function () {
if (isDocumentVisible() || config.refetchIntervalInBackground) {
refetch().catch(Console.error);
}
}, config.refetchInterval);
return function () {
clearInterval(query.refetchInterval);
delete query.refetchInterval;
};
}
}, [config.refetchInterval, config.refetchIntervalInBackground, query.refetchInterval, refetch]);
return _extends({}, query.state, {
config: config,
query: query,
refetch: refetch
});
}
function useQuery() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var query = useBaseQuery.apply(void 0, getQueryArgs(args));
if (query.config.suspense) {
if (query.status === statusError) {
throw query.error;
}
if (query.status === statusLoading) {
query.wasSuspensed = true;
throw query.refetch();
}
}
return query;
}
function usePaginatedQuery() {
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var _getQueryArgs = getQueryArgs(args),
queryKey = _getQueryArgs[0],
queryVariables = _getQueryArgs[1],
queryFn = _getQueryArgs[2],
_getQueryArgs$ = _getQueryArgs[3],
config = _getQueryArgs$ === void 0 ? {} : _getQueryArgs$;
var lastDataRef = React.useRef(); // If latestData is set, don't use initialData
if (typeof lastDataRef.current !== 'undefined') {
delete config.initialData;
}
var query = useBaseQuery(queryKey, queryVariables, queryFn, config);
var latestData = query.data,
status = query.status;
React.useEffect(function () {
if (status === 'success' && typeof latestData !== 'undefined') {
lastDataRef.current = latestData;
}
}, [latestData, status]);
var resolvedData = latestData;
if (typeof resolvedData === 'undefined') {
resolvedData = lastDataRef.current;
}
if (typeof resolvedData !== 'undefined') {
status = 'success';
}
if (query.config.suspense) {
if (query.status === statusError) {
throw query.error;
}
if (query.status === statusLoading) {
query.wasSuspensed = true;
throw query.refetch();
}
}
return _extends({}, query, {
resolvedData: resolvedData,
latestData: latestData,
status: status
});
}
function _await$3(value, then, direct) {
if (direct) {
return then ? then(value) : value;
}
if (!value || !value.then) {
value = Promise.resolve(value);
}
return then ? value.then(then) : value;
}
function _async$3(f) {
return function () {
for (var args = [], i = 0; i < arguments.length; i++) {
args[i] = arguments[i];
}
try {
return Promise.resolve(f.apply(this, args));
} catch (e) {
return Promise.reject(e);
}
};
}
function _rethrow(thrown, value) {
if (thrown) throw value;
return value;
}
function _finallyRethrows(body, finalizer) {
try {
var result = body();
} catch (e) {
return finalizer(true, e);
}
if (result && result.then) {
return result.then(finalizer.bind(null, false), finalizer.bind(null, true));
}
return finalizer(false, result);
}
function useInfiniteQuery() {
var queryInfoRef = React.useRef();
for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {
args[_key] = arguments[_key];
}
var _getQueryArgs = getQueryArgs(args),
queryKey = _getQueryArgs[0],
queryVariables = _getQueryArgs[1],
queryFn = _getQueryArgs[2],
_getQueryArgs$ = _getQueryArgs[3],
config = _getQueryArgs$ === void 0 ? {} : _getQueryArgs$;
var getFetchMore = config.getFetchMore;
var getGetFetchMore = useGetLatest(getFetchMore); // The default queryFn will query all pages and map them together
var originalQueryFn = queryFn;
queryFn = _async$3(function () {
return _await$3(Promise.all(queryInfoRef.current.query.pageVariables.map(function (args) {
return originalQueryFn.apply(void 0, args);
})), function (data) {
queryInfoRef.current.query.canFetchMore = getGetFetchMore()(data[data.length - 1], data);
return data;
});
});
var queryInfo = useBaseQuery(queryKey, queryVariables, queryFn, config);
queryInfoRef.current = queryInfo;
var refetch = queryInfo.refetch,
_queryInfo$data = queryInfo.data,
data = _queryInfo$data === void 0 ? [] : _queryInfo$data,
canFetchMore = queryInfo.query.canFetchMore; // Here we seed the pageVariabes for the query
if (!queryInfo.query.pageVariables) {
queryInfo.query.pageVariables = [[].concat(queryInfo.query.queryKey, queryInfo.query.queryVariables)];
}
var fetchMore = React.useCallback(function (fetchMoreInfo) {
if (fetchMoreInfo === void 0) {
fetchMoreInfo = queryInfoRef.current.query.canFetchMore;
}
return refetch({
force: true,
__queryFn: _async$3(function () {
for (var _len2 = arguments.length, args = new Array(_len2), _key2 = 0; _key2 < _len2; _key2++) {
args[_key2] = arguments[_key2];
}
return _finallyRethrows(function () {
queryInfoRef.current.query.isFetchingMore = true;
var newArgs = [].concat(args, [fetchMoreInfo]);
queryInfoRef.current.query.pageVariables.push(newArgs);
var _queryInfoRef$current = queryInfoRef.current.data;
return _await$3(originalQueryFn.apply(void 0, newArgs), function (_originalQueryFn) {
var data = [].concat(_queryInfoRef$current, [_originalQueryFn]);
queryInfoRef.current.query.canFetchMore = getGetFetchMore()(data[data.length - 1], data);
return data;
});
}, function (_wasThrown, _result) {
queryInfoRef.current.query.isFetchingMore = false;
return _rethrow(_wasThrown, _result);
});
})
});
}, [getGetFetchMore, originalQueryFn, refetch]);
var isFetchingMore = React.useMemo(function () {
return !!queryInfo.query.isFetchingMore;
}, [queryInfo.query.isFetchingMore]);
if (queryInfo.config.suspense) {
if (queryInfo.status === statusError) {
throw queryInfo.error;
}
if (queryInfo.status === statusLoading) {
queryInfo.wasSuspensed = true;
throw queryInfo.refetch();
}
}
return _extends({}, queryInfo, {
data: data,
canFetchMore: canFetchMore,
fetchMore: fetchMore,
isFetchingMore: isFetchingMore
});
}
exports.ReactQueryConfigProvider = ReactQueryConfigProvider;
exports.queryCache = queryCache;
exports.setConsole = setConsole;
exports.setFocusHandler = setFocusHandler;
exports.stableStringify = stableStringify;
exports.statusError = statusError;
exports.statusIdle = statusIdle;
exports.statusLoading = statusLoading;
exports.statusSuccess = statusSuccess;
exports.useInfiniteQuery = useInfiniteQuery;
exports.useIsFetching = useIsFetching;
exports.useMutation = useMutation;
exports.usePaginatedQuery = usePaginatedQuery;
exports.useQuery = useQuery;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=react-query.development.js.map