@nutgaard/use-fetch
Version:
A useFetch hook to be used with react@^16.8.0
155 lines (144 loc) • 6.62 kB
JavaScript
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@nutgaard/use-async'), require('react')) :
typeof define === 'function' && define.amd ? define(['exports', '@nutgaard/use-async', 'react'], factory) :
(factory((global.useFetch = {}),global.useAsync,global.react));
}(this, (function (exports,useAsync,react) { 'use strict';
var useAsync__default = 'default' in useAsync ? useAsync['default'] : useAsync;
/*! *****************************************************************************
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 = react.useState(-1), statusCode = _a[0], setStatusCode = _a[1];
var cacheKey = config.cacheKey || cacheKeyCreator(url, option);
var source = react.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: useAsync.Status.OK, data: globaleFetchCache.getResolved(cacheKey) }
: undefined;
var asyncResult = useAsync__default(source, config.lazy, [source], initialConfig);
return react.useMemo(function () {
return __assign({}, asyncResult, { statusCode: statusCode });
}, [asyncResult, statusCode]);
}
Object.keys(useAsync).forEach(function (key) { exports[key] = useAsync[key]; });
exports.createCacheKey = createCacheKey;
exports.setCacheKeyGenerator = setCacheKeyGenerator;
exports.default = useFetch;
exports.cache = globaleFetchCache;
Object.defineProperty(exports, '__esModule', { value: true });
})));
//# sourceMappingURL=use-fetch.umd.js.map