UNPKG

@nutgaard/use-fetch

Version:

A useFetch hook to be used with react@^16.8.0

144 lines (136 loc) 5.51 kB
import useAsync__default, { Status } from '@nutgaard/use-async'; export * from '@nutgaard/use-async'; import { useCallback, useMemo, useState } from 'react'; /*! ***************************************************************************** Copyright (c) Microsoft Corporation. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, MERCHANTABLITY OR NON-INFRINGEMENT. See the Apache Version 2.0 License for specific language governing permissions and limitations under the License. ***************************************************************************** */ var __assign = function() { __assign = Object.assign || function __assign(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; var FetchCache = /** @class */ (function () { function FetchCache() { this.cache = {}; this.resolvedCache = {}; } FetchCache.prototype.fetch = function (key, url, init) { var _this = this; if (this.hasKey(key)) { return this.get(key); } var result = fetch(url, init); this.put(key, result); result.then(function (resp) { if (!resp.ok) { _this.remove(key); } }, function () { _this.remove(key); }); return result.then(function (resp) { return resp.clone(); }); }; FetchCache.prototype.get = function (key) { return this.cache[key].then(function (resp) { return resp.clone(); }); }; FetchCache.prototype.getResolved = function (key) { return this.resolvedCache[key]; }; FetchCache.prototype.putResolved = function (key, value) { this.resolvedCache[key] = value; }; FetchCache.prototype.put = function (key, value) { this.cache[key] = value.then(function (resp) { return resp.clone(); }); }; FetchCache.prototype.remove = function (key) { delete this.cache[key]; delete this.resolvedCache[key]; }; FetchCache.prototype.clear = function () { this.cache = {}; this.resolvedCache = {}; }; FetchCache.prototype.hasKey = function (key) { // tslint:disable-next-line:strict-type-predicates return this.cache[key] !== undefined; }; FetchCache.prototype.keys = function () { return Object.keys(this.cache); }; FetchCache.prototype.hasKeyResolved = function (key) { // tslint:disable-next-line:strict-type-predicates return this.resolvedCache[key] !== undefined; }; FetchCache.prototype.size = function () { return Object.keys(this.cache).length; }; return FetchCache; }()); var globaleFetchCache = new FetchCache(); function createCacheKey(url, option) { var method = (option && option.method) || 'GET'; var body = (option && option.body && option.body.toString()) || ''; var headers = (option && option.headers && JSON.stringify(option.headers)) || ''; return [url, method.toUpperCase(), body, headers].join('||'); } function setCacheKeyGenerator(keygenerator) { cacheKeyCreator = keygenerator; } var cacheKeyCreator = createCacheKey; function handleResponse(response, setStatusCode, cacheKey) { return response .then(function (resp) { setStatusCode(resp.status); if (!resp.ok) { throw new Error(resp.statusText); } if ([200, 201, 203, 206].includes(resp.status)) { return resp.json(); } return; }) .then(function (json) { globaleFetchCache.putResolved(cacheKey, json); return json; }); } function useFetch(url, option, config) { if (config === void 0) { config = { lazy: false, cacheKey: undefined }; } var _a = useState(-1), statusCode = _a[0], setStatusCode = _a[1]; var cacheKey = config.cacheKey || cacheKeyCreator(url, option); var source = useCallback(function (isRerun) { setStatusCode(-1); var response = isRerun ? fetch(url, option) : globaleFetchCache.fetch(cacheKey, url, option); if (isRerun) { globaleFetchCache.put(cacheKey, response); } return handleResponse(response, setStatusCode, cacheKey); }, [url, option, cacheKey]); var initialConfig = globaleFetchCache.hasKeyResolved(cacheKey) ? { status: Status.OK, data: globaleFetchCache.getResolved(cacheKey) } : undefined; var asyncResult = useAsync__default(source, config.lazy, [source], initialConfig); return useMemo(function () { return __assign({}, asyncResult, { statusCode: statusCode }); }, [asyncResult, statusCode]); } export default useFetch; export { createCacheKey, setCacheKeyGenerator, globaleFetchCache as cache }; //# sourceMappingURL=use-fetch.es5.js.map