1 | import unfetch from 'isomorphic-unfetch';
|
2 | import lru from 'tiny-lru';
|
3 | import { FetchError } from './errors';
|
4 | import { log } from './log';
|
5 |
|
6 | const maxItems = 250;
|
7 | const fiveMinutesTTL = 5 * 60 * 1000;
|
8 | const cache = lru(maxItems, fiveMinutesTTL);
|
9 |
|
10 | export async function fetch({
|
11 | url,
|
12 | cached = true,
|
13 | }: {
|
14 | url: string;
|
15 | cached?: boolean;
|
16 | }): Promise<any> {
|
17 | const cachedJSON = cache.get(url);
|
18 | if (cached && cachedJSON) {
|
19 | log('fetch: returning cached response: %O', { url, cachedJSON });
|
20 | return cachedJSON;
|
21 | }
|
22 |
|
23 | const response = await unfetch(url);
|
24 | if (!response.ok) {
|
25 | log('fetch: request failed: %O', {
|
26 | url,
|
27 | status: response.statusText,
|
28 | response,
|
29 | });
|
30 | throw new FetchError(url, response);
|
31 | }
|
32 |
|
33 | const json = await response.json();
|
34 | if (cached) {
|
35 | cache.set(url, json);
|
36 | }
|
37 |
|
38 | log('fetch: returning fresh response: %O', { url, json });
|
39 | return json;
|
40 | }
|