| 1 |
import useSWR from 'swr'; |
| 2 |
import lagData from './hooks/lagData'; |
| 3 |
import useFallbackAsInitial from '@givewp/components/ListTable/hooks/useFallbackAsInitial'; |
| 4 |
|
| 5 |
export default class ListTableApi { |
| 6 |
private readonly apiRoot: string; |
| 7 |
private controller: AbortController | null; |
| 8 |
private readonly headers: {'X-WP-Nonce': string; 'Content-Type': string}; |
| 9 |
private readonly swrOptions; |
| 10 |
|
| 11 |
constructor({apiNonce, apiRoot, preload = null, swrConfig = {}}) { |
| 12 |
this.controller = null; |
| 13 |
this.apiRoot = apiRoot; |
| 14 |
this.headers = { |
| 15 |
'Content-Type': 'application/json', |
| 16 |
'X-WP-Nonce': apiNonce, |
| 17 |
}; |
| 18 |
this.swrOptions = { |
| 19 |
use: [lagData], |
| 20 |
...swrConfig, |
| 21 |
onErrorRetry: (error, key, config, revalidate, {retryCount}) => { |
| 22 |
//don't retry if we cancelled the initial request |
| 23 |
if (error.name == 'AbortError') return; |
| 24 |
if (retryCount >= 5) return; |
| 25 |
const retryAfter = (retryCount + 1) * 500; |
| 26 |
setTimeout(() => revalidate({retryCount}), retryAfter); |
| 27 |
}, |
| 28 |
}; |
| 29 |
if (preload) { |
| 30 |
this.swrOptions.fallbackData = preload; |
| 31 |
this.swrOptions.use.push(useFallbackAsInitial); |
| 32 |
} |
| 33 |
} |
| 34 |
|
| 35 |
fetchWithArgs = (endpoint, args, method = 'GET', signal = null) => { |
| 36 |
const url = new URL(this.apiRoot + endpoint); |
| 37 |
for (const [param, value] of Object.entries(args)) { |
| 38 |
value !== '' && url.searchParams.set(param, value as string); |
| 39 |
} |
| 40 |
return fetch(url.href, { |
| 41 |
method: method, |
| 42 |
signal: signal, |
| 43 |
headers: this.headers, |
| 44 |
}).then((res) => { |
| 45 |
if (!res.ok) { |
| 46 |
return res.text().then((errorMessage) => { |
| 47 |
throw new Error(errorMessage); |
| 48 |
}); |
| 49 |
} |
| 50 |
return res.json(); |
| 51 |
}); |
| 52 |
}; |
| 53 |
|
| 54 |
fetcher = (params) => { |
| 55 |
if (this.controller instanceof AbortController) this.controller.abort(); |
| 56 |
this.controller = new AbortController(); |
| 57 |
return this.fetchWithArgs('', params, 'GET', this.controller.signal); |
| 58 |
}; |
| 59 |
|
| 60 |
// SWR Fetcher |
| 61 |
useListTable = ({page, perPage, sortColumn, sortDirection, locale, testMode, ...filters}) => { |
| 62 |
const {data, error, mutate, isValidating} = useSWR( |
| 63 |
{ |
| 64 |
page, |
| 65 |
perPage, |
| 66 |
sortColumn, |
| 67 |
sortDirection, |
| 68 |
locale, |
| 69 |
testMode, |
| 70 |
...filters, |
| 71 |
}, |
| 72 |
this.fetcher, |
| 73 |
this.swrOptions |
| 74 |
); |
| 75 |
return {data, error, mutate, isValidating}; |
| 76 |
}; |
| 77 |
|
| 78 |
useStats = (testMode) => { |
| 79 |
const {data, error, mutate, isValidating} = useSWR( |
| 80 |
{testMode}, |
| 81 |
(params) => this.fetchWithArgs('/stats', params, 'GET'), |
| 82 |
this.swrOptions |
| 83 |
); |
| 84 |
return {data, error, mutate, isValidating}; |
| 85 |
}; |
| 86 |
} |
| 87 |
|