async-fetch 0.2.8 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +4 -8
- package/useAsyncFetch.js +18 -21
- package/useCache.js +6 -16
- package/useInterval.js +2 -3
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# useAsyncFetch
|
|
2
2
|
|
|
3
|
-
Use fetch
|
|
3
|
+
Use fetch for requests within React components.
|
|
4
4
|
|
|
5
5
|
## Installation
|
|
6
6
|
|
|
@@ -18,7 +18,7 @@ import useAsyncFetch from "async-fetch";
|
|
|
18
18
|
|
|
19
19
|
function App() {
|
|
20
20
|
const { pending, data, error, sendRequest, cancelRequest } = useAsyncFetch(
|
|
21
|
-
"https://jsonplaceholder.typicode.com/todos/1"
|
|
21
|
+
"https://jsonplaceholder.typicode.com/todos/1",
|
|
22
22
|
);
|
|
23
23
|
|
|
24
24
|
return (
|
package/package.json
CHANGED
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "async-fetch",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "Use fetch
|
|
3
|
+
"version": "0.3.0",
|
|
4
|
+
"description": "Use fetch for requests within React components.",
|
|
5
5
|
"main": "useAsyncFetch.js",
|
|
6
6
|
"type": "module",
|
|
7
|
-
"scripts": {
|
|
8
|
-
"test": "echo \"Error: no test specified\" && exit 1"
|
|
9
|
-
},
|
|
7
|
+
"scripts": {},
|
|
10
8
|
"repository": {
|
|
11
9
|
"type": "git",
|
|
12
10
|
"url": "git+https://github.com/nameer-rizvi/useAsyncFetch.git"
|
|
@@ -19,8 +17,6 @@
|
|
|
19
17
|
],
|
|
20
18
|
"author": "Nameer Rizvi (https://github.com/nameer-rizvi)",
|
|
21
19
|
"license": "ISC",
|
|
22
|
-
"bugs":
|
|
23
|
-
"url": "https://github.com/nameer-rizvi/useAsyncFetch/issues"
|
|
24
|
-
},
|
|
20
|
+
"bugs": "https://github.com/nameer-rizvi/useAsyncFetch/issues",
|
|
25
21
|
"homepage": "https://github.com/nameer-rizvi/useAsyncFetch#readme"
|
|
26
22
|
}
|
package/useAsyncFetch.js
CHANGED
|
@@ -2,7 +2,7 @@ import { useState, useEffect } from "react";
|
|
|
2
2
|
import useCache from "./useCache.js";
|
|
3
3
|
import useInterval from "./useInterval.js";
|
|
4
4
|
|
|
5
|
-
function useAsyncFetch(
|
|
5
|
+
function useAsyncFetch(requestURL, props = {}) {
|
|
6
6
|
const {
|
|
7
7
|
initialPending,
|
|
8
8
|
initialData,
|
|
@@ -10,7 +10,7 @@ function useAsyncFetch(path, props = {}) {
|
|
|
10
10
|
deps = [],
|
|
11
11
|
poll,
|
|
12
12
|
cachetime = 60000, // 1 minute.
|
|
13
|
-
timeout = 30000, //
|
|
13
|
+
timeout = 30000, // 30 seconds.
|
|
14
14
|
ignoreCleanup,
|
|
15
15
|
ignoreRequest,
|
|
16
16
|
query,
|
|
@@ -62,10 +62,15 @@ function useAsyncFetch(path, props = {}) {
|
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
async function sendRequest(constant) {
|
|
65
|
-
if (!
|
|
65
|
+
if (!requestURL) {
|
|
66
|
+
throw new Error("URL is required.");
|
|
67
|
+
}
|
|
66
68
|
|
|
67
|
-
if (typeof
|
|
69
|
+
if (typeof requestURL !== "string") {
|
|
68
70
|
throw new Error("URL must be of type string.");
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
const url = new URL(requestURL);
|
|
69
74
|
|
|
70
75
|
if (ignoreRequest !== true) {
|
|
71
76
|
const controller = new AbortController();
|
|
@@ -77,51 +82,43 @@ function useAsyncFetch(path, props = {}) {
|
|
|
77
82
|
}, timeout);
|
|
78
83
|
|
|
79
84
|
try {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
if (query || params) {
|
|
83
|
-
if (!path.endsWith("?")) q += "?";
|
|
84
|
-
q += new URLSearchParams(query || params).toString();
|
|
85
|
-
}
|
|
85
|
+
if (query || params) url.search = new URLSearchParams(query || params);
|
|
86
86
|
|
|
87
87
|
const contentType =
|
|
88
88
|
fetchProps.headers?.["Content-Type"] ||
|
|
89
89
|
fetchProps.headers?.["content-type"];
|
|
90
90
|
|
|
91
91
|
if (contentType === "application/x-www-form-urlencoded") {
|
|
92
|
-
fetchProps.body = new URLSearchParams(data2 || {})
|
|
92
|
+
fetchProps.body = new URLSearchParams(data2 || {});
|
|
93
93
|
} else if (data2) {
|
|
94
94
|
fetchProps.body = JSON.stringify(data2);
|
|
95
95
|
}
|
|
96
96
|
|
|
97
97
|
if (!unmounted) {
|
|
98
|
-
if (pending)
|
|
99
|
-
|
|
100
|
-
} else setPending(true);
|
|
98
|
+
if (pending) setPending2(true);
|
|
99
|
+
if (!pending) setPending(true);
|
|
101
100
|
setError();
|
|
102
101
|
cancelRequest();
|
|
103
102
|
setCancelSource(controller);
|
|
104
103
|
if (onStart) onStart();
|
|
105
104
|
}
|
|
106
105
|
|
|
107
|
-
const
|
|
108
|
-
|
|
109
|
-
const cachedResponse =
|
|
110
|
-
constant === "USE_CACHE" && cache.get(url, fetchProps);
|
|
106
|
+
const cachedResponse = constant === "USE_CACHE" && cache.get(url.href);
|
|
111
107
|
|
|
112
108
|
let parsedResponse = cachedResponse;
|
|
113
109
|
|
|
114
110
|
if (!parsedResponse) {
|
|
115
111
|
const response = await fetch(url, fetchProps);
|
|
116
112
|
|
|
117
|
-
if (!response.ok)
|
|
113
|
+
if (!response.ok) {
|
|
118
114
|
throw new Error(
|
|
119
115
|
JSON.stringify({
|
|
120
116
|
code: response.status,
|
|
121
117
|
text: response.statusText,
|
|
122
118
|
response: await response.text(),
|
|
123
|
-
})
|
|
119
|
+
}),
|
|
124
120
|
);
|
|
121
|
+
}
|
|
125
122
|
|
|
126
123
|
parsedResponse = await response[parser]();
|
|
127
124
|
}
|
|
@@ -129,7 +126,7 @@ function useAsyncFetch(path, props = {}) {
|
|
|
129
126
|
if (!unmounted) {
|
|
130
127
|
setData(parsedResponse);
|
|
131
128
|
if (onSuccess) onSuccess(parsedResponse);
|
|
132
|
-
if (!cachedResponse) cache.set(url,
|
|
129
|
+
if (!cachedResponse) cache.set(url, parsedResponse);
|
|
133
130
|
}
|
|
134
131
|
} catch (e) {
|
|
135
132
|
if (!unmounted && e.name !== "AbortError") {
|
package/useCache.js
CHANGED
|
@@ -4,27 +4,17 @@ const cache = {};
|
|
|
4
4
|
|
|
5
5
|
function useCache(cachetime) {
|
|
6
6
|
useInterval(() => {
|
|
7
|
-
for (let [key, value] of Object.entries(cache))
|
|
7
|
+
for (let [key, value] of Object.entries(cache)) {
|
|
8
8
|
if (value.timestamp + cachetime < new Date().getTime()) delete cache[key];
|
|
9
|
+
}
|
|
9
10
|
}, cachetime);
|
|
10
11
|
|
|
11
|
-
function
|
|
12
|
-
|
|
12
|
+
function get(url) {
|
|
13
|
+
if (cachetime) return cache[url]?.response;
|
|
13
14
|
}
|
|
14
15
|
|
|
15
|
-
function
|
|
16
|
-
if (cachetime) {
|
|
17
|
-
const key = makeKey(url, fetchProps);
|
|
18
|
-
return cache[key]?.response;
|
|
19
|
-
}
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
function set(url, fetchProps, response) {
|
|
23
|
-
if (cachetime) {
|
|
24
|
-
const key = makeKey(url, fetchProps);
|
|
25
|
-
const payload = { timestamp: new Date().getTime(), response };
|
|
26
|
-
cache[key] = payload;
|
|
27
|
-
}
|
|
16
|
+
function set(url, response) {
|
|
17
|
+
if (cachetime) cache[url] = { timestamp: new Date().getTime(), response };
|
|
28
18
|
}
|
|
29
19
|
|
|
30
20
|
return { get, set };
|
package/useInterval.js
CHANGED
|
@@ -8,9 +8,8 @@ function useInterval(callback, poll) {
|
|
|
8
8
|
});
|
|
9
9
|
|
|
10
10
|
useEffect(() => {
|
|
11
|
-
if (
|
|
12
|
-
const
|
|
13
|
-
const interval = setInterval(onTick, poll);
|
|
11
|
+
if (typeof poll !== "number") return;
|
|
12
|
+
const interval = setInterval(() => callbackRef.current(), poll);
|
|
14
13
|
return () => {
|
|
15
14
|
clearInterval(interval);
|
|
16
15
|
};
|