vue-request
Advanced tools
Comparing version 2.0.0-beta.2 to 2.0.0-rc.1
@@ -29,3 +29,4 @@ 'use strict'; | ||
return !isServer && ((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.visibilityState) === 'visible'; | ||
if (isServer || isNil((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.visibilityState)) return true; | ||
return window.document.visibilityState === 'visible'; | ||
}; | ||
@@ -37,3 +38,3 @@ const isOnline = () => { | ||
}; | ||
const resolvedPromise = Promise.resolve(null); | ||
const resolvedPromise = () => new Promise(() => {}); | ||
const get = (source, path, defaultValue = undefined) => { | ||
@@ -63,2 +64,11 @@ // a[3].b -> a.3.b | ||
} | ||
const warning = (message, throwError = false) => { | ||
const msg = `Warning: [vue-request] ${message}`; | ||
if (throwError) { | ||
return new Error(msg); | ||
} else { | ||
console.error(msg); | ||
} | ||
}; | ||
const refToRaw = value => { | ||
@@ -68,6 +78,2 @@ return vueDemi.isRef(value) ? value.value : value; | ||
const definePlugin = options => { | ||
return options; | ||
}; | ||
const CACHE_MAP = new Map(); | ||
@@ -91,153 +97,20 @@ const getCache = cacheKey => { | ||
}; | ||
const clearCache = cacheKey => { | ||
if (cacheKey) { | ||
var _CACHE_MAP$get; | ||
const cacheQuery = new Map(); | ||
const setCacheQuery = (cacheKey, query) => { | ||
cacheQuery.set(cacheKey, query); | ||
query.then(res => { | ||
cacheQuery.delete(cacheKey); | ||
return res; | ||
}).catch(() => { | ||
cacheQuery.delete(cacheKey); | ||
}); | ||
}; | ||
const getCacheQuery = cacheKey => { | ||
return cacheQuery.get(cacheKey); | ||
}; | ||
const listeners = new Map(); | ||
const trigger = (key, data) => { | ||
if (listeners.has(key)) { | ||
listeners.get(key).forEach(item => item(data)); | ||
const timer = (_CACHE_MAP$get = CACHE_MAP.get(cacheKey)) === null || _CACHE_MAP$get === void 0 ? void 0 : _CACHE_MAP$get.timer; | ||
timer && clearTimeout(timer); | ||
CACHE_MAP.delete(cacheKey); | ||
} else { | ||
// clear timer | ||
CACHE_MAP.forEach(i => i.timer && clearTimeout(i.timer)); | ||
CACHE_MAP.clear(); | ||
} | ||
}; | ||
const subscribe = (key, listener) => { | ||
if (!listeners.has(key)) { | ||
listeners.set(key, [listener]); | ||
} else { | ||
listeners.get(key).push(listener); | ||
} | ||
return () => { | ||
const index = listeners.get(key).indexOf(listener); | ||
listeners.get(key).splice(index, 1); | ||
}; | ||
const definePlugin = options => { | ||
return options; | ||
}; | ||
var useCachePlugin = definePlugin((queryInstance, { | ||
cacheKey, | ||
cacheTime = 600000, | ||
staleTime = 0, | ||
getCache: customGetCache, | ||
setCache: customSetCache | ||
}) => { | ||
if (!cacheKey) return {}; | ||
const unSubscribe = vueDemi.ref(); | ||
let currentQuery; | ||
const _getCache = key => { | ||
if (customGetCache) { | ||
return customGetCache(key); | ||
} else { | ||
return getCache(key); | ||
} | ||
}; | ||
const _setCache = (key, time, cacheData) => { | ||
if (customSetCache) { | ||
customSetCache(key, cacheData); | ||
} else { | ||
setCache(key, time, cacheData); | ||
} | ||
trigger(key, cacheData.data); | ||
}; | ||
const isFresh = time => staleTime === -1 || time + staleTime > new Date().getTime(); // Returns a boolean indicating whether the object has the specified property as its own property | ||
// (as opposed to inheriting it) | ||
const hasProp = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); | ||
const subscribeCache = () => subscribe(cacheKey, data => { | ||
queryInstance.data.value = data; | ||
}); // When initializing, restore if there is a cache | ||
const cache = _getCache(cacheKey); | ||
if (cache && hasProp(cache, 'data')) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.params.value = cache.params; | ||
} | ||
unSubscribe.value = subscribeCache(); | ||
vueDemi.onUnmounted(() => { | ||
unSubscribe.value(); | ||
}); | ||
return { | ||
onBefore() { | ||
const cache = _getCache(cacheKey); | ||
if (!cache || !hasProp(cache, 'data')) { | ||
return {}; | ||
} // If it's fresh, stop the request | ||
if (isFresh(cache.time)) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.loading.value = false; | ||
return { | ||
isBreak: true, | ||
breakResult: cache.data | ||
}; | ||
} else { | ||
// If it is not fresh, set data and request | ||
queryInstance.data.value = cache.data; | ||
} | ||
}, | ||
onQuery(service, params) { | ||
let servicePromise = getCacheQuery(cacheKey); | ||
if (servicePromise && servicePromise !== currentQuery) { | ||
return { | ||
servicePromise | ||
}; | ||
} | ||
servicePromise = service(...params); | ||
currentQuery = servicePromise; | ||
setCacheQuery(cacheKey, servicePromise); | ||
return { | ||
servicePromise | ||
}; | ||
}, | ||
onSuccess(data, params) { | ||
unSubscribe.value(); | ||
_setCache(cacheKey, cacheTime, { | ||
data, | ||
params, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(); | ||
}, | ||
onMutate(data) { | ||
unSubscribe.value(); | ||
_setCache(cacheKey, cacheTime, { | ||
data, | ||
params: queryInstance.params.value, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(); | ||
} | ||
}; | ||
}); | ||
/** | ||
@@ -571,173 +444,2 @@ * source by `lodash` | ||
var useLoadingDelayPlugin = definePlugin((queryInstance, { | ||
loadingDelay = 0 | ||
}) => { | ||
const delayLoadingTimer = vueDemi.ref(() => {}); | ||
const loadingDelayRef = vueDemi.computed(() => refToRaw(loadingDelay)); | ||
const delayLoading = () => { | ||
let timerId; | ||
if (loadingDelayRef.value) { | ||
timerId = setTimeout(() => { | ||
queryInstance.loading.value = true; | ||
}, loadingDelayRef.value); | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
return { | ||
onBefore() { | ||
queryInstance.loading.value = !loadingDelayRef.value; | ||
delayLoadingTimer.value(); | ||
delayLoadingTimer.value = delayLoading(); | ||
}, | ||
onCancel() { | ||
delayLoadingTimer.value(); | ||
}, | ||
onAfter() { | ||
delayLoadingTimer.value(); | ||
} | ||
}; | ||
}); | ||
var _window; | ||
const FOCUS_LISTENER = new Set(); | ||
const VISIBLE_LISTENER = new Set(); | ||
const RECONNECT_LISTENER = new Set(); | ||
const subscriber = (listenerType, event) => { | ||
let listeners; | ||
switch (listenerType) { | ||
case 'FOCUS_LISTENER': | ||
listeners = FOCUS_LISTENER; | ||
break; | ||
case 'RECONNECT_LISTENER': | ||
listeners = RECONNECT_LISTENER; | ||
break; | ||
case 'VISIBLE_LISTENER': | ||
listeners = VISIBLE_LISTENER; | ||
break; | ||
} | ||
if (listeners.has(event)) return; | ||
listeners.add(event); | ||
return () => { | ||
listeners.delete(event); | ||
}; | ||
}; | ||
const observer = listeners => { | ||
listeners.forEach(event => { | ||
event(); | ||
}); | ||
}; | ||
/* istanbul ignore else */ | ||
if (!isServer && (_window = window) !== null && _window !== void 0 && _window.addEventListener) { | ||
window.addEventListener('visibilitychange', () => { | ||
/* istanbul ignore else */ | ||
if (isDocumentVisibility()) { | ||
observer(VISIBLE_LISTENER); | ||
} | ||
}, false); | ||
window.addEventListener('focus', () => observer(FOCUS_LISTENER), false); | ||
window.addEventListener('online', () => observer(RECONNECT_LISTENER), false); | ||
} | ||
var usePollingPlugin = definePlugin((queryInstance, { | ||
pollingInterval, | ||
pollingWhenHidden = false, | ||
pollingWhenOffline = false, | ||
errorRetryCount = 0 | ||
}) => { | ||
const pollingTimer = vueDemi.ref(); | ||
const stopPollingWhenHiddenOrOffline = vueDemi.ref(false); | ||
const pollingIntervalRef = vueDemi.computed(() => refToRaw(pollingInterval)); | ||
const errorRetryCountRef = vueDemi.computed(() => refToRaw(errorRetryCount)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const isKeepPolling = () => { | ||
return (// pollingWhenHidden = true or pollingWhenHidden = false and document is visibility | ||
(pollingWhenHidden || isDocumentVisibility()) && ( // pollingWhenOffline = true or pollingWhenOffline = false and is online | ||
pollingWhenOffline || isOnline()) | ||
); | ||
}; | ||
const polling = pollingFunc => { | ||
// if errorRetry is enabled, then skip this method | ||
if (queryInstance.error.value && errorRetryCountRef.value !== 0) return; | ||
let timerId; | ||
if (!isNil(pollingIntervalRef.value) && pollingIntervalRef.value >= 0) { | ||
if (isKeepPolling()) { | ||
timerId = setTimeout(pollingFunc, pollingIntervalRef.value); | ||
} else { | ||
// stop polling | ||
stopPollingWhenHiddenOrOffline.value = true; | ||
return; | ||
} | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
const rePolling = () => { | ||
if (stopPollingWhenHiddenOrOffline.value && isKeepPolling()) { | ||
queryInstance.context.refresh(); | ||
stopPollingWhenHiddenOrOffline.value = false; | ||
} | ||
}; | ||
vueDemi.watch(pollingIntervalRef, () => { | ||
if (pollingTimer.value) { | ||
pollingTimer.value(); | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}); // subscribe polling | ||
if (!pollingWhenHidden) { | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', rePolling)); | ||
} // subscribe online when pollingWhenOffline is false | ||
if (!pollingWhenOffline) { | ||
addUnsubscribeList(subscriber('RECONNECT_LISTENER', rePolling)); | ||
} | ||
vueDemi.onUnmounted(() => { | ||
unsubscribeList.forEach(unsubscribe => unsubscribe()); | ||
}); | ||
return { | ||
onBefore() { | ||
var _pollingTimer$value; | ||
(_pollingTimer$value = pollingTimer.value) === null || _pollingTimer$value === void 0 ? void 0 : _pollingTimer$value.call(pollingTimer); | ||
}, | ||
onCancel() { | ||
var _pollingTimer$value2; | ||
(_pollingTimer$value2 = pollingTimer.value) === null || _pollingTimer$value2 === void 0 ? void 0 : _pollingTimer$value2.call(pollingTimer); | ||
}, | ||
onAfter() { | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}; | ||
}); | ||
var useReadyPlugin = definePlugin((queryInstance, { | ||
@@ -777,8 +479,6 @@ ready = vueDemi.ref(true), | ||
vueDemi.watch(refreshDeps, () => { | ||
if (manual) return; | ||
if (refreshDepsAction) { | ||
refreshDepsAction(); | ||
} else { | ||
queryInstance.context.refresh(); | ||
!manual && queryInstance.context.refresh(); | ||
} | ||
@@ -791,45 +491,2 @@ }); | ||
const limitTrigger = (fn, timeInterval) => { | ||
let running = false; | ||
return (...args) => { | ||
if (running) return; | ||
running = true; | ||
fn(...args); | ||
setTimeout(() => { | ||
running = false; | ||
}, timeInterval); | ||
}; | ||
}; | ||
var useRefreshOnWindowFocus = definePlugin((queryInstance, { | ||
refreshOnWindowFocus = false, | ||
refocusTimespan = 5000 | ||
}) => { | ||
const refreshOnWindowFocusRef = vueDemi.computed(() => refToRaw(refreshOnWindowFocus)); | ||
const refocusTimespanRef = vueDemi.computed(() => refToRaw(refocusTimespan)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const unsubscribe = () => { | ||
unsubscribeList.forEach(fn => fn()); | ||
}; | ||
vueDemi.watchEffect(() => { | ||
unsubscribe(); | ||
if (refreshOnWindowFocusRef.value) { | ||
const limitRefresh = limitTrigger(queryInstance.context.refresh, refocusTimespanRef.value); | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', limitRefresh)); | ||
addUnsubscribeList(subscriber('FOCUS_LISTENER', limitRefresh)); | ||
} | ||
}); | ||
vueDemi.onUnmounted(() => { | ||
unsubscribe(); | ||
}); | ||
return {}; | ||
}); | ||
var useThrottlePlugin = definePlugin((queryInstance, { | ||
@@ -923,3 +580,3 @@ throttleInterval, | ||
isBreak, | ||
breakResult = resolvedPromise | ||
breakResult = resolvedPromise() | ||
} = emit('onBefore', args); | ||
@@ -939,3 +596,3 @@ if (isBreak) return breakResult; | ||
const res = await servicePromise; | ||
if (currentCount !== count.value) return resolvedPromise; | ||
if (currentCount !== count.value) return resolvedPromise(); | ||
setState({ | ||
@@ -952,3 +609,3 @@ data: res, | ||
} catch (error) { | ||
if (currentCount !== count.value) return resolvedPromise; | ||
if (currentCount !== count.value) return resolvedPromise(); | ||
setState({ | ||
@@ -983,7 +640,7 @@ loading: false, | ||
context.refresh = () => { | ||
context.run(...params.value); | ||
context.run(...(params.value || [])); | ||
}; | ||
context.refreshAsync = () => { | ||
return context.runAsync(...params.value); | ||
return context.runAsync(...(params.value || [])); | ||
}; | ||
@@ -993,6 +650,9 @@ | ||
const mutateData = isFunction(x) ? x(data.value) : x; | ||
const _mutateData = isObject(mutateData) ? Object.assign({}, mutateData) : mutateData; | ||
setState({ | ||
data: mutateData | ||
data: _mutateData | ||
}); | ||
emit('onMutate', mutateData); | ||
emit('onMutate', _mutateData); | ||
}; | ||
@@ -1045,132 +705,517 @@ | ||
function useRequest(service, options) { | ||
return useQuery(service, options, [useLoadingDelayPlugin, useErrorRetryPlugin, useDebouncePlugin, usePollingPlugin, useThrottlePlugin, useRefreshOnWindowFocus, useRefreshDepsPlugin, useReadyPlugin, useCachePlugin]); | ||
} | ||
function useLoadMore(service, options) { | ||
var _injectedGlobalOption; | ||
const injectedGlobalOptions = vueDemi.inject(GLOBAL_OPTIONS_PROVIDE_KEY, {}); | ||
const { | ||
isNoMore, | ||
listKey = 'list', | ||
...restOptions | ||
} = Object.assign({ | ||
listKey: (_injectedGlobalOption = injectedGlobalOptions.listKey) !== null && _injectedGlobalOption !== void 0 ? _injectedGlobalOption : getGlobalOptions().listKey | ||
}, options !== null && options !== void 0 ? options : {}); | ||
const refreshing = vueDemi.ref(false); | ||
} = options !== null && options !== void 0 ? options : {}; | ||
const data = vueDemi.shallowRef(); | ||
const dataList = vueDemi.computed(() => { | ||
var _data$value; | ||
return ((_data$value = data.value) === null || _data$value === void 0 ? void 0 : _data$value.list) || []; | ||
}); | ||
const loadingMore = vueDemi.ref(false); | ||
const reloading = vueDemi.ref(false); | ||
const dataList = vueDemi.ref([]); | ||
const isTriggerByLoadMore = vueDemi.ref(false); | ||
const count = vueDemi.ref(0); | ||
const { | ||
data, | ||
params, | ||
runAsync, | ||
run, | ||
cancel: _cancel, | ||
...rest // @ts-ignore | ||
...rest | ||
} = useQuery(async lastData => { | ||
const currentCount = count.value; | ||
const currentData = await service(lastData); | ||
} = useRequest(service, { ...restOptions, | ||
onSuccess: (...p) => { | ||
var _restOptions$onSucces; | ||
if (currentCount === count.value) { | ||
if (lastData) { | ||
data.value = { ...currentData, | ||
list: [...lastData.list, ...currentData.list] | ||
}; | ||
} else { | ||
data.value = currentData; | ||
} | ||
} | ||
if (refreshing.value) { | ||
dataList.value = []; | ||
return currentData; | ||
}, { ...restOptions, | ||
defaultParams: [], | ||
refreshDepsAction: () => { | ||
if (restOptions !== null && restOptions !== void 0 && restOptions.refreshDepsAction) { | ||
restOptions.refreshDepsAction(); | ||
} else { | ||
refresh(); | ||
} | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
reloading.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onSucces = restOptions.onSuccess) === null || _restOptions$onSucces === void 0 ? void 0 : _restOptions$onSucces.call(restOptions, ...p); | ||
}, | ||
onError: (...p) => { | ||
onError: error => { | ||
var _restOptions$onError; | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
reloading.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onError = restOptions.onError) === null || _restOptions$onError === void 0 ? void 0 : _restOptions$onError.call(restOptions, ...p); | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onError = restOptions.onError) === null || _restOptions$onError === void 0 ? void 0 : _restOptions$onError.call(restOptions, error); | ||
}, | ||
onAfter: (...p) => { | ||
onSuccess: data => { | ||
var _restOptions$onSucces; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onSucces = restOptions.onSuccess) === null || _restOptions$onSucces === void 0 ? void 0 : _restOptions$onSucces.call(restOptions, data); | ||
}, | ||
onBefore: () => { | ||
var _restOptions$onBefore; | ||
count.value += 1; | ||
if (isTriggerByLoadMore.value) { | ||
isTriggerByLoadMore.value = false; | ||
loadingMore.value = true; | ||
} | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onBefore = restOptions.onBefore) === null || _restOptions$onBefore === void 0 ? void 0 : _restOptions$onBefore.call(restOptions); | ||
}, | ||
onAfter: () => { | ||
var _restOptions$onAfter; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onAfter = restOptions.onAfter) === null || _restOptions$onAfter === void 0 ? void 0 : _restOptions$onAfter.call(restOptions, ...p); | ||
loadingMore.value = false; | ||
isTriggerByLoadMore.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onAfter = restOptions.onAfter) === null || _restOptions$onAfter === void 0 ? void 0 : _restOptions$onAfter.call(restOptions); | ||
} | ||
}); | ||
}, [useErrorRetryPlugin, useDebouncePlugin, useThrottlePlugin, useRefreshDepsPlugin, useReadyPlugin]); | ||
const noMore = vueDemi.computed(() => { | ||
return isNoMore && isFunction(isNoMore) ? isNoMore(data.value) : false; | ||
}); | ||
vueDemi.watch(data, value => { | ||
if (value) { | ||
const list = get(value, listKey); | ||
if (list && Array.isArray(list)) { | ||
dataList.value = [...dataList.value, ...list]; | ||
} | ||
} | ||
}); | ||
const loadMore = () => { | ||
loadMoreAsync().catch(() => {}); | ||
}; | ||
const loadMore = () => { | ||
const loadMoreAsync = () => { | ||
if (noMore.value) { | ||
return; | ||
return Promise.reject(warning('No more data. You need to ignore this error by checking if `noMore` is false before calling `loadMoreAsync`', true)); | ||
} | ||
loadingMore.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [{ | ||
dataList: dataList.value, | ||
data: data.value | ||
}, ...restParams]; | ||
run(...mergerParams); | ||
isTriggerByLoadMore.value = true; | ||
return runAsync(data.value); | ||
}; | ||
const refreshAsync = async () => { | ||
refreshing.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
await runAsync(...mergerParams); | ||
}; | ||
const refresh = () => run(); | ||
const refresh = () => { | ||
refreshing.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
runAsync(...mergerParams); | ||
}; | ||
const refreshAsync = () => runAsync(); | ||
const reload = () => { | ||
reloading.value = true; | ||
cancel(); | ||
dataList.value = []; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
run(...mergerParams); | ||
}; | ||
const cancel = () => { | ||
count.value += 1; | ||
const cancel = () => { | ||
_cancel(); | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
}; | ||
const mutate = x => { | ||
const mutateData = isFunction(x) ? x(data.value) : x; | ||
const _mutateData = isObject(mutateData) ? Object.assign({}, mutateData) : mutateData; | ||
data.value = _mutateData; | ||
}; | ||
return { | ||
data, | ||
dataList, | ||
params, | ||
loadingMore, | ||
noMore, | ||
loadingMore, | ||
refreshing, | ||
reloading, | ||
runAsync, | ||
reload, | ||
loadMore, | ||
cancel, | ||
mutate, | ||
refresh, | ||
cancel, | ||
run, | ||
refreshAsync, | ||
...omit(rest, ['refresh', 'refreshAsync']) | ||
loadMore, | ||
loadMoreAsync, | ||
...omit(rest, ['refresh', 'refreshAsync', 'mutate', 'params', 'data']) | ||
}; | ||
} | ||
const cacheQuery = new Map(); | ||
const setCacheQuery = (cacheKey, query) => { | ||
cacheQuery.set(cacheKey, query); | ||
query.then(res => { | ||
cacheQuery.delete(cacheKey); | ||
return res; | ||
}).catch(() => { | ||
cacheQuery.delete(cacheKey); | ||
}); | ||
}; | ||
const getCacheQuery = cacheKey => { | ||
return cacheQuery.get(cacheKey); | ||
}; | ||
const listeners = new Map(); | ||
const trigger = (key, data) => { | ||
if (listeners.has(key)) { | ||
listeners.get(key).forEach(item => item(data)); | ||
} | ||
}; | ||
const subscribe = (key, listener) => { | ||
if (!listeners.has(key)) { | ||
listeners.set(key, [listener]); | ||
} else { | ||
listeners.get(key).push(listener); | ||
} | ||
return () => { | ||
const index = listeners.get(key).indexOf(listener); | ||
listeners.get(key).splice(index, 1); | ||
}; | ||
}; | ||
var useCachePlugin = definePlugin((queryInstance, { | ||
cacheKey: customCacheKey, | ||
cacheTime = 600000, | ||
staleTime = 0, | ||
getCache: customGetCache, | ||
setCache: customSetCache | ||
}) => { | ||
if (!customCacheKey) return {}; | ||
const cacheKey = isFunction(customCacheKey) ? customCacheKey : () => customCacheKey; | ||
const unSubscribe = vueDemi.ref(() => {}); | ||
let currentQuery; | ||
const _getCache = key => { | ||
if (customGetCache) { | ||
return customGetCache(key); | ||
} else { | ||
return getCache(key); | ||
} | ||
}; | ||
const _setCache = (key, time, cacheData) => { | ||
if (customSetCache) { | ||
customSetCache(key, cacheData); | ||
} else { | ||
setCache(key, time, cacheData); | ||
} | ||
trigger(key, cacheData.data); | ||
}; | ||
const isFresh = time => staleTime === -1 || time + staleTime > new Date().getTime(); // Returns a boolean indicating whether the object has the specified property as its own property | ||
// (as opposed to inheriting it) | ||
const hasProp = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); | ||
const subscribeCache = params => { | ||
const _cacheKey = cacheKey(params); | ||
return subscribe(_cacheKey, data => { | ||
queryInstance.data.value = data; | ||
}); | ||
}; // When initializing, restore if there is a cache | ||
const _cacheKey = cacheKey(); | ||
const cache = _getCache(_cacheKey); | ||
if (cache && hasProp(cache, 'data')) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.params.value = cache.params; | ||
} | ||
if (_cacheKey) { | ||
unSubscribe.value = subscribeCache(); | ||
} | ||
vueDemi.onUnmounted(() => { | ||
unSubscribe.value(); | ||
}); | ||
return { | ||
onBefore(params) { | ||
const _cacheKey = cacheKey(params); | ||
const cache = _getCache(_cacheKey); | ||
if (!cache || !hasProp(cache, 'data')) { | ||
return {}; | ||
} // If it's fresh, stop the request | ||
if (isFresh(cache.time)) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.loading.value = false; | ||
return { | ||
isBreak: true, | ||
breakResult: cache.data | ||
}; | ||
} else { | ||
// If it is not fresh, set data and request | ||
queryInstance.data.value = cache.data; | ||
} | ||
}, | ||
onQuery(service, params) { | ||
const _cacheKey = cacheKey(params); | ||
let servicePromise = getCacheQuery(_cacheKey); | ||
if (servicePromise && servicePromise !== currentQuery) { | ||
return { | ||
servicePromise | ||
}; | ||
} | ||
servicePromise = service(...params); | ||
currentQuery = servicePromise; | ||
setCacheQuery(_cacheKey, servicePromise); | ||
return { | ||
servicePromise | ||
}; | ||
}, | ||
onSuccess(data, params) { | ||
const _cacheKey = cacheKey(params); | ||
if (_cacheKey) { | ||
unSubscribe.value(); | ||
_setCache(_cacheKey, cacheTime, { | ||
data, | ||
params, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(params); | ||
} | ||
}, | ||
onMutate(data) { | ||
const _cacheKey = cacheKey(queryInstance.params.value); | ||
if (_cacheKey) { | ||
unSubscribe.value(); | ||
_setCache(_cacheKey, cacheTime, { | ||
data, | ||
params: queryInstance.params.value, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(queryInstance.params.value); | ||
} | ||
} | ||
}; | ||
}); | ||
var useLoadingDelayPlugin = definePlugin((queryInstance, { | ||
loadingDelay = 0 | ||
}) => { | ||
const delayLoadingTimer = vueDemi.ref(() => {}); | ||
const loadingDelayRef = vueDemi.computed(() => refToRaw(loadingDelay)); | ||
const delayLoading = () => { | ||
let timerId; | ||
if (loadingDelayRef.value) { | ||
timerId = setTimeout(() => { | ||
queryInstance.loading.value = true; | ||
}, loadingDelayRef.value); | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
return { | ||
onBefore() { | ||
queryInstance.loading.value = !loadingDelayRef.value; | ||
delayLoadingTimer.value(); | ||
delayLoadingTimer.value = delayLoading(); | ||
}, | ||
onCancel() { | ||
delayLoadingTimer.value(); | ||
}, | ||
onAfter() { | ||
delayLoadingTimer.value(); | ||
} | ||
}; | ||
}); | ||
var _window; | ||
const FOCUS_LISTENER = new Set(); | ||
const VISIBLE_LISTENER = new Set(); | ||
const RECONNECT_LISTENER = new Set(); | ||
const subscriber = (listenerType, event) => { | ||
let listeners; | ||
switch (listenerType) { | ||
case 'FOCUS_LISTENER': | ||
listeners = FOCUS_LISTENER; | ||
break; | ||
case 'RECONNECT_LISTENER': | ||
listeners = RECONNECT_LISTENER; | ||
break; | ||
case 'VISIBLE_LISTENER': | ||
listeners = VISIBLE_LISTENER; | ||
break; | ||
} | ||
if (listeners.has(event)) return; | ||
listeners.add(event); | ||
return () => { | ||
listeners.delete(event); | ||
}; | ||
}; | ||
const observer = listeners => { | ||
listeners.forEach(event => { | ||
event(); | ||
}); | ||
}; | ||
/* istanbul ignore else */ | ||
if (!isServer && (_window = window) !== null && _window !== void 0 && _window.addEventListener) { | ||
window.addEventListener('visibilitychange', () => { | ||
/* istanbul ignore else */ | ||
if (isDocumentVisibility()) { | ||
observer(VISIBLE_LISTENER); | ||
} | ||
}, false); | ||
window.addEventListener('focus', () => observer(FOCUS_LISTENER), false); | ||
window.addEventListener('online', () => observer(RECONNECT_LISTENER), false); | ||
} | ||
var usePollingPlugin = definePlugin((queryInstance, { | ||
pollingInterval, | ||
pollingWhenHidden = false, | ||
pollingWhenOffline = false, | ||
errorRetryCount = 0 | ||
}) => { | ||
const pollingTimer = vueDemi.ref(); | ||
const stopPollingWhenHiddenOrOffline = vueDemi.ref(false); | ||
const pollingIntervalRef = vueDemi.computed(() => refToRaw(pollingInterval)); | ||
const errorRetryCountRef = vueDemi.computed(() => refToRaw(errorRetryCount)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const isKeepPolling = () => { | ||
return (// pollingWhenHidden = true or pollingWhenHidden = false and document is visibility | ||
(pollingWhenHidden || isDocumentVisibility()) && ( // pollingWhenOffline = true or pollingWhenOffline = false and is online | ||
pollingWhenOffline || isOnline()) | ||
); | ||
}; | ||
const polling = pollingFunc => { | ||
// if errorRetry is enabled, then skip this method | ||
if (queryInstance.error.value && errorRetryCountRef.value !== 0) return; | ||
let timerId; | ||
if (!isNil(pollingIntervalRef.value) && pollingIntervalRef.value >= 0) { | ||
if (isKeepPolling()) { | ||
timerId = setTimeout(pollingFunc, pollingIntervalRef.value); | ||
} else { | ||
// stop polling | ||
stopPollingWhenHiddenOrOffline.value = true; | ||
return; | ||
} | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
const rePolling = () => { | ||
if (stopPollingWhenHiddenOrOffline.value && isKeepPolling()) { | ||
queryInstance.context.refresh(); | ||
stopPollingWhenHiddenOrOffline.value = false; | ||
} | ||
}; | ||
vueDemi.watch(pollingIntervalRef, () => { | ||
if (pollingTimer.value) { | ||
pollingTimer.value(); | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}); // subscribe polling | ||
if (!pollingWhenHidden) { | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', rePolling)); | ||
} // subscribe online when pollingWhenOffline is false | ||
if (!pollingWhenOffline) { | ||
addUnsubscribeList(subscriber('RECONNECT_LISTENER', rePolling)); | ||
} | ||
vueDemi.onUnmounted(() => { | ||
unsubscribeList.forEach(unsubscribe => unsubscribe()); | ||
}); | ||
return { | ||
onBefore() { | ||
var _pollingTimer$value; | ||
(_pollingTimer$value = pollingTimer.value) === null || _pollingTimer$value === void 0 ? void 0 : _pollingTimer$value.call(pollingTimer); | ||
}, | ||
onCancel() { | ||
var _pollingTimer$value2; | ||
(_pollingTimer$value2 = pollingTimer.value) === null || _pollingTimer$value2 === void 0 ? void 0 : _pollingTimer$value2.call(pollingTimer); | ||
}, | ||
onAfter() { | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}; | ||
}); | ||
const limitTrigger = (fn, timeInterval) => { | ||
let running = false; | ||
return (...args) => { | ||
if (running) return; | ||
running = true; | ||
fn(...args); | ||
setTimeout(() => { | ||
running = false; | ||
}, timeInterval); | ||
}; | ||
}; | ||
var useRefreshOnWindowFocus = definePlugin((queryInstance, { | ||
refreshOnWindowFocus = false, | ||
refocusTimespan = 5000 | ||
}) => { | ||
const refreshOnWindowFocusRef = vueDemi.computed(() => refToRaw(refreshOnWindowFocus)); | ||
const refocusTimespanRef = vueDemi.computed(() => refToRaw(refocusTimespan)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const unsubscribe = () => { | ||
unsubscribeList.forEach(fn => fn()); | ||
}; | ||
vueDemi.watchEffect(() => { | ||
unsubscribe(); | ||
if (refreshOnWindowFocusRef.value) { | ||
const limitRefresh = limitTrigger(queryInstance.context.refresh, refocusTimespanRef.value); | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', limitRefresh)); | ||
addUnsubscribeList(subscriber('FOCUS_LISTENER', limitRefresh)); | ||
} | ||
}); | ||
vueDemi.onUnmounted(() => { | ||
unsubscribe(); | ||
}); | ||
return {}; | ||
}); | ||
function useRequest(service, options) { | ||
return useQuery(service, options, [useLoadingDelayPlugin, useErrorRetryPlugin, useDebouncePlugin, usePollingPlugin, useThrottlePlugin, useRefreshOnWindowFocus, useRefreshDepsPlugin, useReadyPlugin, useCachePlugin]); | ||
} | ||
function usePagination(service, options = {}) { | ||
@@ -1283,2 +1328,3 @@ const defaultPaginationOptions = { | ||
exports.clearCache = clearCache; | ||
exports.setGlobalOptions = setGlobalOptions; | ||
@@ -1285,0 +1331,0 @@ exports.useLoadMore = useLoadMore; |
@@ -1,2 +0,2 @@ | ||
import { isRef, ref, onUnmounted, computed, watchEffect, watch, shallowRef, inject, provide } from 'vue-demi'; | ||
import { isRef, ref, computed, watchEffect, watch, shallowRef, inject, onUnmounted, provide } from 'vue-demi'; | ||
@@ -25,3 +25,4 @@ const GLOBAL_OPTIONS = {}; | ||
return !isServer && ((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.visibilityState) === 'visible'; | ||
if (isServer || isNil((_window$document = window.document) === null || _window$document === void 0 ? void 0 : _window$document.visibilityState)) return true; | ||
return window.document.visibilityState === 'visible'; | ||
}; | ||
@@ -33,3 +34,3 @@ const isOnline = () => { | ||
}; | ||
const resolvedPromise = Promise.resolve(null); | ||
const resolvedPromise = () => new Promise(() => {}); | ||
const get = (source, path, defaultValue = undefined) => { | ||
@@ -59,2 +60,11 @@ // a[3].b -> a.3.b | ||
} | ||
const warning = (message, throwError = false) => { | ||
const msg = `Warning: [vue-request] ${message}`; | ||
if (throwError) { | ||
return new Error(msg); | ||
} else { | ||
console.error(msg); | ||
} | ||
}; | ||
const refToRaw = value => { | ||
@@ -64,6 +74,2 @@ return isRef(value) ? value.value : value; | ||
const definePlugin = options => { | ||
return options; | ||
}; | ||
const CACHE_MAP = new Map(); | ||
@@ -87,153 +93,20 @@ const getCache = cacheKey => { | ||
}; | ||
const clearCache = cacheKey => { | ||
if (cacheKey) { | ||
var _CACHE_MAP$get; | ||
const cacheQuery = new Map(); | ||
const setCacheQuery = (cacheKey, query) => { | ||
cacheQuery.set(cacheKey, query); | ||
query.then(res => { | ||
cacheQuery.delete(cacheKey); | ||
return res; | ||
}).catch(() => { | ||
cacheQuery.delete(cacheKey); | ||
}); | ||
}; | ||
const getCacheQuery = cacheKey => { | ||
return cacheQuery.get(cacheKey); | ||
}; | ||
const listeners = new Map(); | ||
const trigger = (key, data) => { | ||
if (listeners.has(key)) { | ||
listeners.get(key).forEach(item => item(data)); | ||
const timer = (_CACHE_MAP$get = CACHE_MAP.get(cacheKey)) === null || _CACHE_MAP$get === void 0 ? void 0 : _CACHE_MAP$get.timer; | ||
timer && clearTimeout(timer); | ||
CACHE_MAP.delete(cacheKey); | ||
} else { | ||
// clear timer | ||
CACHE_MAP.forEach(i => i.timer && clearTimeout(i.timer)); | ||
CACHE_MAP.clear(); | ||
} | ||
}; | ||
const subscribe = (key, listener) => { | ||
if (!listeners.has(key)) { | ||
listeners.set(key, [listener]); | ||
} else { | ||
listeners.get(key).push(listener); | ||
} | ||
return () => { | ||
const index = listeners.get(key).indexOf(listener); | ||
listeners.get(key).splice(index, 1); | ||
}; | ||
const definePlugin = options => { | ||
return options; | ||
}; | ||
var useCachePlugin = definePlugin((queryInstance, { | ||
cacheKey, | ||
cacheTime = 600000, | ||
staleTime = 0, | ||
getCache: customGetCache, | ||
setCache: customSetCache | ||
}) => { | ||
if (!cacheKey) return {}; | ||
const unSubscribe = ref(); | ||
let currentQuery; | ||
const _getCache = key => { | ||
if (customGetCache) { | ||
return customGetCache(key); | ||
} else { | ||
return getCache(key); | ||
} | ||
}; | ||
const _setCache = (key, time, cacheData) => { | ||
if (customSetCache) { | ||
customSetCache(key, cacheData); | ||
} else { | ||
setCache(key, time, cacheData); | ||
} | ||
trigger(key, cacheData.data); | ||
}; | ||
const isFresh = time => staleTime === -1 || time + staleTime > new Date().getTime(); // Returns a boolean indicating whether the object has the specified property as its own property | ||
// (as opposed to inheriting it) | ||
const hasProp = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); | ||
const subscribeCache = () => subscribe(cacheKey, data => { | ||
queryInstance.data.value = data; | ||
}); // When initializing, restore if there is a cache | ||
const cache = _getCache(cacheKey); | ||
if (cache && hasProp(cache, 'data')) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.params.value = cache.params; | ||
} | ||
unSubscribe.value = subscribeCache(); | ||
onUnmounted(() => { | ||
unSubscribe.value(); | ||
}); | ||
return { | ||
onBefore() { | ||
const cache = _getCache(cacheKey); | ||
if (!cache || !hasProp(cache, 'data')) { | ||
return {}; | ||
} // If it's fresh, stop the request | ||
if (isFresh(cache.time)) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.loading.value = false; | ||
return { | ||
isBreak: true, | ||
breakResult: cache.data | ||
}; | ||
} else { | ||
// If it is not fresh, set data and request | ||
queryInstance.data.value = cache.data; | ||
} | ||
}, | ||
onQuery(service, params) { | ||
let servicePromise = getCacheQuery(cacheKey); | ||
if (servicePromise && servicePromise !== currentQuery) { | ||
return { | ||
servicePromise | ||
}; | ||
} | ||
servicePromise = service(...params); | ||
currentQuery = servicePromise; | ||
setCacheQuery(cacheKey, servicePromise); | ||
return { | ||
servicePromise | ||
}; | ||
}, | ||
onSuccess(data, params) { | ||
unSubscribe.value(); | ||
_setCache(cacheKey, cacheTime, { | ||
data, | ||
params, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(); | ||
}, | ||
onMutate(data) { | ||
unSubscribe.value(); | ||
_setCache(cacheKey, cacheTime, { | ||
data, | ||
params: queryInstance.params.value, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(); | ||
} | ||
}; | ||
}); | ||
/** | ||
@@ -567,173 +440,2 @@ * source by `lodash` | ||
var useLoadingDelayPlugin = definePlugin((queryInstance, { | ||
loadingDelay = 0 | ||
}) => { | ||
const delayLoadingTimer = ref(() => {}); | ||
const loadingDelayRef = computed(() => refToRaw(loadingDelay)); | ||
const delayLoading = () => { | ||
let timerId; | ||
if (loadingDelayRef.value) { | ||
timerId = setTimeout(() => { | ||
queryInstance.loading.value = true; | ||
}, loadingDelayRef.value); | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
return { | ||
onBefore() { | ||
queryInstance.loading.value = !loadingDelayRef.value; | ||
delayLoadingTimer.value(); | ||
delayLoadingTimer.value = delayLoading(); | ||
}, | ||
onCancel() { | ||
delayLoadingTimer.value(); | ||
}, | ||
onAfter() { | ||
delayLoadingTimer.value(); | ||
} | ||
}; | ||
}); | ||
var _window; | ||
const FOCUS_LISTENER = new Set(); | ||
const VISIBLE_LISTENER = new Set(); | ||
const RECONNECT_LISTENER = new Set(); | ||
const subscriber = (listenerType, event) => { | ||
let listeners; | ||
switch (listenerType) { | ||
case 'FOCUS_LISTENER': | ||
listeners = FOCUS_LISTENER; | ||
break; | ||
case 'RECONNECT_LISTENER': | ||
listeners = RECONNECT_LISTENER; | ||
break; | ||
case 'VISIBLE_LISTENER': | ||
listeners = VISIBLE_LISTENER; | ||
break; | ||
} | ||
if (listeners.has(event)) return; | ||
listeners.add(event); | ||
return () => { | ||
listeners.delete(event); | ||
}; | ||
}; | ||
const observer = listeners => { | ||
listeners.forEach(event => { | ||
event(); | ||
}); | ||
}; | ||
/* istanbul ignore else */ | ||
if (!isServer && (_window = window) !== null && _window !== void 0 && _window.addEventListener) { | ||
window.addEventListener('visibilitychange', () => { | ||
/* istanbul ignore else */ | ||
if (isDocumentVisibility()) { | ||
observer(VISIBLE_LISTENER); | ||
} | ||
}, false); | ||
window.addEventListener('focus', () => observer(FOCUS_LISTENER), false); | ||
window.addEventListener('online', () => observer(RECONNECT_LISTENER), false); | ||
} | ||
var usePollingPlugin = definePlugin((queryInstance, { | ||
pollingInterval, | ||
pollingWhenHidden = false, | ||
pollingWhenOffline = false, | ||
errorRetryCount = 0 | ||
}) => { | ||
const pollingTimer = ref(); | ||
const stopPollingWhenHiddenOrOffline = ref(false); | ||
const pollingIntervalRef = computed(() => refToRaw(pollingInterval)); | ||
const errorRetryCountRef = computed(() => refToRaw(errorRetryCount)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const isKeepPolling = () => { | ||
return (// pollingWhenHidden = true or pollingWhenHidden = false and document is visibility | ||
(pollingWhenHidden || isDocumentVisibility()) && ( // pollingWhenOffline = true or pollingWhenOffline = false and is online | ||
pollingWhenOffline || isOnline()) | ||
); | ||
}; | ||
const polling = pollingFunc => { | ||
// if errorRetry is enabled, then skip this method | ||
if (queryInstance.error.value && errorRetryCountRef.value !== 0) return; | ||
let timerId; | ||
if (!isNil(pollingIntervalRef.value) && pollingIntervalRef.value >= 0) { | ||
if (isKeepPolling()) { | ||
timerId = setTimeout(pollingFunc, pollingIntervalRef.value); | ||
} else { | ||
// stop polling | ||
stopPollingWhenHiddenOrOffline.value = true; | ||
return; | ||
} | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
const rePolling = () => { | ||
if (stopPollingWhenHiddenOrOffline.value && isKeepPolling()) { | ||
queryInstance.context.refresh(); | ||
stopPollingWhenHiddenOrOffline.value = false; | ||
} | ||
}; | ||
watch(pollingIntervalRef, () => { | ||
if (pollingTimer.value) { | ||
pollingTimer.value(); | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}); // subscribe polling | ||
if (!pollingWhenHidden) { | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', rePolling)); | ||
} // subscribe online when pollingWhenOffline is false | ||
if (!pollingWhenOffline) { | ||
addUnsubscribeList(subscriber('RECONNECT_LISTENER', rePolling)); | ||
} | ||
onUnmounted(() => { | ||
unsubscribeList.forEach(unsubscribe => unsubscribe()); | ||
}); | ||
return { | ||
onBefore() { | ||
var _pollingTimer$value; | ||
(_pollingTimer$value = pollingTimer.value) === null || _pollingTimer$value === void 0 ? void 0 : _pollingTimer$value.call(pollingTimer); | ||
}, | ||
onCancel() { | ||
var _pollingTimer$value2; | ||
(_pollingTimer$value2 = pollingTimer.value) === null || _pollingTimer$value2 === void 0 ? void 0 : _pollingTimer$value2.call(pollingTimer); | ||
}, | ||
onAfter() { | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}; | ||
}); | ||
var useReadyPlugin = definePlugin((queryInstance, { | ||
@@ -773,8 +475,6 @@ ready = ref(true), | ||
watch(refreshDeps, () => { | ||
if (manual) return; | ||
if (refreshDepsAction) { | ||
refreshDepsAction(); | ||
} else { | ||
queryInstance.context.refresh(); | ||
!manual && queryInstance.context.refresh(); | ||
} | ||
@@ -787,45 +487,2 @@ }); | ||
const limitTrigger = (fn, timeInterval) => { | ||
let running = false; | ||
return (...args) => { | ||
if (running) return; | ||
running = true; | ||
fn(...args); | ||
setTimeout(() => { | ||
running = false; | ||
}, timeInterval); | ||
}; | ||
}; | ||
var useRefreshOnWindowFocus = definePlugin((queryInstance, { | ||
refreshOnWindowFocus = false, | ||
refocusTimespan = 5000 | ||
}) => { | ||
const refreshOnWindowFocusRef = computed(() => refToRaw(refreshOnWindowFocus)); | ||
const refocusTimespanRef = computed(() => refToRaw(refocusTimespan)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const unsubscribe = () => { | ||
unsubscribeList.forEach(fn => fn()); | ||
}; | ||
watchEffect(() => { | ||
unsubscribe(); | ||
if (refreshOnWindowFocusRef.value) { | ||
const limitRefresh = limitTrigger(queryInstance.context.refresh, refocusTimespanRef.value); | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', limitRefresh)); | ||
addUnsubscribeList(subscriber('FOCUS_LISTENER', limitRefresh)); | ||
} | ||
}); | ||
onUnmounted(() => { | ||
unsubscribe(); | ||
}); | ||
return {}; | ||
}); | ||
var useThrottlePlugin = definePlugin((queryInstance, { | ||
@@ -919,3 +576,3 @@ throttleInterval, | ||
isBreak, | ||
breakResult = resolvedPromise | ||
breakResult = resolvedPromise() | ||
} = emit('onBefore', args); | ||
@@ -935,3 +592,3 @@ if (isBreak) return breakResult; | ||
const res = await servicePromise; | ||
if (currentCount !== count.value) return resolvedPromise; | ||
if (currentCount !== count.value) return resolvedPromise(); | ||
setState({ | ||
@@ -948,3 +605,3 @@ data: res, | ||
} catch (error) { | ||
if (currentCount !== count.value) return resolvedPromise; | ||
if (currentCount !== count.value) return resolvedPromise(); | ||
setState({ | ||
@@ -979,7 +636,7 @@ loading: false, | ||
context.refresh = () => { | ||
context.run(...params.value); | ||
context.run(...(params.value || [])); | ||
}; | ||
context.refreshAsync = () => { | ||
return context.runAsync(...params.value); | ||
return context.runAsync(...(params.value || [])); | ||
}; | ||
@@ -989,6 +646,9 @@ | ||
const mutateData = isFunction(x) ? x(data.value) : x; | ||
const _mutateData = isObject(mutateData) ? Object.assign({}, mutateData) : mutateData; | ||
setState({ | ||
data: mutateData | ||
data: _mutateData | ||
}); | ||
emit('onMutate', mutateData); | ||
emit('onMutate', _mutateData); | ||
}; | ||
@@ -1041,132 +701,517 @@ | ||
function useRequest(service, options) { | ||
return useQuery(service, options, [useLoadingDelayPlugin, useErrorRetryPlugin, useDebouncePlugin, usePollingPlugin, useThrottlePlugin, useRefreshOnWindowFocus, useRefreshDepsPlugin, useReadyPlugin, useCachePlugin]); | ||
} | ||
function useLoadMore(service, options) { | ||
var _injectedGlobalOption; | ||
const injectedGlobalOptions = inject(GLOBAL_OPTIONS_PROVIDE_KEY, {}); | ||
const { | ||
isNoMore, | ||
listKey = 'list', | ||
...restOptions | ||
} = Object.assign({ | ||
listKey: (_injectedGlobalOption = injectedGlobalOptions.listKey) !== null && _injectedGlobalOption !== void 0 ? _injectedGlobalOption : getGlobalOptions().listKey | ||
}, options !== null && options !== void 0 ? options : {}); | ||
const refreshing = ref(false); | ||
} = options !== null && options !== void 0 ? options : {}; | ||
const data = shallowRef(); | ||
const dataList = computed(() => { | ||
var _data$value; | ||
return ((_data$value = data.value) === null || _data$value === void 0 ? void 0 : _data$value.list) || []; | ||
}); | ||
const loadingMore = ref(false); | ||
const reloading = ref(false); | ||
const dataList = ref([]); | ||
const isTriggerByLoadMore = ref(false); | ||
const count = ref(0); | ||
const { | ||
data, | ||
params, | ||
runAsync, | ||
run, | ||
cancel: _cancel, | ||
...rest // @ts-ignore | ||
...rest | ||
} = useQuery(async lastData => { | ||
const currentCount = count.value; | ||
const currentData = await service(lastData); | ||
} = useRequest(service, { ...restOptions, | ||
onSuccess: (...p) => { | ||
var _restOptions$onSucces; | ||
if (currentCount === count.value) { | ||
if (lastData) { | ||
data.value = { ...currentData, | ||
list: [...lastData.list, ...currentData.list] | ||
}; | ||
} else { | ||
data.value = currentData; | ||
} | ||
} | ||
if (refreshing.value) { | ||
dataList.value = []; | ||
return currentData; | ||
}, { ...restOptions, | ||
defaultParams: [], | ||
refreshDepsAction: () => { | ||
if (restOptions !== null && restOptions !== void 0 && restOptions.refreshDepsAction) { | ||
restOptions.refreshDepsAction(); | ||
} else { | ||
refresh(); | ||
} | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
reloading.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onSucces = restOptions.onSuccess) === null || _restOptions$onSucces === void 0 ? void 0 : _restOptions$onSucces.call(restOptions, ...p); | ||
}, | ||
onError: (...p) => { | ||
onError: error => { | ||
var _restOptions$onError; | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
reloading.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onError = restOptions.onError) === null || _restOptions$onError === void 0 ? void 0 : _restOptions$onError.call(restOptions, ...p); | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onError = restOptions.onError) === null || _restOptions$onError === void 0 ? void 0 : _restOptions$onError.call(restOptions, error); | ||
}, | ||
onAfter: (...p) => { | ||
onSuccess: data => { | ||
var _restOptions$onSucces; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onSucces = restOptions.onSuccess) === null || _restOptions$onSucces === void 0 ? void 0 : _restOptions$onSucces.call(restOptions, data); | ||
}, | ||
onBefore: () => { | ||
var _restOptions$onBefore; | ||
count.value += 1; | ||
if (isTriggerByLoadMore.value) { | ||
isTriggerByLoadMore.value = false; | ||
loadingMore.value = true; | ||
} | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onBefore = restOptions.onBefore) === null || _restOptions$onBefore === void 0 ? void 0 : _restOptions$onBefore.call(restOptions); | ||
}, | ||
onAfter: () => { | ||
var _restOptions$onAfter; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onAfter = restOptions.onAfter) === null || _restOptions$onAfter === void 0 ? void 0 : _restOptions$onAfter.call(restOptions, ...p); | ||
loadingMore.value = false; | ||
isTriggerByLoadMore.value = false; | ||
restOptions === null || restOptions === void 0 ? void 0 : (_restOptions$onAfter = restOptions.onAfter) === null || _restOptions$onAfter === void 0 ? void 0 : _restOptions$onAfter.call(restOptions); | ||
} | ||
}); | ||
}, [useErrorRetryPlugin, useDebouncePlugin, useThrottlePlugin, useRefreshDepsPlugin, useReadyPlugin]); | ||
const noMore = computed(() => { | ||
return isNoMore && isFunction(isNoMore) ? isNoMore(data.value) : false; | ||
}); | ||
watch(data, value => { | ||
if (value) { | ||
const list = get(value, listKey); | ||
if (list && Array.isArray(list)) { | ||
dataList.value = [...dataList.value, ...list]; | ||
} | ||
} | ||
}); | ||
const loadMore = () => { | ||
loadMoreAsync().catch(() => {}); | ||
}; | ||
const loadMore = () => { | ||
const loadMoreAsync = () => { | ||
if (noMore.value) { | ||
return; | ||
return Promise.reject(warning('No more data. You need to ignore this error by checking if `noMore` is false before calling `loadMoreAsync`', true)); | ||
} | ||
loadingMore.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [{ | ||
dataList: dataList.value, | ||
data: data.value | ||
}, ...restParams]; | ||
run(...mergerParams); | ||
isTriggerByLoadMore.value = true; | ||
return runAsync(data.value); | ||
}; | ||
const refreshAsync = async () => { | ||
refreshing.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
await runAsync(...mergerParams); | ||
}; | ||
const refresh = () => run(); | ||
const refresh = () => { | ||
refreshing.value = true; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
runAsync(...mergerParams); | ||
}; | ||
const refreshAsync = () => runAsync(); | ||
const reload = () => { | ||
reloading.value = true; | ||
cancel(); | ||
dataList.value = []; | ||
const [, ...restParams] = params.value; | ||
const mergerParams = [undefined, ...restParams]; | ||
run(...mergerParams); | ||
}; | ||
const cancel = () => { | ||
count.value += 1; | ||
const cancel = () => { | ||
_cancel(); | ||
loadingMore.value = false; | ||
refreshing.value = false; | ||
}; | ||
const mutate = x => { | ||
const mutateData = isFunction(x) ? x(data.value) : x; | ||
const _mutateData = isObject(mutateData) ? Object.assign({}, mutateData) : mutateData; | ||
data.value = _mutateData; | ||
}; | ||
return { | ||
data, | ||
dataList, | ||
params, | ||
loadingMore, | ||
noMore, | ||
loadingMore, | ||
refreshing, | ||
reloading, | ||
runAsync, | ||
reload, | ||
loadMore, | ||
cancel, | ||
mutate, | ||
refresh, | ||
cancel, | ||
run, | ||
refreshAsync, | ||
...omit(rest, ['refresh', 'refreshAsync']) | ||
loadMore, | ||
loadMoreAsync, | ||
...omit(rest, ['refresh', 'refreshAsync', 'mutate', 'params', 'data']) | ||
}; | ||
} | ||
const cacheQuery = new Map(); | ||
const setCacheQuery = (cacheKey, query) => { | ||
cacheQuery.set(cacheKey, query); | ||
query.then(res => { | ||
cacheQuery.delete(cacheKey); | ||
return res; | ||
}).catch(() => { | ||
cacheQuery.delete(cacheKey); | ||
}); | ||
}; | ||
const getCacheQuery = cacheKey => { | ||
return cacheQuery.get(cacheKey); | ||
}; | ||
const listeners = new Map(); | ||
const trigger = (key, data) => { | ||
if (listeners.has(key)) { | ||
listeners.get(key).forEach(item => item(data)); | ||
} | ||
}; | ||
const subscribe = (key, listener) => { | ||
if (!listeners.has(key)) { | ||
listeners.set(key, [listener]); | ||
} else { | ||
listeners.get(key).push(listener); | ||
} | ||
return () => { | ||
const index = listeners.get(key).indexOf(listener); | ||
listeners.get(key).splice(index, 1); | ||
}; | ||
}; | ||
var useCachePlugin = definePlugin((queryInstance, { | ||
cacheKey: customCacheKey, | ||
cacheTime = 600000, | ||
staleTime = 0, | ||
getCache: customGetCache, | ||
setCache: customSetCache | ||
}) => { | ||
if (!customCacheKey) return {}; | ||
const cacheKey = isFunction(customCacheKey) ? customCacheKey : () => customCacheKey; | ||
const unSubscribe = ref(() => {}); | ||
let currentQuery; | ||
const _getCache = key => { | ||
if (customGetCache) { | ||
return customGetCache(key); | ||
} else { | ||
return getCache(key); | ||
} | ||
}; | ||
const _setCache = (key, time, cacheData) => { | ||
if (customSetCache) { | ||
customSetCache(key, cacheData); | ||
} else { | ||
setCache(key, time, cacheData); | ||
} | ||
trigger(key, cacheData.data); | ||
}; | ||
const isFresh = time => staleTime === -1 || time + staleTime > new Date().getTime(); // Returns a boolean indicating whether the object has the specified property as its own property | ||
// (as opposed to inheriting it) | ||
const hasProp = (object, prop) => Object.prototype.hasOwnProperty.call(object, prop); | ||
const subscribeCache = params => { | ||
const _cacheKey = cacheKey(params); | ||
return subscribe(_cacheKey, data => { | ||
queryInstance.data.value = data; | ||
}); | ||
}; // When initializing, restore if there is a cache | ||
const _cacheKey = cacheKey(); | ||
const cache = _getCache(_cacheKey); | ||
if (cache && hasProp(cache, 'data')) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.params.value = cache.params; | ||
} | ||
if (_cacheKey) { | ||
unSubscribe.value = subscribeCache(); | ||
} | ||
onUnmounted(() => { | ||
unSubscribe.value(); | ||
}); | ||
return { | ||
onBefore(params) { | ||
const _cacheKey = cacheKey(params); | ||
const cache = _getCache(_cacheKey); | ||
if (!cache || !hasProp(cache, 'data')) { | ||
return {}; | ||
} // If it's fresh, stop the request | ||
if (isFresh(cache.time)) { | ||
queryInstance.data.value = cache.data; | ||
queryInstance.loading.value = false; | ||
return { | ||
isBreak: true, | ||
breakResult: cache.data | ||
}; | ||
} else { | ||
// If it is not fresh, set data and request | ||
queryInstance.data.value = cache.data; | ||
} | ||
}, | ||
onQuery(service, params) { | ||
const _cacheKey = cacheKey(params); | ||
let servicePromise = getCacheQuery(_cacheKey); | ||
if (servicePromise && servicePromise !== currentQuery) { | ||
return { | ||
servicePromise | ||
}; | ||
} | ||
servicePromise = service(...params); | ||
currentQuery = servicePromise; | ||
setCacheQuery(_cacheKey, servicePromise); | ||
return { | ||
servicePromise | ||
}; | ||
}, | ||
onSuccess(data, params) { | ||
const _cacheKey = cacheKey(params); | ||
if (_cacheKey) { | ||
unSubscribe.value(); | ||
_setCache(_cacheKey, cacheTime, { | ||
data, | ||
params, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(params); | ||
} | ||
}, | ||
onMutate(data) { | ||
const _cacheKey = cacheKey(queryInstance.params.value); | ||
if (_cacheKey) { | ||
unSubscribe.value(); | ||
_setCache(_cacheKey, cacheTime, { | ||
data, | ||
params: queryInstance.params.value, | ||
time: new Date().getTime() | ||
}); | ||
unSubscribe.value = subscribeCache(queryInstance.params.value); | ||
} | ||
} | ||
}; | ||
}); | ||
var useLoadingDelayPlugin = definePlugin((queryInstance, { | ||
loadingDelay = 0 | ||
}) => { | ||
const delayLoadingTimer = ref(() => {}); | ||
const loadingDelayRef = computed(() => refToRaw(loadingDelay)); | ||
const delayLoading = () => { | ||
let timerId; | ||
if (loadingDelayRef.value) { | ||
timerId = setTimeout(() => { | ||
queryInstance.loading.value = true; | ||
}, loadingDelayRef.value); | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
return { | ||
onBefore() { | ||
queryInstance.loading.value = !loadingDelayRef.value; | ||
delayLoadingTimer.value(); | ||
delayLoadingTimer.value = delayLoading(); | ||
}, | ||
onCancel() { | ||
delayLoadingTimer.value(); | ||
}, | ||
onAfter() { | ||
delayLoadingTimer.value(); | ||
} | ||
}; | ||
}); | ||
var _window; | ||
const FOCUS_LISTENER = new Set(); | ||
const VISIBLE_LISTENER = new Set(); | ||
const RECONNECT_LISTENER = new Set(); | ||
const subscriber = (listenerType, event) => { | ||
let listeners; | ||
switch (listenerType) { | ||
case 'FOCUS_LISTENER': | ||
listeners = FOCUS_LISTENER; | ||
break; | ||
case 'RECONNECT_LISTENER': | ||
listeners = RECONNECT_LISTENER; | ||
break; | ||
case 'VISIBLE_LISTENER': | ||
listeners = VISIBLE_LISTENER; | ||
break; | ||
} | ||
if (listeners.has(event)) return; | ||
listeners.add(event); | ||
return () => { | ||
listeners.delete(event); | ||
}; | ||
}; | ||
const observer = listeners => { | ||
listeners.forEach(event => { | ||
event(); | ||
}); | ||
}; | ||
/* istanbul ignore else */ | ||
if (!isServer && (_window = window) !== null && _window !== void 0 && _window.addEventListener) { | ||
window.addEventListener('visibilitychange', () => { | ||
/* istanbul ignore else */ | ||
if (isDocumentVisibility()) { | ||
observer(VISIBLE_LISTENER); | ||
} | ||
}, false); | ||
window.addEventListener('focus', () => observer(FOCUS_LISTENER), false); | ||
window.addEventListener('online', () => observer(RECONNECT_LISTENER), false); | ||
} | ||
var usePollingPlugin = definePlugin((queryInstance, { | ||
pollingInterval, | ||
pollingWhenHidden = false, | ||
pollingWhenOffline = false, | ||
errorRetryCount = 0 | ||
}) => { | ||
const pollingTimer = ref(); | ||
const stopPollingWhenHiddenOrOffline = ref(false); | ||
const pollingIntervalRef = computed(() => refToRaw(pollingInterval)); | ||
const errorRetryCountRef = computed(() => refToRaw(errorRetryCount)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const isKeepPolling = () => { | ||
return (// pollingWhenHidden = true or pollingWhenHidden = false and document is visibility | ||
(pollingWhenHidden || isDocumentVisibility()) && ( // pollingWhenOffline = true or pollingWhenOffline = false and is online | ||
pollingWhenOffline || isOnline()) | ||
); | ||
}; | ||
const polling = pollingFunc => { | ||
// if errorRetry is enabled, then skip this method | ||
if (queryInstance.error.value && errorRetryCountRef.value !== 0) return; | ||
let timerId; | ||
if (!isNil(pollingIntervalRef.value) && pollingIntervalRef.value >= 0) { | ||
if (isKeepPolling()) { | ||
timerId = setTimeout(pollingFunc, pollingIntervalRef.value); | ||
} else { | ||
// stop polling | ||
stopPollingWhenHiddenOrOffline.value = true; | ||
return; | ||
} | ||
} | ||
return () => timerId && clearTimeout(timerId); | ||
}; | ||
const rePolling = () => { | ||
if (stopPollingWhenHiddenOrOffline.value && isKeepPolling()) { | ||
queryInstance.context.refresh(); | ||
stopPollingWhenHiddenOrOffline.value = false; | ||
} | ||
}; | ||
watch(pollingIntervalRef, () => { | ||
if (pollingTimer.value) { | ||
pollingTimer.value(); | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}); // subscribe polling | ||
if (!pollingWhenHidden) { | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', rePolling)); | ||
} // subscribe online when pollingWhenOffline is false | ||
if (!pollingWhenOffline) { | ||
addUnsubscribeList(subscriber('RECONNECT_LISTENER', rePolling)); | ||
} | ||
onUnmounted(() => { | ||
unsubscribeList.forEach(unsubscribe => unsubscribe()); | ||
}); | ||
return { | ||
onBefore() { | ||
var _pollingTimer$value; | ||
(_pollingTimer$value = pollingTimer.value) === null || _pollingTimer$value === void 0 ? void 0 : _pollingTimer$value.call(pollingTimer); | ||
}, | ||
onCancel() { | ||
var _pollingTimer$value2; | ||
(_pollingTimer$value2 = pollingTimer.value) === null || _pollingTimer$value2 === void 0 ? void 0 : _pollingTimer$value2.call(pollingTimer); | ||
}, | ||
onAfter() { | ||
pollingTimer.value = polling(() => queryInstance.context.refresh()); | ||
} | ||
}; | ||
}); | ||
const limitTrigger = (fn, timeInterval) => { | ||
let running = false; | ||
return (...args) => { | ||
if (running) return; | ||
running = true; | ||
fn(...args); | ||
setTimeout(() => { | ||
running = false; | ||
}, timeInterval); | ||
}; | ||
}; | ||
var useRefreshOnWindowFocus = definePlugin((queryInstance, { | ||
refreshOnWindowFocus = false, | ||
refocusTimespan = 5000 | ||
}) => { | ||
const refreshOnWindowFocusRef = computed(() => refToRaw(refreshOnWindowFocus)); | ||
const refocusTimespanRef = computed(() => refToRaw(refocusTimespan)); | ||
const unsubscribeList = []; | ||
const addUnsubscribeList = event => { | ||
event && unsubscribeList.push(event); | ||
}; | ||
const unsubscribe = () => { | ||
unsubscribeList.forEach(fn => fn()); | ||
}; | ||
watchEffect(() => { | ||
unsubscribe(); | ||
if (refreshOnWindowFocusRef.value) { | ||
const limitRefresh = limitTrigger(queryInstance.context.refresh, refocusTimespanRef.value); | ||
addUnsubscribeList(subscriber('VISIBLE_LISTENER', limitRefresh)); | ||
addUnsubscribeList(subscriber('FOCUS_LISTENER', limitRefresh)); | ||
} | ||
}); | ||
onUnmounted(() => { | ||
unsubscribe(); | ||
}); | ||
return {}; | ||
}); | ||
function useRequest(service, options) { | ||
return useQuery(service, options, [useLoadingDelayPlugin, useErrorRetryPlugin, useDebouncePlugin, usePollingPlugin, useThrottlePlugin, useRefreshOnWindowFocus, useRefreshDepsPlugin, useReadyPlugin, useCachePlugin]); | ||
} | ||
function usePagination(service, options = {}) { | ||
@@ -1279,2 +1324,2 @@ const defaultPaginationOptions = { | ||
export { setGlobalOptions, useLoadMore, usePagination, useRequest, useRequestProvider }; | ||
export { clearCache, setGlobalOptions, useLoadMore, usePagination, useRequest, useRequestProvider }; |
@@ -1,25 +0,3 @@ | ||
import { Ref, ComputedRef, WritableComputedRef, WatchSource } from 'vue-demi'; | ||
import { WritableComputedRef, ComputedRef, Ref, WatchSource } from 'vue-demi'; | ||
declare type LoadMoreExtendsOption = { | ||
listKey?: string; | ||
}; | ||
declare type LoadMoreGenericExtendsOption<R> = { | ||
isNoMore?: (data: R | undefined) => boolean; | ||
}; | ||
declare type LoadMoreService<R, P extends unknown[], LR> = (r: { | ||
data: R; | ||
dataList: LR; | ||
}, ...args: P) => Promise<R>; | ||
declare type LoadMoreBaseOptions<R, P extends unknown[]> = Options<R, P> & LoadMoreGenericExtendsOption<R> & LoadMoreExtendsOption; | ||
interface LoadMoreQueryResult<R, P extends unknown[], LR extends unknown[] = any[]> extends QueryResult<R, P> { | ||
dataList: Ref<LR>; | ||
noMore: ComputedRef<number>; | ||
loadingMore: Ref<boolean>; | ||
refreshing: Ref<boolean>; | ||
reloading: Ref<boolean>; | ||
reload: () => void; | ||
loadMore: () => void; | ||
} | ||
declare function useLoadMore<R, P extends unknown[] = any, LR extends unknown[] = any[]>(service: LoadMoreService<R, P, LR>, options?: LoadMoreBaseOptions<R, P>): LoadMoreQueryResult<R, P>; | ||
interface PaginationType { | ||
@@ -52,2 +30,3 @@ currentKey: string; | ||
}; | ||
declare const clearCache: (cacheKey?: string | undefined) => void; | ||
@@ -66,7 +45,7 @@ declare type MutateData<R> = (newData: R) => void; | ||
interface FunctionContext<R, P extends unknown[]> { | ||
runAsync: (...arg: P) => Promise<R | null | void>; | ||
runAsync: (...arg: P) => Promise<R>; | ||
run: (...arg: P) => void; | ||
cancel: () => void; | ||
refresh: () => void; | ||
refreshAsync: () => Promise<R | null | void>; | ||
refreshAsync: () => Promise<R>; | ||
mutate: Mutate<R>; | ||
@@ -82,3 +61,3 @@ } | ||
declare type ThrottleOptions = Omit<DebounceOptions, 'maxWait'>; | ||
declare type GlobalOptions = BaseOptions & PaginationExtendsOption & LoadMoreExtendsOption; | ||
declare type GlobalOptions = BaseOptions & PaginationExtendsOption; | ||
declare type BaseOptions = { | ||
@@ -108,3 +87,3 @@ loadingDelay?: number | Ref<number>; | ||
refreshDeps?: WatchSource<any>[]; | ||
cacheKey?: string; | ||
cacheKey?: string | ((params?: P) => string); | ||
refreshDepsAction?: () => void; | ||
@@ -119,2 +98,23 @@ onSuccess?: (data: R, params: P) => void; | ||
declare type DataType = { | ||
list: any[]; | ||
[key: string]: any; | ||
}; | ||
declare type LoadMoreService<R extends DataType> = (data?: R) => Promise<R>; | ||
declare type LoadMoreBaseOptions<R> = Pick<Options<R, any>, 'ready' | 'manual' | 'refreshDeps' | 'refreshDepsAction' | 'debounceInterval' | 'debounceOptions' | 'throttleInterval' | 'throttleOptions' | 'errorRetryCount' | 'errorRetryInterval'> & { | ||
isNoMore?: (data?: R) => boolean; | ||
onBefore?: () => void; | ||
onAfter?: () => void; | ||
onSuccess?: (data: R) => void; | ||
onError?: (error: Error) => void; | ||
}; | ||
declare type LoadMoreQueryResult<R extends DataType> = Pick<QueryResult<R, any>, 'data' | 'loading' | 'error' | 'refresh' | 'refreshAsync' | 'cancel' | 'mutate'> & { | ||
dataList: ComputedRef<R['list']>; | ||
noMore: ComputedRef<boolean>; | ||
loadingMore: Ref<boolean>; | ||
loadMore: () => void; | ||
loadMoreAsync: () => Promise<R>; | ||
}; | ||
declare function useLoadMore<R extends DataType>(service: LoadMoreService<R>, options?: LoadMoreBaseOptions<R>): LoadMoreQueryResult<R>; | ||
declare function useRequest<R, P extends unknown[] = any>(service: Service<R, P>, options?: Options<R, P>): QueryResult<R, P>; | ||
@@ -124,2 +124,2 @@ | ||
export { setGlobalOptions, useLoadMore, usePagination, useRequest, _default as useRequestProvider }; | ||
export { Options, clearCache, setGlobalOptions, useLoadMore, usePagination, useRequest, _default as useRequestProvider }; |
@@ -1,1 +0,1 @@ | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("vue-demi")):"function"==typeof define&&define.amd?define(["exports","vue-demi"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).VueRequest=e.VueRequest||{},e.vueDemi)}(this,(function(e,n){"use strict";const t={},a=Symbol("GLOBAL_OPTIONS_PROVIDE_KEY"),r=()=>t,o=Object.prototype.toString,u=e=>"[object Object]"===(e=>o.call(e))(e),l=e=>null!==e&&"object"==typeof e,i=e=>e instanceof Function,c=e=>null==e,s="undefined"==typeof window,v=()=>{var e;return!s&&"visible"===(null===(e=window.document)||void 0===e?void 0:e.visibilityState)},d=Promise.resolve(null),f=(e,n,t)=>{const a=n.replace(/\[(\d+)\]/g,".$1").split(".");let r=e;for(const e of a)if(r=Object(r)[e],void 0===r)return t;return r};function m(e,n){const t=Object.assign({},e);for(const e of n)delete t[e];return t}const p=e=>n.isRef(e)?e.value:e,h=new Map,g=new Map,y=new Map;var w=(e,{cacheKey:t,cacheTime:a=6e5,staleTime:r=0,getCache:o,setCache:u})=>{if(!t)return{};const l=n.ref();let i;const s=e=>o?o(e):(e=>{if(c(e))return;return h.get(e)})(e),v=(e,n,t)=>{u?u(e,t):((e,n,t)=>{const a=h.get(e);null!=a&&a.timer&&clearTimeout(a.timer);const r=setTimeout((()=>h.delete(e)),n);h.set(e,{...t,timer:r})})(e,n,t),((e,n)=>{y.has(e)&&y.get(e).forEach((e=>e(n)))})(e,t.data)},d=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),f=()=>{return n=t,a=n=>{e.data.value=n},y.has(n)?y.get(n).push(a):y.set(n,[a]),()=>{const e=y.get(n).indexOf(a);y.get(n).splice(e,1)};var n,a},m=s(t);return m&&d(m,"data")&&(e.data.value=m.data,e.params.value=m.params),l.value=f(),n.onUnmounted((()=>{l.value()})),{onBefore(){const n=s(t);return n&&d(n,"data")?(a=n.time,-1===r||a+r>(new Date).getTime()?(e.data.value=n.data,e.loading.value=!1,{isBreak:!0,breakResult:n.data}):void(e.data.value=n.data)):{};var a},onQuery(e,n){let a=(e=>g.get(e))(t);return a&&a!==i||(a=e(...n),i=a,((e,n)=>{g.set(e,n),n.then((n=>(g.delete(e),n))).catch((()=>{g.delete(e)}))})(t,a)),{servicePromise:a}},onSuccess(e,n){l.value(),v(t,a,{data:e,params:n,time:(new Date).getTime()}),l.value=f()},onMutate(n){l.value(),v(t,a,{data:n,params:e.params.value,time:(new Date).getTime()}),l.value=f()}}};function E(e,n,t){let a,r,o,u,i,c,s=0,v=!1,d=!1,f=!0;const m=!n&&0!==n&&"function"==typeof window.requestAnimationFrame;if("function"!=typeof e)throw new TypeError("Expected a function");function p(n){const t=a,o=r;return a=r=void 0,s=n,u=e.apply(o,t),u}function h(e,n){return m?(window.cancelAnimationFrame(i),window.requestAnimationFrame(e)):setTimeout(e,n)}function g(e){const t=e-c;return void 0===c||t>=n||t<0||d&&e-s>=o}function y(){const e=Date.now();if(g(e))return w(e);i=h(y,function(e){const t=e-s,a=n-(e-c);return d?Math.min(a,o-t):a}(e))}function w(e){return i=void 0,f&&a?p(e):(a=r=void 0,u)}function E(...e){const t=Date.now(),o=g(t);if(a=e,r=this,c=t,o){if(void 0===i)return function(e){return s=e,i=h(y,n),v?p(e):u}(c);if(d)return i=h(y,n),p(c)}return void 0===i&&(i=h(y,n)),u}return n=+n||0,l(t)&&(v=!!t.leading,d="maxWait"in t,o=d?Math.max(+t.maxWait||0,n):o,f="trailing"in t?!!t.trailing:f),E.cancel=function(){void 0!==i&&function(e){if(m)return window.cancelAnimationFrame(e);clearTimeout(e)}(i),s=0,a=c=r=i=void 0},E.flush=function(){return void 0===i?u:w(Date.now())},E.pending=function(){return void 0!==i},E}function A(e,n){for(const a in n)void 0!==n[a]&&(l(n[a])&&l(e[a])&&a in e?(u(n[a])||(t=n[a],Array.isArray(t)))&&A(e[a],n[a]):e[a]=n[a]);var t}function x(e,...n){const t=Object.assign({},e);if(!n.length)return t;for(const e of n)A(t,e);return t}var T,S=(e,{debounceInterval:t,debounceOptions:a,manual:r})=>{const o=n.ref(!1),u=n.ref(),l=n.computed((()=>a)),i=n.computed((()=>p(t))),s=n.ref(e.context.runAsync);return r||(o.value=!0),n.watchEffect((n=>{c(i.value)||(u.value=E((e=>e()),i.value,l.value),e.context.runAsync=(...e)=>new Promise(((n,t)=>{o.value?(o.value=!1,s.value(...e).then(n).catch(t)):u.value((()=>{s.value(...e).then(n).catch(t)}))})),n((()=>{var n;null===(n=u.value)||void 0===n||n.cancel(),e.context.runAsync=s.value})))})),{onCancel(){var e;null===(e=u.value)||void 0===e||e.cancel()}}},b=(e,{errorRetryCount:t=0,errorRetryInterval:a=0})=>{const r=n.ref(),o=n.ref(0),u=n.computed((()=>p(t))),l=n.computed((()=>p(a)));let i=!1;const c=()=>{o.value=0},s=n.computed((()=>{if(l.value)return l.value;return 1e3*Math.floor(Math.random()*2**Math.min(o.value,9)+1)})),v=()=>{r.value&&r.value()};return{onBefore(){i||c(),i=!1,v()},onSuccess(){c()},onError(){r.value=(()=>{let n;const t=-1===u.value,a=o.value<u.value;return(t||a)&&(t||(o.value+=1),n=setTimeout((()=>{i=!0,e.context.refresh()}),s.value)),()=>n&&clearTimeout(n)})()},onCancel(){c(),v()}}},O=(e,{loadingDelay:t=0})=>{const a=n.ref((()=>{})),r=n.computed((()=>p(t)));return{onBefore(){e.loading.value=!r.value,a.value(),a.value=(()=>{let n;return r.value&&(n=setTimeout((()=>{e.loading.value=!0}),r.value)),()=>n&&clearTimeout(n)})()},onCancel(){a.value()},onAfter(){a.value()}}};const P=new Set,R=new Set,L=new Set,I=(e,n)=>{let t;switch(e){case"FOCUS_LISTENER":t=P;break;case"RECONNECT_LISTENER":t=L;break;case"VISIBLE_LISTENER":t=R}if(!t.has(n))return t.add(n),()=>{t.delete(n)}},j=e=>{e.forEach((e=>{e()}))};!s&&null!==(T=window)&&void 0!==T&&T.addEventListener&&(window.addEventListener("visibilitychange",(()=>{v()&&j(R)}),!1),window.addEventListener("focus",(()=>j(P)),!1),window.addEventListener("online",(()=>j(L)),!1));var C=(e,{pollingInterval:t,pollingWhenHidden:a=!1,pollingWhenOffline:r=!1,errorRetryCount:o=0})=>{const u=n.ref(),l=n.ref(!1),i=n.computed((()=>p(t))),d=n.computed((()=>p(o))),f=[],m=e=>{e&&f.push(e)},h=()=>{return(a||v())&&(r||null===(e=!s&&(null===(n=window.navigator)||void 0===n?void 0:n.onLine))||void 0===e||e);var e,n},g=n=>{if(e.error.value&&0!==d.value)return;let t;if(!c(i.value)&&i.value>=0){if(!h())return void(l.value=!0);t=setTimeout(n,i.value)}return()=>t&&clearTimeout(t)},y=()=>{l.value&&h()&&(e.context.refresh(),l.value=!1)};return n.watch(i,(()=>{u.value&&(u.value(),u.value=g((()=>e.context.refresh())))})),a||m(I("VISIBLE_LISTENER",y)),r||m(I("RECONNECT_LISTENER",y)),n.onUnmounted((()=>{f.forEach((e=>e()))})),{onBefore(){var e;null===(e=u.value)||void 0===e||e.call(u)},onCancel(){var e;null===(e=u.value)||void 0===e||e.call(u)},onAfter(){u.value=g((()=>e.context.refresh()))}}},M=(e,{ready:t=n.ref(!0),manual:a,defaultParams:r=[]})=>(n.watch(t,(n=>{!a&&n&&e.context.run(...r)}),{flush:"sync"}),{onBefore(){if(!t.value)return e.loading.value=!1,{isBreak:!0}}}),B=(e,{refreshDeps:t=[],refreshDepsAction:a,manual:r})=>(null!=t&&t.length&&n.watch(t,(()=>{r||(a?a():e.context.refresh())})),{});var K=(e,{refreshOnWindowFocus:t=!1,refocusTimespan:a=5e3})=>{const r=n.computed((()=>p(t))),o=n.computed((()=>p(a))),u=[],l=e=>{e&&u.push(e)},i=()=>{u.forEach((e=>e()))};return n.watchEffect((()=>{if(i(),r.value){const n=((e,n)=>{let t=!1;return(...a)=>{t||(t=!0,e(...a),setTimeout((()=>{t=!1}),n))}})(e.context.refresh,o.value);l(I("VISIBLE_LISTENER",n)),l(I("FOCUS_LISTENER",n))}})),n.onUnmounted((()=>{i()})),{}},N=(e,{throttleInterval:t,throttleOptions:a})=>{const r=n.ref(),o=n.computed((()=>p(t))),u=n.computed((()=>a)),i=n.ref(e.context.runAsync);return n.watchEffect((n=>{if(c(t))return{};r.value=function(e,n,t){let a=!0,r=!0;if("function"!=typeof e)throw new TypeError("Expected a function");return l(t)&&(a="leading"in t?!!t.leading:a,r="trailing"in t?!!t.trailing:r),E(e,n,{leading:a,trailing:r,maxWait:n})}((e=>e()),o.value,u.value),e.context.runAsync=(...e)=>new Promise(((n,t)=>{r.value((()=>{i.value(...e).then(n).catch(t)}))})),n((()=>{var n;null===(n=r.value)||void 0===n||n.cancel(),e.context.runAsync=i.value}))})),{onCancel(){var e;null===(e=r.value)||void 0===e||e.cancel()}}};const D=(e,t,a)=>{var r,o;const{initialData:u,onSuccess:l,onError:c,onBefore:s,onAfter:v}=t,f=n.ref(null!==(r=null==a?void 0:a.loading)&&void 0!==r&&r),m=n.shallowRef(null!==(o=null==a?void 0:a.data)&&void 0!==o?o:u),p=n.shallowRef(null==a?void 0:a.error),h=n.ref(null==a?void 0:a.params),g=n.ref([]),y={},w=(E={loading:f,data:m,error:p,params:h},A=[],e=>{Object.keys(e).forEach((n=>{E[n].value=e[n]})),A.forEach((e=>e(E)))});var E,A;const x=(e,...n)=>{const t=g.value.map((t=>{var a;return null===(a=t[e])||void 0===a?void 0:a.call(t,...n)}));return Object.assign({},...t)},T=n.ref(0);return y.runAsync=async(...n)=>{w({loading:!0,params:n}),T.value+=1;const t=T.value,{isBreak:a,breakResult:r=d}=x("onBefore",n);if(a)return r;null==s||s(n);try{let{servicePromise:a}=x("onQuery",e,h.value);a||(a=e(...h.value));const r=await a;return t!==T.value?d:(w({data:r,loading:!1,error:void 0}),x("onSuccess",r,n),null==l||l(r,n),x("onAfter",n,r,void 0),null==v||v(n),r)}catch(e){if(t!==T.value)return d;throw w({loading:!1,error:e}),x("onError",e,n),null==c||c(e,n),x("onAfter",n,void 0,e),null==v||v(n),e}},y.run=async(...e)=>{y.runAsync(...e).catch((e=>{c||console.error(e)}))},y.cancel=()=>{T.value+=1,w({loading:!1}),x("onCancel")},y.refresh=()=>{y.run(...h.value)},y.refreshAsync=()=>y.runAsync(...h.value),y.mutate=e=>{const n=i(e)?e(m.value):e;w({data:n}),x("onMutate",n)},{loading:f,data:m,error:p,params:h,plugins:g,context:y}};function _(e,t){return function(e,t={},o){const u=n.inject(a,{}),l={...r(),...u,...t},{manual:i=!1,defaultParams:c=[]}=l,s=D(e,l);if(s.plugins.value=o.map((e=>e(s,l))),!i){const e=s.params.value||c;s.context.run(...e)}return n.onUnmounted((()=>{s.context.cancel()})),{loading:s.loading,data:s.data,error:s.error,params:s.params,cancel:s.context.cancel,refresh:s.context.refresh,refreshAsync:s.context.refreshAsync,mutate:s.context.mutate,run:s.context.run,runAsync:s.context.runAsync}}(e,t,[O,b,S,C,N,K,B,M,w])}e.setGlobalOptions=e=>{Object.keys(e).forEach((n=>{t[n]=e[n]}))},e.useLoadMore=function(e,t){var o;const u=n.inject(a,{}),{isNoMore:l,listKey:c="list",...s}=Object.assign({listKey:null!==(o=u.listKey)&&void 0!==o?o:r().listKey},null!=t?t:{}),v=n.ref(!1),d=n.ref(!1),p=n.ref(!1),h=n.ref([]),{data:g,params:y,runAsync:w,run:E,cancel:A,...x}=_(e,{...s,onSuccess:(...e)=>{var n;v.value&&(h.value=[]),d.value=!1,v.value=!1,p.value=!1,null==s||null===(n=s.onSuccess)||void 0===n||n.call(s,...e)},onError:(...e)=>{var n;d.value=!1,v.value=!1,p.value=!1,null==s||null===(n=s.onError)||void 0===n||n.call(s,...e)},onAfter:(...e)=>{var n;null==s||null===(n=s.onAfter)||void 0===n||n.call(s,...e)}}),T=n.computed((()=>!(!l||!i(l))&&l(g.value)));n.watch(g,(e=>{if(e){const n=f(e,c);n&&Array.isArray(n)&&(h.value=[...h.value,...n])}}));const S=()=>{A(),d.value=!1,v.value=!1};return{data:g,dataList:h,params:y,noMore:T,loadingMore:d,refreshing:v,reloading:p,runAsync:w,reload:()=>{p.value=!0,S(),h.value=[];const[,...e]=y.value,n=[void 0,...e];E(...n)},loadMore:()=>{if(T.value)return;d.value=!0;const[,...e]=y.value,n=[{dataList:h.value,data:g.value},...e];E(...n)},refresh:()=>{v.value=!0;const[,...e]=y.value,n=[void 0,...e];w(...n)},cancel:S,run:E,refreshAsync:async()=>{v.value=!0;const[,...e]=y.value,n=[void 0,...e];await w(...n)},...m(x,["refresh","refreshAsync"])}},e.usePagination=function(e,t={}){const o=n.inject(a,{}),{pagination:u,...l}=t,{currentKey:i,pageSizeKey:c,totalKey:s,totalPageKey:v}=x({currentKey:"current",pageSizeKey:"pageSize",totalKey:"total",totalPageKey:"totalPage"},r().pagination||{},o.pagination||{},u||{}),d=x({defaultParams:[{[i]:1,[c]:10}]},l),{data:m,params:p,run:h,...g}=_(e,d),y=e=>{const[n,...t]=p.value||[],a=[{...n,...e},...t];h(...a)},w=e=>{y({[i]:e})},E=e=>{y({[c]:e})},A=n.computed((()=>f(m.value,s,0))),T=n.computed({get:()=>{var e,n;return null!==(e=null===(n=p.value)||void 0===n?void 0:n[0][i])&&void 0!==e?e:d.defaultParams[0][i]},set:e=>{w(e)}}),S=n.computed({get:()=>{var e,n;return null!==(e=null===(n=p.value)||void 0===n?void 0:n[0][c])&&void 0!==e?e:d.defaultParams[0][c]},set:e=>{E(e)}}),b=n.computed((()=>f(m.value,v,Math.ceil(A.value/S.value))));return{data:m,params:p,current:T,pageSize:S,total:A,totalPage:b,run:h,changeCurrent:w,changePageSize:E,changePagination:(e,n)=>{y({[i]:e,[c]:n})},...g}},e.useRequest=_,e.useRequestProvider=e=>{n.provide(a,e)},Object.defineProperty(e,"__esModule",{value:!0})})); | ||
!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports,require("vue-demi")):"function"==typeof define&&define.amd?define(["exports","vue-demi"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).VueRequest=e.VueRequest||{},e.vueDemi)}(this,(function(e,n){"use strict";const t={},a=Symbol("GLOBAL_OPTIONS_PROVIDE_KEY"),r=()=>t,o=Object.prototype.toString,u=e=>"[object Object]"===(e=>o.call(e))(e),l=e=>null!==e&&"object"==typeof e,i=e=>e instanceof Function,c=e=>null==e,s="undefined"==typeof window,v=()=>{var e;return!(!s&&!c(null===(e=window.document)||void 0===e?void 0:e.visibilityState))||"visible"===window.document.visibilityState},d=()=>new Promise((()=>{})),f=(e,n,t)=>{const a=n.replace(/\[(\d+)\]/g,".$1").split(".");let r=e;for(const e of a)if(r=Object(r)[e],void 0===r)return t;return r};function m(e,n){const t=Object.assign({},e);for(const e of n)delete t[e];return t}const p=e=>n.isRef(e)?e.value:e,h=new Map;function g(e,n,t){let a,r,o,u,i,c,s=0,v=!1,d=!1,f=!0;const m=!n&&0!==n&&"function"==typeof window.requestAnimationFrame;if("function"!=typeof e)throw new TypeError("Expected a function");function p(n){const t=a,o=r;return a=r=void 0,s=n,u=e.apply(o,t),u}function h(e,n){return m?(window.cancelAnimationFrame(i),window.requestAnimationFrame(e)):setTimeout(e,n)}function g(e){const t=e-c;return void 0===c||t>=n||t<0||d&&e-s>=o}function y(){const e=Date.now();if(g(e))return w(e);i=h(y,function(e){const t=e-s,a=n-(e-c);return d?Math.min(a,o-t):a}(e))}function w(e){return i=void 0,f&&a?p(e):(a=r=void 0,u)}function E(...e){const t=Date.now(),o=g(t);if(a=e,r=this,c=t,o){if(void 0===i)return function(e){return s=e,i=h(y,n),v?p(e):u}(c);if(d)return i=h(y,n),p(c)}return void 0===i&&(i=h(y,n)),u}return n=+n||0,l(t)&&(v=!!t.leading,d="maxWait"in t,o=d?Math.max(+t.maxWait||0,n):o,f="trailing"in t?!!t.trailing:f),E.cancel=function(){void 0!==i&&function(e){if(m)return window.cancelAnimationFrame(e);clearTimeout(e)}(i),s=0,a=c=r=i=void 0},E.flush=function(){return void 0===i?u:w(Date.now())},E.pending=function(){return void 0!==i},E}function y(e,n){for(const a in n)void 0!==n[a]&&(l(n[a])&&l(e[a])&&a in e?(u(n[a])||(t=n[a],Array.isArray(t)))&&y(e[a],n[a]):e[a]=n[a]);var t}function w(e,...n){const t=Object.assign({},e);if(!n.length)return t;for(const e of n)y(t,e);return t}var E=(e,{debounceInterval:t,debounceOptions:a,manual:r})=>{const o=n.ref(!1),u=n.ref(),l=n.computed((()=>a)),i=n.computed((()=>p(t))),s=n.ref(e.context.runAsync);return r||(o.value=!0),n.watchEffect((n=>{c(i.value)||(u.value=g((e=>e()),i.value,l.value),e.context.runAsync=(...e)=>new Promise(((n,t)=>{o.value?(o.value=!1,s.value(...e).then(n).catch(t)):u.value((()=>{s.value(...e).then(n).catch(t)}))})),n((()=>{var n;null===(n=u.value)||void 0===n||n.cancel(),e.context.runAsync=s.value})))})),{onCancel(){var e;null===(e=u.value)||void 0===e||e.cancel()}}},A=(e,{errorRetryCount:t=0,errorRetryInterval:a=0})=>{const r=n.ref(),o=n.ref(0),u=n.computed((()=>p(t))),l=n.computed((()=>p(a)));let i=!1;const c=()=>{o.value=0},s=n.computed((()=>{if(l.value)return l.value;return 1e3*Math.floor(Math.random()*2**Math.min(o.value,9)+1)})),v=()=>{r.value&&r.value()};return{onBefore(){i||c(),i=!1,v()},onSuccess(){c()},onError(){r.value=(()=>{let n;const t=-1===u.value,a=o.value<u.value;return(t||a)&&(t||(o.value+=1),n=setTimeout((()=>{i=!0,e.context.refresh()}),s.value)),()=>n&&clearTimeout(n)})()},onCancel(){c(),v()}}},T=(e,{ready:t=n.ref(!0),manual:a,defaultParams:r=[]})=>(n.watch(t,(n=>{!a&&n&&e.context.run(...r)}),{flush:"sync"}),{onBefore(){if(!t.value)return e.loading.value=!1,{isBreak:!0}}}),x=(e,{refreshDeps:t=[],refreshDepsAction:a,manual:r})=>(null!=t&&t.length&&n.watch(t,(()=>{a?a():!r&&e.context.refresh()})),{}),b=(e,{throttleInterval:t,throttleOptions:a})=>{const r=n.ref(),o=n.computed((()=>p(t))),u=n.computed((()=>a)),i=n.ref(e.context.runAsync);return n.watchEffect((n=>{if(c(t))return{};r.value=function(e,n,t){let a=!0,r=!0;if("function"!=typeof e)throw new TypeError("Expected a function");return l(t)&&(a="leading"in t?!!t.leading:a,r="trailing"in t?!!t.trailing:r),g(e,n,{leading:a,trailing:r,maxWait:n})}((e=>e()),o.value,u.value),e.context.runAsync=(...e)=>new Promise(((n,t)=>{r.value((()=>{i.value(...e).then(n).catch(t)}))})),n((()=>{var n;null===(n=r.value)||void 0===n||n.cancel(),e.context.runAsync=i.value}))})),{onCancel(){var e;null===(e=r.value)||void 0===e||e.cancel()}}};const S=(e,t,a)=>{var r,o;const{initialData:u,onSuccess:c,onError:s,onBefore:v,onAfter:f}=t,m=n.ref(null!==(r=null==a?void 0:a.loading)&&void 0!==r&&r),p=n.shallowRef(null!==(o=null==a?void 0:a.data)&&void 0!==o?o:u),h=n.shallowRef(null==a?void 0:a.error),g=n.ref(null==a?void 0:a.params),y=n.ref([]),w={},E=(A={loading:m,data:p,error:h,params:g},T=[],e=>{Object.keys(e).forEach((n=>{A[n].value=e[n]})),T.forEach((e=>e(A)))});var A,T;const x=(e,...n)=>{const t=y.value.map((t=>{var a;return null===(a=t[e])||void 0===a?void 0:a.call(t,...n)}));return Object.assign({},...t)},b=n.ref(0);return w.runAsync=async(...n)=>{E({loading:!0,params:n}),b.value+=1;const t=b.value,{isBreak:a,breakResult:r=d()}=x("onBefore",n);if(a)return r;null==v||v(n);try{let{servicePromise:a}=x("onQuery",e,g.value);a||(a=e(...g.value));const r=await a;return t!==b.value?d():(E({data:r,loading:!1,error:void 0}),x("onSuccess",r,n),null==c||c(r,n),x("onAfter",n,r,void 0),null==f||f(n),r)}catch(e){if(t!==b.value)return d();throw E({loading:!1,error:e}),x("onError",e,n),null==s||s(e,n),x("onAfter",n,void 0,e),null==f||f(n),e}},w.run=async(...e)=>{w.runAsync(...e).catch((e=>{s||console.error(e)}))},w.cancel=()=>{b.value+=1,E({loading:!1}),x("onCancel")},w.refresh=()=>{w.run(...g.value||[])},w.refreshAsync=()=>w.runAsync(...g.value||[]),w.mutate=e=>{const n=i(e)?e(p.value):e,t=l(n)?Object.assign({},n):n;E({data:t}),x("onMutate",t)},{loading:m,data:p,error:h,params:g,plugins:y,context:w}};function O(e,t={},o){const u=n.inject(a,{}),l={...r(),...u,...t},{manual:i=!1,defaultParams:c=[]}=l,s=S(e,l);if(s.plugins.value=o.map((e=>e(s,l))),!i){const e=s.params.value||c;s.context.run(...e)}return n.onUnmounted((()=>{s.context.cancel()})),{loading:s.loading,data:s.data,error:s.error,params:s.params,cancel:s.context.cancel,refresh:s.context.refresh,refreshAsync:s.context.refreshAsync,mutate:s.context.mutate,run:s.context.run,runAsync:s.context.runAsync}}const P=new Map,R=new Map;var M,I=(e,{cacheKey:t,cacheTime:a=6e5,staleTime:r=0,getCache:o,setCache:u})=>{if(!t)return{};const l=i(t)?t:()=>t,s=n.ref((()=>{}));let v;const d=e=>o?o(e):(e=>{if(c(e))return;return h.get(e)})(e),f=(e,n,t)=>{u?u(e,t):((e,n,t)=>{const a=h.get(e);null!=a&&a.timer&&clearTimeout(a.timer);const r=setTimeout((()=>h.delete(e)),n);h.set(e,{...t,timer:r})})(e,n,t),((e,n)=>{R.has(e)&&R.get(e).forEach((e=>e(n)))})(e,t.data)},m=(e,n)=>Object.prototype.hasOwnProperty.call(e,n),p=n=>{const t=l(n);return a=t,r=n=>{e.data.value=n},R.has(a)?R.get(a).push(r):R.set(a,[r]),()=>{const e=R.get(a).indexOf(r);R.get(a).splice(e,1)};var a,r},g=l(),y=d(g);return y&&m(y,"data")&&(e.data.value=y.data,e.params.value=y.params),g&&(s.value=p()),n.onUnmounted((()=>{s.value()})),{onBefore(n){const t=l(n),a=d(t);return a&&m(a,"data")?(o=a.time,-1===r||o+r>(new Date).getTime()?(e.data.value=a.data,e.loading.value=!1,{isBreak:!0,breakResult:a.data}):void(e.data.value=a.data)):{};var o},onQuery(e,n){const t=l(n);let a=(e=>P.get(e))(t);return a&&a!==v||(a=e(...n),v=a,((e,n)=>{P.set(e,n),n.then((n=>(P.delete(e),n))).catch((()=>{P.delete(e)}))})(t,a)),{servicePromise:a}},onSuccess(e,n){const t=l(n);t&&(s.value(),f(t,a,{data:e,params:n,time:(new Date).getTime()}),s.value=p(n))},onMutate(n){const t=l(e.params.value);t&&(s.value(),f(t,a,{data:n,params:e.params.value,time:(new Date).getTime()}),s.value=p(e.params.value))}}},L=(e,{loadingDelay:t=0})=>{const a=n.ref((()=>{})),r=n.computed((()=>p(t)));return{onBefore(){e.loading.value=!r.value,a.value(),a.value=(()=>{let n;return r.value&&(n=setTimeout((()=>{e.loading.value=!0}),r.value)),()=>n&&clearTimeout(n)})()},onCancel(){a.value()},onAfter(){a.value()}}};const j=new Set,C=new Set,B=new Set,D=(e,n)=>{let t;switch(e){case"FOCUS_LISTENER":t=j;break;case"RECONNECT_LISTENER":t=B;break;case"VISIBLE_LISTENER":t=C}if(!t.has(n))return t.add(n),()=>{t.delete(n)}},N=e=>{e.forEach((e=>{e()}))};!s&&null!==(M=window)&&void 0!==M&&M.addEventListener&&(window.addEventListener("visibilitychange",(()=>{v()&&N(C)}),!1),window.addEventListener("focus",(()=>N(j)),!1),window.addEventListener("online",(()=>N(B)),!1));var _=(e,{pollingInterval:t,pollingWhenHidden:a=!1,pollingWhenOffline:r=!1,errorRetryCount:o=0})=>{const u=n.ref(),l=n.ref(!1),i=n.computed((()=>p(t))),d=n.computed((()=>p(o))),f=[],m=e=>{e&&f.push(e)},h=()=>{return(a||v())&&(r||null===(e=!s&&(null===(n=window.navigator)||void 0===n?void 0:n.onLine))||void 0===e||e);var e,n},g=n=>{if(e.error.value&&0!==d.value)return;let t;if(!c(i.value)&&i.value>=0){if(!h())return void(l.value=!0);t=setTimeout(n,i.value)}return()=>t&&clearTimeout(t)},y=()=>{l.value&&h()&&(e.context.refresh(),l.value=!1)};return n.watch(i,(()=>{u.value&&(u.value(),u.value=g((()=>e.context.refresh())))})),a||m(D("VISIBLE_LISTENER",y)),r||m(D("RECONNECT_LISTENER",y)),n.onUnmounted((()=>{f.forEach((e=>e()))})),{onBefore(){var e;null===(e=u.value)||void 0===e||e.call(u)},onCancel(){var e;null===(e=u.value)||void 0===e||e.call(u)},onAfter(){u.value=g((()=>e.context.refresh()))}}};var k=(e,{refreshOnWindowFocus:t=!1,refocusTimespan:a=5e3})=>{const r=n.computed((()=>p(t))),o=n.computed((()=>p(a))),u=[],l=e=>{e&&u.push(e)},i=()=>{u.forEach((e=>e()))};return n.watchEffect((()=>{if(i(),r.value){const n=((e,n)=>{let t=!1;return(...a)=>{t||(t=!0,e(...a),setTimeout((()=>{t=!1}),n))}})(e.context.refresh,o.value);l(D("VISIBLE_LISTENER",n)),l(D("FOCUS_LISTENER",n))}})),n.onUnmounted((()=>{i()})),{}};function K(e,n){return O(e,n,[L,A,E,_,b,k,x,T,I])}e.clearCache=e=>{if(e){var n;const t=null===(n=h.get(e))||void 0===n?void 0:n.timer;t&&clearTimeout(t),h.delete(e)}else h.forEach((e=>e.timer&&clearTimeout(e.timer))),h.clear()},e.setGlobalOptions=e=>{Object.keys(e).forEach((n=>{t[n]=e[n]}))},e.useLoadMore=function(e,t){const{isNoMore:a,...r}=null!=t?t:{},o=n.shallowRef(),u=n.computed((()=>{var e;return(null===(e=o.value)||void 0===e?void 0:e.list)||[]})),c=n.ref(!1),s=n.ref(!1),v=n.ref(0),{runAsync:d,run:f,cancel:p,...h}=O((async n=>{const t=v.value,a=await e(n);return t===v.value&&(o.value=n?{...a,list:[...n.list,...a.list]}:a),a}),{...r,defaultParams:[],refreshDepsAction:()=>{null!=r&&r.refreshDepsAction?r.refreshDepsAction():w()},onError:e=>{var n;null==r||null===(n=r.onError)||void 0===n||n.call(r,e)},onSuccess:e=>{var n;null==r||null===(n=r.onSuccess)||void 0===n||n.call(r,e)},onBefore:()=>{var e;v.value+=1,s.value&&(s.value=!1,c.value=!0),null==r||null===(e=r.onBefore)||void 0===e||e.call(r)},onAfter:()=>{var e;c.value=!1,s.value=!1,null==r||null===(e=r.onAfter)||void 0===e||e.call(r)}},[A,E,b,x,T]),g=n.computed((()=>!(!a||!i(a))&&a(o.value))),y=()=>g.value?Promise.reject(((e,n=!1)=>{const t=`Warning: [vue-request] ${e}`;if(n)return new Error(t);console.error(t)})("No more data. You need to ignore this error by checking if `noMore` is false before calling `loadMoreAsync`",!0)):(s.value=!0,d(o.value)),w=()=>f();return{data:o,dataList:u,loadingMore:c,noMore:g,cancel:()=>{v.value+=1,p(),c.value=!1},mutate:e=>{const n=i(e)?e(o.value):e,t=l(n)?Object.assign({},n):n;o.value=t},refresh:w,refreshAsync:()=>d(),loadMore:()=>{y().catch((()=>{}))},loadMoreAsync:y,...m(h,["refresh","refreshAsync","mutate","params","data"])}},e.usePagination=function(e,t={}){const o=n.inject(a,{}),{pagination:u,...l}=t,{currentKey:i,pageSizeKey:c,totalKey:s,totalPageKey:v}=w({currentKey:"current",pageSizeKey:"pageSize",totalKey:"total",totalPageKey:"totalPage"},r().pagination||{},o.pagination||{},u||{}),d=w({defaultParams:[{[i]:1,[c]:10}]},l),{data:m,params:p,run:h,...g}=K(e,d),y=e=>{const[n,...t]=p.value||[],a=[{...n,...e},...t];h(...a)},E=e=>{y({[i]:e})},A=e=>{y({[c]:e})},T=n.computed((()=>f(m.value,s,0))),x=n.computed({get:()=>{var e,n;return null!==(e=null===(n=p.value)||void 0===n?void 0:n[0][i])&&void 0!==e?e:d.defaultParams[0][i]},set:e=>{E(e)}}),b=n.computed({get:()=>{var e,n;return null!==(e=null===(n=p.value)||void 0===n?void 0:n[0][c])&&void 0!==e?e:d.defaultParams[0][c]},set:e=>{A(e)}}),S=n.computed((()=>f(m.value,v,Math.ceil(T.value/b.value))));return{data:m,params:p,current:x,pageSize:b,total:T,totalPage:S,run:h,changeCurrent:E,changePageSize:A,changePagination:(e,n)=>{y({[i]:e,[c]:n})},...g}},e.useRequest=K,e.useRequestProvider=e=>{n.provide(a,e)},Object.defineProperty(e,"__esModule",{value:!0})})); |
{ | ||
"name": "vue-request", | ||
"version": "2.0.0-beta.2", | ||
"version": "2.0.0-rc.1", | ||
"description": "Vue composition API for data fetching, supports SWR, polling, error retry, cache request, pagination and other cool features.", | ||
@@ -5,0 +5,0 @@ "keywords": [ |
@@ -43,3 +43,3 @@ [English](./README.md) | 简体中文 | ||
目前处于 Alpha 版本,详情请查看[更新日志](https://github.com/AttoJS/vue-request/issues/121)。 | ||
目前处于 Beta 版本,详情请查看[更新日志](https://github.com/AttoJS/vue-request/issues/121)。 | ||
@@ -46,0 +46,0 @@ ## 为什么选择 VueRequest |
@@ -43,3 +43,3 @@ English | [简体中文](README-zh_CN.md) | ||
Currently in Alpha version. For details, please see the [changelog](https://github.com/AttoJS/vue-request/issues/121). | ||
Currently in Beta version. For details, please see the [changelog](https://github.com/AttoJS/vue-request/issues/121). | ||
@@ -46,0 +46,0 @@ ## Why VueRequest |
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
122000
2337