1 | import unfetch from 'isomorphic-unfetch';
|
2 | import lru from 'tiny-lru';
|
3 | import { FetchError } from './errors.esm.js';
|
4 | import { log } from './log.esm.js';
|
5 |
|
6 | const maxItems = 250;
|
7 | const fiveMinutesTTL = 5 * 60 * 1000;
|
8 | const cache = lru(maxItems, fiveMinutesTTL);
|
9 | async function fetch({
|
10 | url,
|
11 | headers,
|
12 | cached = true
|
13 | }) {
|
14 | const cacheKey = `headers=${JSON.stringify(headers)};url=${url}`;
|
15 | const cachedJSON = cache.get(cacheKey);
|
16 |
|
17 | if (cached && cachedJSON) {
|
18 | log('fetch: returning cached response: %O', {
|
19 | cacheKey,
|
20 | url,
|
21 | cachedJSON
|
22 | });
|
23 | return cachedJSON;
|
24 | }
|
25 |
|
26 | const response = await unfetch(url, {
|
27 | headers
|
28 | });
|
29 |
|
30 | if (!response.ok) {
|
31 | log('fetch: request failed: %O', {
|
32 | url,
|
33 | headers,
|
34 | status: response.statusText,
|
35 | response
|
36 | });
|
37 | throw new FetchError(url, response);
|
38 | }
|
39 |
|
40 | const json = await response.json();
|
41 |
|
42 | if (cached) {
|
43 | cache.set(cacheKey, json);
|
44 | }
|
45 |
|
46 | log('fetch: returning fresh response: %O', {
|
47 | url,
|
48 | json
|
49 | });
|
50 | return json;
|
51 | }
|
52 |
|
53 | export { fetch };
|
54 |
|