Last active
May 4, 2022 16:54
-
-
Save danybeltran/4611694ba7c021f598025bef0a21a4ea to your computer and use it in GitHub Desktop.
Http React Fetcher for browsers
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict" | |
/** | |
* @license http-react-fetcher | |
* Copyright (c) Dany Beltran | |
* | |
* This source code is licensed under the MIT license found in the | |
* LICENSE file in the root directory of this source tree. | |
*/ | |
var __assign = | |
(this && this.__assign) || | |
function () { | |
__assign = | |
Object.assign || | |
function (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 __awaiter = | |
(this && this.__awaiter) || | |
function (thisArg, _arguments, P, generator) { | |
function adopt(value) { | |
return value instanceof P | |
? value | |
: new P(function (resolve) { | |
resolve(value) | |
}) | |
} | |
return new (P || (P = Promise))(function (resolve, reject) { | |
function fulfilled(value) { | |
try { | |
step(generator.next(value)) | |
} catch (e) { | |
reject(e) | |
} | |
} | |
function rejected(value) { | |
try { | |
step(generator["throw"](value)) | |
} catch (e) { | |
reject(e) | |
} | |
} | |
function step(result) { | |
result.done | |
? resolve(result.value) | |
: adopt(result.value).then(fulfilled, rejected) | |
} | |
step((generator = generator.apply(thisArg, _arguments || [])).next()) | |
}) | |
} | |
var __generator = | |
(this && this.__generator) || | |
function (thisArg, body) { | |
var _ = { | |
label: 0, | |
sent: function () { | |
if (t[0] & 1) throw t[1] | |
return t[1] | |
}, | |
trys: [], | |
ops: [] | |
}, | |
f, | |
y, | |
t, | |
g | |
return ( | |
(g = { next: verb(0), throw: verb(1), return: verb(2) }), | |
typeof Symbol === "function" && | |
(g[Symbol.iterator] = function () { | |
return this | |
}), | |
g | |
) | |
function verb(n) { | |
return function (v) { | |
return step([n, v]) | |
} | |
} | |
function step(op) { | |
if (f) throw new TypeError("Generator is already executing.") | |
while (_) | |
try { | |
if ( | |
((f = 1), | |
y && | |
(t = | |
op[0] & 2 | |
? y["return"] | |
: op[0] | |
? y["throw"] || ((t = y["return"]) && t.call(y), 0) | |
: y.next) && | |
!(t = t.call(y, op[1])).done) | |
) | |
return t | |
if (((y = 0), t)) op = [op[0] & 2, t.value] | |
switch (op[0]) { | |
case 0: | |
case 1: | |
t = op | |
break | |
case 4: | |
_.label++ | |
return { value: op[1], done: false } | |
case 5: | |
_.label++ | |
y = op[1] | |
op = [0] | |
continue | |
case 7: | |
op = _.ops.pop() | |
_.trys.pop() | |
continue | |
default: | |
if ( | |
!((t = _.trys), (t = t.length > 0 && t[t.length - 1])) && | |
(op[0] === 6 || op[0] === 2) | |
) { | |
_ = 0 | |
continue | |
} | |
if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { | |
_.label = op[1] | |
break | |
} | |
if (op[0] === 6 && _.label < t[1]) { | |
_.label = t[1] | |
t = op | |
break | |
} | |
if (t && _.label < t[2]) { | |
_.label = t[2] | |
_.ops.push(op) | |
break | |
} | |
if (t[2]) _.ops.pop() | |
_.trys.pop() | |
continue | |
} | |
op = body.call(thisArg, _) | |
} catch (e) { | |
op = [6, e] | |
y = 0 | |
} finally { | |
f = t = 0 | |
} | |
if (op[0] & 5) throw op[1] | |
return { value: op[0] ? op[1] : void 0, done: true } | |
} | |
} | |
var __rest = | |
(this && this.__rest) || | |
function (s, e) { | |
var t = {} | |
for (var p in s) | |
if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) | |
t[p] = s[p] | |
if (s != null && typeof Object.getOwnPropertySymbols === "function") | |
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) { | |
if ( | |
e.indexOf(p[i]) < 0 && | |
Object.prototype.propertyIsEnumerable.call(s, p[i]) | |
) | |
t[p[i]] = s[p[i]] | |
} | |
return t | |
} | |
var react_1 = React | |
/** | |
* @deprecated Use the `useFetcher` hook instead | |
*/ | |
var Fetcher = function (_a) { | |
var _b = _a.url, | |
url = _b === void 0 ? "/" : _b, | |
def = _a.default, | |
_c = _a.config, | |
config = _c === void 0 ? { method: "GET", headers: {}, body: {} } : _c, | |
Children = _a.children, | |
_d = _a.onError, | |
onError = _d === void 0 ? function () {} : _d, | |
_e = _a.onResolve, | |
onResolve = _e === void 0 ? function () {} : _e, | |
_f = _a.refresh, | |
refresh = _f === void 0 ? 0 : _f | |
var _g = (0, react_1.useState)(def), | |
data = _g[0], | |
setData = _g[1] | |
var _h = (0, react_1.useState)(null), | |
error = _h[0], | |
setError = _h[1] | |
var _j = (0, react_1.useState)(true), | |
loading = _j[0], | |
setLoading = _j[1] | |
function fetchData() { | |
var _a | |
return __awaiter(this, void 0, void 0, function () { | |
var json, _data, code, err_1 | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
_b.trys.push([0, 3, 4, 5]) | |
return [ | |
4 /*yield*/, | |
fetch(url, { | |
method: config.method, | |
headers: __assign( | |
{ "Content-Type": "application/json" }, | |
config.headers | |
), | |
body: ( | |
(_a = config.method) === null || _a === void 0 | |
? void 0 | |
: _a.match(/(POST|PUT|DELETE)/) | |
) | |
? JSON.stringify(config.body) | |
: undefined | |
}) | |
] | |
case 1: | |
json = _b.sent() | |
return [4 /*yield*/, json.json()] | |
case 2: | |
_data = _b.sent() | |
code = json.status | |
if (code >= 200 && code < 300) { | |
setData(_data) | |
setError(null) | |
onResolve(_data) | |
} else { | |
if (def) { | |
setData(def) | |
} | |
setError(true) | |
onError(_data) | |
} | |
return [3 /*break*/, 5] | |
case 3: | |
err_1 = _b.sent() | |
setData(undefined) | |
setError(new Error(err_1)) | |
onError(err_1) | |
return [3 /*break*/, 5] | |
case 4: | |
setLoading(false) | |
return [7 /*endfinally*/] | |
case 5: | |
return [2 /*return*/] | |
} | |
}) | |
}) | |
} | |
;(0, react_1.useEffect)( | |
function () { | |
function reValidate() { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
if ((data || error) && !loading) { | |
setLoading(true) | |
fetchData() | |
} | |
return [2 /*return*/] | |
}) | |
}) | |
} | |
if (refresh > 0) { | |
var interval_1 = setTimeout(reValidate, refresh * 1000) | |
return function () { | |
return clearTimeout(interval_1) | |
} | |
} | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, | |
[refresh, loading, error, data, config] | |
) | |
;(0, react_1.useEffect)( | |
function () { | |
setLoading(true) | |
fetchData() | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, | |
[url, refresh, config] | |
) | |
if (typeof Children !== "undefined") { | |
return React.createElement(Children, { | |
data: data, | |
error: error, | |
loading: loading | |
}) | |
} else { | |
return null | |
} | |
} | |
var resolvedRequests = {} | |
function FetcherConfig(_a) { | |
var children = _a.children, | |
_b = _a.defaults, | |
defaults = _b === void 0 ? {} : _b | |
if (defaults) { | |
for (var defaultKey in defaults) { | |
resolvedRequests[defaultKey] = defaults[defaultKey] | |
} | |
} | |
return children | |
} | |
/** | |
* Fetcher available as a hook | |
*/ | |
var useFetcher = function (_a) { | |
var _b = _a.url, | |
url = _b === void 0 ? "/" : _b, | |
def = _a.default, | |
_c = _a.config, | |
config = _c === void 0 ? { method: "GET", headers: {}, body: {} } : _c, | |
_d = _a.resolver, | |
resolver = | |
_d === void 0 | |
? function (d) { | |
return d.json() | |
} | |
: _d, | |
_e = _a.onError, | |
onError = _e === void 0 ? function () {} : _e, | |
_f = _a.auto, | |
auto = _f === void 0 ? true : _f, | |
_g = _a.memory, | |
memory = _g === void 0 ? true : _g, | |
_h = _a.onResolve, | |
onResolve = _h === void 0 ? function () {} : _h, | |
_j = _a.onAbort, | |
onAbort = _j === void 0 ? function () {} : _j, | |
_k = _a.refresh, | |
refresh = _k === void 0 ? 0 : _k, | |
_l = _a.cancelOnChange, | |
cancelOnChange = _l === void 0 ? false : _l | |
var resolvedKey = url.split("?")[0] | |
var _m = (0, react_1.useState)( | |
// Saved to base url of request without query params | |
memory ? resolvedRequests[resolvedKey] || def : def | |
), | |
data = _m[0], | |
setData = _m[1] | |
var _o = (0, react_1.useState)(), | |
statusCode = _o[0], | |
setStatusCode = _o[1] | |
var _p = (0, react_1.useState)(null), | |
error = _p[0], | |
setError = _p[1] | |
var _q = (0, react_1.useState)(true), | |
loading = _q[0], | |
setLoading = _q[1] | |
var _r = (0, react_1.useState)(new AbortController()), | |
requestAbortController = _r[0], | |
setRequestAbortController = _r[1] | |
function fetchData() { | |
var _a | |
return __awaiter(this, void 0, void 0, function () { | |
var newAbortController, json, code, _data, err_2, errorString | |
return __generator(this, function (_b) { | |
switch (_b.label) { | |
case 0: | |
if (cancelOnChange) { | |
requestAbortController === null || | |
requestAbortController === void 0 | |
? void 0 | |
: requestAbortController.abort() | |
} | |
newAbortController = new AbortController() | |
setRequestAbortController(newAbortController) | |
setError(null) | |
_b.label = 1 | |
case 1: | |
_b.trys.push([1, 4, 5, 6]) | |
return [ | |
4 /*yield*/, | |
fetch(url, { | |
signal: newAbortController.signal, | |
method: config.method, | |
headers: __assign( | |
{ "Content-Type": "application/json" }, | |
config.headers | |
), | |
body: ( | |
(_a = config.method) === null || _a === void 0 | |
? void 0 | |
: _a.match(/(POST|PUT|DELETE)/) | |
) | |
? JSON.stringify(config.body) | |
: undefined | |
}) | |
] | |
case 2: | |
json = _b.sent() | |
code = json.status | |
setStatusCode(code) | |
return [4 /*yield*/, resolver(json)] | |
case 3: | |
_data = _b.sent() | |
if (code >= 200 && code < 400) { | |
if (memory) { | |
resolvedRequests[resolvedKey] = _data | |
} | |
setData(_data) | |
setError(null) | |
onResolve(_data) | |
} else { | |
if (def) { | |
setData(def) | |
} | |
setError(true) | |
onError(_data) | |
} | |
return [3 /*break*/, 6] | |
case 4: | |
err_2 = _b.sent() | |
errorString = | |
err_2 === null || err_2 === void 0 ? void 0 : err_2.toString() | |
// Only set error if no abort | |
if (!errorString.match(/abort/i)) { | |
setData(undefined) | |
setError(new Error(err_2)) | |
onError(err_2) | |
} else { | |
if (!resolvedRequests[resolvedKey]) { | |
setData(def) | |
} | |
} | |
return [3 /*break*/, 6] | |
case 5: | |
setLoading(false) | |
return [7 /*endfinally*/] | |
case 6: | |
return [2 /*return*/] | |
} | |
}) | |
}) | |
} | |
// const cancelCurrentRequest = React.useMemo( | |
// () => | |
// function cancelCurrentRequest() { | |
// if (loading) { | |
// requestAbortController.abort(); | |
// setError(false); | |
// setLoading(false); | |
// setData(resolvedRequests[resolvedKey]); | |
// } | |
// }, | |
// [requestAbortController, loading, resolvedKey] | |
// ); | |
;(0, react_1.useEffect)( | |
function () { | |
var signal = (requestAbortController || {}).signal | |
// Run onAbort callback | |
var abortCallback = function () { | |
var timeout = setTimeout(function () { | |
onAbort() | |
clearTimeout(timeout) | |
}) | |
} | |
signal === null || signal === void 0 | |
? void 0 | |
: signal.addEventListener("abort", abortCallback) | |
return function () { | |
signal === null || signal === void 0 | |
? void 0 | |
: signal.removeEventListener("abort", abortCallback) | |
} | |
}, | |
[requestAbortController, onAbort] | |
) | |
function reValidate() { | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
// Only revalidate if request was already completed | |
if (!loading) { | |
setLoading(true) | |
fetchData() | |
} | |
return [2 /*return*/] | |
}) | |
}) | |
} | |
;(0, react_1.useEffect)( | |
function () { | |
if (refresh > 0 && auto) { | |
var interval_2 = setTimeout(reValidate, refresh * 1000) | |
return function () { | |
return clearTimeout(interval_2) | |
} | |
} | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, | |
[refresh, loading, error, data, config] | |
) | |
;(0, react_1.useEffect)( | |
function () { | |
if (auto) { | |
setLoading(true) | |
fetchData() | |
} else { | |
setData(def) | |
setError(null) | |
setLoading(false) | |
} | |
// eslint-disable-next-line react-hooks/exhaustive-deps | |
}, | |
[url, refresh, JSON.stringify(config)] | |
) | |
return { | |
data: data, | |
loading: loading, | |
error: error, | |
code: statusCode, | |
reFetch: reValidate, | |
mutate: setData, | |
abort: function () { | |
requestAbortController.abort() | |
if (loading) { | |
setError(false) | |
setLoading(false) | |
setData(resolvedRequests[resolvedKey]) | |
} | |
}, | |
config: __assign(__assign({}, config), { url: url }) | |
} | |
} | |
/** | |
* Extend the useFetcher hook | |
*/ | |
useFetcher.extend = function extendFetcher(_a) { | |
var _b = _a === void 0 ? {} : _a, | |
_c = _b.baseUrl, | |
baseUrl = _c === void 0 ? "" : _c, | |
_d = _b.headers, | |
headers = _d === void 0 ? {} : _d, | |
_e = _b.body, | |
body = _e === void 0 ? {} : _e, | |
// json by default | |
_f = _b.resolver, | |
// json by default | |
resolver = | |
_f === void 0 | |
? function (d) { | |
return d.json() | |
} | |
: _f | |
function useCustomFetcher(_a) { | |
var _b = _a.url, | |
url = _b === void 0 ? "" : _b, | |
_c = _a.config, | |
config = _c === void 0 ? {} : _c, | |
otherProps = __rest(_a, ["url", "config"]) | |
return (0, useFetcher)( | |
__assign(__assign({}, otherProps), { | |
url: "".concat(baseUrl).concat(url), | |
// If resolver is present is hook call, use that instead | |
resolver: otherProps.resolver || resolver, | |
config: { | |
method: config.method, | |
headers: __assign(__assign({}, headers), config.headers), | |
body: __assign(__assign({}, body), config.body) | |
} | |
}) | |
) | |
} | |
useCustomFetcher.config = { | |
baseUrl: baseUrl, | |
headers: headers, | |
body: body | |
} | |
useCustomFetcher.Config = function FetcherConfig(_a) { | |
var children = _a.children, | |
_b = _a.defaults, | |
defaults = _b === void 0 ? {} : _b | |
if (defaults) { | |
for (var defaultKey in defaults) { | |
var url = "".concat(baseUrl).concat(defaultKey) | |
resolvedRequests[url] = defaults[defaultKey] | |
} | |
} | |
return children | |
} | |
return useCustomFetcher | |
} | |
var defaultConfig = { headers: {}, body: undefined } | |
/** | |
* Basic HttpClient | |
*/ | |
var HttpClient = /** @class */ (function () { | |
function HttpClient(url) { | |
this.baseUrl = "" | |
this.baseUrl = url | |
} | |
HttpClient.prototype.get = function (path, _a, method) { | |
var _b = _a === void 0 ? defaultConfig : _a, | |
headers = _b.headers, | |
body = _b.body | |
if (method === void 0) { | |
method = "GET" | |
} | |
return __awaiter(this, void 0, void 0, function () { | |
var requestUrl, responseBody, responseData | |
return __generator(this, function (_c) { | |
switch (_c.label) { | |
case 0: | |
requestUrl = "".concat(this.baseUrl).concat(path) | |
return [ | |
4 /*yield*/, | |
fetch( | |
requestUrl, | |
__assign( | |
{ | |
method: method, | |
headers: __assign( | |
{ | |
"Content-Type": "application/json", | |
Accept: "application/json" | |
}, | |
headers | |
) | |
}, | |
body ? { body: JSON.stringify(body) } : {} | |
) | |
) | |
] | |
case 1: | |
responseBody = _c.sent() | |
return [4 /*yield*/, responseBody.json()] | |
case 2: | |
responseData = _c.sent() | |
return [2 /*return*/, responseData] | |
} | |
}) | |
}) | |
} | |
HttpClient.prototype.post = function (path, props) { | |
if (props === void 0) { | |
props = defaultConfig | |
} | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
return [4 /*yield*/, this.get(path, props, "POST")] | |
case 1: | |
return [2 /*return*/, _a.sent()] | |
} | |
}) | |
}) | |
} | |
HttpClient.prototype.put = function (path, props) { | |
if (props === void 0) { | |
props = defaultConfig | |
} | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
return [4 /*yield*/, this.get(path, props, "PUT")] | |
case 1: | |
return [2 /*return*/, _a.sent()] | |
} | |
}) | |
}) | |
} | |
HttpClient.prototype.delete = function (path, props) { | |
if (props === void 0) { | |
props = defaultConfig | |
} | |
return __awaiter(this, void 0, void 0, function () { | |
return __generator(this, function (_a) { | |
switch (_a.label) { | |
case 0: | |
return [4 /*yield*/, this.get(path, props, "DELETE")] | |
case 1: | |
return [2 /*return*/, _a.sent()] | |
} | |
}) | |
}) | |
} | |
return HttpClient | |
})() | |
/** | |
* Creates a new HTTP client | |
*/ | |
function createHttpClient(url) { | |
return new HttpClient(url) | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
"use strict";var __assign=this&&this.__assign||function(){return(__assign=Object.assign||function(e){for(var t,n=1,r=arguments.length;n<r;n++)for(var o in t=arguments[n])Object.prototype.hasOwnProperty.call(t,o)&&(e[o]=t[o]);return e}).apply(this,arguments)},__awaiter=this&&this.__awaiter||function(e,t,n,r){return new(n||(n=Promise))(function(o,i){function a(e){try{u(r.next(e))}catch(e){i(e)}}function s(e){try{u(r.throw(e))}catch(e){i(e)}}function u(e){var t;e.done?o(e.value):(t=e.value,t instanceof n?t:new n(function(e){e(t)})).then(a,s)}u((r=r.apply(e,t||[])).next())})},__generator=this&&this.__generator||function(e,t){var n,r,o,i,a={label:0,sent:function(){if(1&o[0])throw o[1];return o[1]},trys:[],ops:[]};return i={next:s(0),throw:s(1),return:s(2)},"function"==typeof Symbol&&(i[Symbol.iterator]=function(){return this}),i;function s(i){return function(s){return function(i){if(n)throw new TypeError("Generator is already executing.");for(;a;)try{if(n=1,r&&(o=2&i[0]?r.return:i[0]?r.throw||((o=r.return)&&o.call(r),0):r.next)&&!(o=o.call(r,i[1])).done)return o;switch(r=0,o&&(i=[2&i[0],o.value]),i[0]){case 0:case 1:o=i;break;case 4:return a.label++,{value:i[1],done:!1};case 5:a.label++,r=i[1],i=[0];continue;case 7:i=a.ops.pop(),a.trys.pop();continue;default:if(!(o=(o=a.trys).length>0&&o[o.length-1])&&(6===i[0]||2===i[0])){a=0;continue}if(3===i[0]&&(!o||i[1]>o[0]&&i[1]<o[3])){a.label=i[1];break}if(6===i[0]&&a.label<o[1]){a.label=o[1],o=i;break}if(o&&a.label<o[2]){a.label=o[2],a.ops.push(i);break}o[2]&&a.ops.pop(),a.trys.pop();continue}i=t.call(e,a)}catch(e){i=[6,e],r=0}finally{n=o=0}if(5&i[0])throw i[1];return{value:i[0]?i[1]:void 0,done:!0}}([i,s])}}},__rest=this&&this.__rest||function(e,t){var n={};for(var r in e)Object.prototype.hasOwnProperty.call(e,r)&&t.indexOf(r)<0&&(n[r]=e[r]);if(null!=e&&"function"==typeof Object.getOwnPropertySymbols){var o=0;for(r=Object.getOwnPropertySymbols(e);o<r.length;o++)t.indexOf(r[o])<0&&Object.prototype.propertyIsEnumerable.call(e,r[o])&&(n[r[o]]=e[r[o]])}return n},react_1=React,Fetcher=function(e){var t=e.url,n=void 0===t?"/":t,r=e.default,o=e.config,i=void 0===o?{method:"GET",headers:{},body:{}}:o,a=e.children,s=e.onError,u=void 0===s?function(){}:s,c=e.onResolve,l=void 0===c?function(){}:c,f=e.refresh,d=void 0===f?0:f,v=(0,react_1.useState)(r),h=v[0],_=v[1],g=(0,react_1.useState)(null),p=g[0],b=g[1],y=(0,react_1.useState)(!0),w=y[0],m=y[1];function E(){var e;return __awaiter(this,void 0,void 0,function(){var t,o,a,s;return __generator(this,function(c){switch(c.label){case 0:return c.trys.push([0,3,4,5]),[4,fetch(n,{method:i.method,headers:__assign({"Content-Type":"application/json"},i.headers),body:(null===(e=i.method)||void 0===e?void 0:e.match(/(POST|PUT|DELETE)/))?JSON.stringify(i.body):void 0})];case 1:return[4,(t=c.sent()).json()];case 2:return o=c.sent(),(a=t.status)>=200&&a<300?(_(o),b(null),l(o)):(r&&_(r),b(!0),u(o)),[3,5];case 3:return s=c.sent(),_(void 0),b(new Error(s)),u(s),[3,5];case 4:return m(!1),[7];case 5:return[2]}})})}return(0,react_1.useEffect)(function(){if(d>0){var e=setTimeout(function(){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(e){return!h&&!p||w||(m(!0),E()),[2]})})},1e3*d);return function(){return clearTimeout(e)}}},[d,w,p,h,i]),(0,react_1.useEffect)(function(){m(!0),E()},[n,d,i]),void 0!==a?React.createElement(a,{data:h,error:p,loading:w}):null},resolvedRequests={};function FetcherConfig(e){var t=e.children,n=e.defaults,r=void 0===n?{}:n;if(r)for(var o in r)resolvedRequests[o]=r[o];return t}var useFetcher=function(e){var t=e.url,n=void 0===t?"/":t,r=e.default,o=e.config,i=void 0===o?{method:"GET",headers:{},body:{}}:o,a=e.resolver,s=void 0===a?function(e){return e.json()}:a,u=e.onError,c=void 0===u?function(){}:u,l=e.auto,f=void 0===l||l,d=e.memory,v=void 0===d||d,h=e.onResolve,_=void 0===h?function(){}:h,g=e.onAbort,p=void 0===g?function(){}:g,b=e.refresh,y=void 0===b?0:b,w=e.cancelOnChange,m=void 0!==w&&w,E=n.split("?")[0],T=(0,react_1.useState)(v&&resolvedRequests[E]||r),O=T[0],S=T[1],C=(0,react_1.useState)(),j=C[0],P=C[1],R=(0,react_1.useState)(null),x=R[0],U=R[1],q=(0,react_1.useState)(!0),F=q[0],L=q[1],k=(0,react_1.useState)(new AbortController),A=k[0],G=k[1];function J(){var e;return __awaiter(this,void 0,void 0,function(){var t,o,a,u,l;return __generator(this,function(f){switch(f.label){case 0:m&&(null==A||A.abort()),t=new AbortController,G(t),U(null),f.label=1;case 1:return f.trys.push([1,4,5,6]),[4,fetch(n,{signal:t.signal,method:i.method,headers:__assign({"Content-Type":"application/json"},i.headers),body:(null===(e=i.method)||void 0===e?void 0:e.match(/(POST|PUT|DELETE)/))?JSON.stringify(i.body):void 0})];case 2:return o=f.sent(),a=o.status,P(a),[4,s(o)];case 3:return u=f.sent(),a>=200&&a<400?(v&&(resolvedRequests[E]=u),S(u),U(null),_(u)):(r&&S(r),U(!0),c(u)),[3,6];case 4:return l=f.sent(),(null==l?void 0:l.toString()).match(/abort/i)?resolvedRequests[E]||S(r):(S(void 0),U(new Error(l)),c(l)),[3,6];case 5:return L(!1),[7];case 6:return[2]}})})}function N(){return __awaiter(this,void 0,void 0,function(){return __generator(this,function(e){return F||(L(!0),J()),[2]})})}return(0,react_1.useEffect)(function(){var e=(A||{}).signal,t=function(){var e=setTimeout(function(){p(),clearTimeout(e)})};return null==e||e.addEventListener("abort",t),function(){null==e||e.removeEventListener("abort",t)}},[A,p]),(0,react_1.useEffect)(function(){if(y>0&&f){var e=setTimeout(N,1e3*y);return function(){return clearTimeout(e)}}},[y,F,x,O,i]),(0,react_1.useEffect)(function(){f?(L(!0),J()):(S(r),U(null),L(!1))},[n,y,JSON.stringify(i)]),{data:O,loading:F,error:x,code:j,reFetch:N,mutate:S,abort:function(){A.abort(),F&&(U(!1),L(!1),S(resolvedRequests[E]))},config:__assign(__assign({},i),{url:n})}};useFetcher.extend=function(e){var t=void 0===e?{}:e,n=t.baseUrl,r=void 0===n?"":n,o=t.headers,i=void 0===o?{}:o,a=t.body,s=void 0===a?{}:a,u=t.resolver,c=void 0===u?function(e){return e.json()}:u;function l(e){var t=e.url,n=void 0===t?"":t,o=e.config,a=void 0===o?{}:o,u=__rest(e,["url","config"]);return useFetcher(__assign(__assign({},u),{url:"".concat(r).concat(n),resolver:u.resolver||c,config:{method:a.method,headers:__assign(__assign({},i),a.headers),body:__assign(__assign({},s),a.body)}}))}return l.config={baseUrl:r,headers:i,body:s},l.Config=function(e){var t=e.children,n=e.defaults,o=void 0===n?{}:n;if(o)for(var i in o){var a="".concat(r).concat(i);resolvedRequests[a]=o[i]}return t},l};var defaultConfig={headers:{},body:void 0},HttpClient=function(){function e(e){this.baseUrl="",this.baseUrl=e}return e.prototype.get=function(e,t,n){var r=void 0===t?defaultConfig:t,o=r.headers,i=r.body;return void 0===n&&(n="GET"),__awaiter(this,void 0,void 0,function(){var t;return __generator(this,function(r){switch(r.label){case 0:return t="".concat(this.baseUrl).concat(e),[4,fetch(t,__assign({method:n,headers:__assign({"Content-Type":"application/json",Accept:"application/json"},o)},i?{body:JSON.stringify(i)}:{}))];case 1:return[4,r.sent().json()];case 2:return[2,r.sent()]}})})},e.prototype.post=function(e,t){return void 0===t&&(t=defaultConfig),__awaiter(this,void 0,void 0,function(){return __generator(this,function(n){switch(n.label){case 0:return[4,this.get(e,t,"POST")];case 1:return[2,n.sent()]}})})},e.prototype.put=function(e,t){return void 0===t&&(t=defaultConfig),__awaiter(this,void 0,void 0,function(){return __generator(this,function(n){switch(n.label){case 0:return[4,this.get(e,t,"PUT")];case 1:return[2,n.sent()]}})})},e.prototype.delete=function(e,t){return void 0===t&&(t=defaultConfig),__awaiter(this,void 0,void 0,function(){return __generator(this,function(n){switch(n.label){case 0:return[4,this.get(e,t,"DELETE")];case 1:return[2,n.sent()]}})})},e}();function createHttpClient(e){return new HttpClient(e)} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<meta charset="UTF-8" /> | |
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> | |
<meta http-equiv="X-UA-Compatible" content="ie=edge" /> | |
<script | |
src="https://unpkg.com/react@18/umd/react.production.min.js" | |
crossorigin | |
></script> | |
<script | |
type="text/babel" | |
src="https://gist.githubusercontent.com/danybeltran/6057e377f94ff76110ce4c67d31dc34c/raw/c519f06daa647a4ffe16b39769a251363dbb43a4/[email protected]" | |
></script> | |
<script type="text/babel" src="https://gist.githubusercontent.com/danybeltran/4611694ba7c021f598025bef0a21a4ea/raw/[email protected]"></script> | |
<script | |
src="https://unpkg.com/react-dom@18/umd/react-dom.production.min.js" | |
crossorigin | |
></script> | |
<title>Static Template</title> | |
</head> | |
<body> | |
<div id="root"></div> | |
<script type="text/babel"> | |
const countAtom = atom({ | |
name: "counter" | |
// default: 0, | |
// localStoragePersistence: true | |
}) | |
function App() { | |
const [count, setCount] = useAtom(countAtom) | |
const { data } = useFetcher({ | |
url: "https://jsonplaceholder.typicode.com/todos/2" | |
}) | |
return ( | |
<div> | |
<h2>Atomic state in browser, {count}</h2> | |
<button | |
onClick={() => { | |
setCount((c) => c + 1) | |
}} | |
> | |
+ | |
</button> | |
<pre>{JSON.stringify(data, null, 2)}</pre> | |
</div> | |
) | |
} | |
const domContainer = document.querySelector("#root") | |
const root = ReactDOM.createRoot(domContainer) | |
root.render( | |
<AtomicState | |
atoms={{ | |
counter: 10 | |
}} | |
> | |
<App /> | |
</AtomicState> | |
) | |
</script> | |
<script src="https://unpkg.com/babel-standalone@6/babel.min.js"></script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment