UNPKG

axios-hooks

Version:
279 lines 9.02 kB
import _asyncToGenerator from "@babel/runtime/helpers/esm/asyncToGenerator"; import _extends from "@babel/runtime/helpers/esm/extends"; import _regeneratorRuntime from "@babel/runtime/regenerator"; import React from 'react'; import StaticAxios, { isCancel } from 'axios'; import { LRUCache } from 'lru-cache'; import { dequal as deepEqual } from 'dequal/lite'; var actions = { REQUEST_START: 'REQUEST_START', REQUEST_END: 'REQUEST_END' }; var DEFAULT_OPTIONS = { manual: false, useCache: true, ssr: true, autoCancel: true }; var useAxios = makeUseAxios(); var __ssrPromises = useAxios.__ssrPromises, resetConfigure = useAxios.resetConfigure, configure = useAxios.configure, loadCache = useAxios.loadCache, serializeCache = useAxios.serializeCache, clearCache = useAxios.clearCache; export default useAxios; export { __ssrPromises, resetConfigure, configure, loadCache, serializeCache, clearCache }; function isReactEvent(obj) { return obj && obj.nativeEvent && obj.nativeEvent instanceof Event; } function createCacheKey(config) { var cleanedConfig = _extends({}, config); delete cleanedConfig.cancelToken; return JSON.stringify(cleanedConfig); } function configToObject(config) { if (typeof config === 'string') { return { url: config }; } return Object.assign({}, config); } export function makeUseAxios(configureOptions) { /** * @type {import('lru-cache')} */ var cache; var axiosInstance; var defaultOptions; var __ssrPromises = []; function resetConfigure() { cache = new LRUCache({ max: 500 }); axiosInstance = StaticAxios; defaultOptions = DEFAULT_OPTIONS; } function configure(options) { if (options === void 0) { options = {}; } if (options.axios !== undefined) { axiosInstance = options.axios; } if (options.cache !== undefined) { cache = options.cache; } if (options.defaultOptions !== undefined) { defaultOptions = _extends({}, DEFAULT_OPTIONS, options.defaultOptions); } } resetConfigure(); configure(configureOptions); function loadCache(data) { cache.load(data); } function serializeCache() { return _serializeCache.apply(this, arguments); } function _serializeCache() { _serializeCache = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee() { var ssrPromisesCopy; return _regeneratorRuntime.wrap(function _callee$(_context) { while (1) switch (_context.prev = _context.next) { case 0: ssrPromisesCopy = [].concat(__ssrPromises); __ssrPromises.length = 0; _context.next = 4; return Promise.all(ssrPromisesCopy); case 4: return _context.abrupt("return", cache.dump()); case 5: case "end": return _context.stop(); } }, _callee); })); return _serializeCache.apply(this, arguments); } function clearCache() { cache.clear(); } return Object.assign(useAxios, { __ssrPromises: __ssrPromises, resetConfigure: resetConfigure, configure: configure, loadCache: loadCache, serializeCache: serializeCache, clearCache: clearCache }); function tryStoreInCache(config, response) { if (!cache) { return; } var cacheKey = createCacheKey(config); var responseForCache = _extends({}, response); delete responseForCache.config; delete responseForCache.request; cache.set(cacheKey, responseForCache); } function createInitialState(config, options) { var response = !options.manual && tryGetFromCache(config, options); return _extends({ loading: !options.manual && !response, error: null }, response ? { data: response.data, response: response } : null); } function reducer(state, action) { var _extends2; switch (action.type) { case actions.REQUEST_START: return _extends({}, state, { loading: true, error: null }); case actions.REQUEST_END: return _extends({}, state, { loading: false }, action.error ? {} : { data: action.payload.data, error: null }, (_extends2 = {}, _extends2[action.error ? 'error' : 'response'] = action.payload, _extends2)); } } function tryGetFromCache(config, options, dispatch) { if (!cache || !options.useCache) { return; } var cacheKey = createCacheKey(config); var response = cache.get(cacheKey); if (response && dispatch) { dispatch({ type: actions.REQUEST_END, payload: response }); } return response; } function executeRequest(_x, _x2) { return _executeRequest.apply(this, arguments); } function _executeRequest() { _executeRequest = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee2(config, dispatch) { var response; return _regeneratorRuntime.wrap(function _callee2$(_context2) { while (1) switch (_context2.prev = _context2.next) { case 0: _context2.prev = 0; dispatch({ type: actions.REQUEST_START }); _context2.next = 4; return axiosInstance(config); case 4: response = _context2.sent; tryStoreInCache(config, response); dispatch({ type: actions.REQUEST_END, payload: response }); return _context2.abrupt("return", response); case 10: _context2.prev = 10; _context2.t0 = _context2["catch"](0); if (!isCancel(_context2.t0)) { dispatch({ type: actions.REQUEST_END, payload: _context2.t0, error: true }); } throw _context2.t0; case 14: case "end": return _context2.stop(); } }, _callee2, null, [[0, 10]]); })); return _executeRequest.apply(this, arguments); } function request(_x3, _x4, _x5) { return _request.apply(this, arguments); } function _request() { _request = _asyncToGenerator(/*#__PURE__*/_regeneratorRuntime.mark(function _callee3(config, options, dispatch) { return _regeneratorRuntime.wrap(function _callee3$(_context3) { while (1) switch (_context3.prev = _context3.next) { case 0: return _context3.abrupt("return", tryGetFromCache(config, options, dispatch) || executeRequest(config, dispatch)); case 1: case "end": return _context3.stop(); } }, _callee3); })); return _request.apply(this, arguments); } function useAxios(_config, _options) { var config = React.useMemo(function () { return configToObject(_config); }, // eslint-disable-next-line react-hooks/exhaustive-deps useDeepCompareMemoize(_config)); var options = React.useMemo(function () { return _extends({}, defaultOptions, _options); }, // eslint-disable-next-line react-hooks/exhaustive-deps useDeepCompareMemoize(_options)); var abortControllerRef = React.useRef(); var _React$useReducer = React.useReducer(reducer, createInitialState(config, options)), state = _React$useReducer[0], dispatch = _React$useReducer[1]; if (typeof window === 'undefined' && options.ssr && !options.manual) { useAxios.__ssrPromises.push(axiosInstance(config)); } var cancelOutstandingRequest = React.useCallback(function () { if (abortControllerRef.current) { abortControllerRef.current.abort(); } }, []); var withAbortSignal = React.useCallback(function (config) { if (options.autoCancel) { cancelOutstandingRequest(); } abortControllerRef.current = new AbortController(); config.signal = abortControllerRef.current.signal; return config; }, [cancelOutstandingRequest, options.autoCancel]); React.useEffect(function () { if (!options.manual) { request(withAbortSignal(config), options, dispatch)["catch"](function () {}); } return function () { if (options.autoCancel) { cancelOutstandingRequest(); } }; }, [config, options, withAbortSignal, cancelOutstandingRequest]); var refetch = React.useCallback(function (configOverride, options) { configOverride = configToObject(configOverride); return request(withAbortSignal(_extends({}, config, isReactEvent(configOverride) ? null : configOverride)), _extends({ useCache: false }, options), dispatch); }, [config, withAbortSignal]); return [state, refetch, cancelOutstandingRequest]; } } function useDeepCompareMemoize(value) { var ref = React.useRef(); var signalRef = React.useRef(0); if (!deepEqual(value, ref.current)) { ref.current = value; signalRef.current += 1; } return [signalRef.current]; }