"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.FETCH_STATUS = void 0; exports.useFetcher = useFetcher; var _react = require("react"); /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0; you may not use this file except in compliance with the Elastic License * 2.0. */ let FETCH_STATUS; exports.FETCH_STATUS = FETCH_STATUS; (function (FETCH_STATUS) { FETCH_STATUS["LOADING"] = "loading"; FETCH_STATUS["SUCCESS"] = "success"; FETCH_STATUS["FAILURE"] = "failure"; FETCH_STATUS["PENDING"] = "pending"; FETCH_STATUS["NOT_INITIATED"] = "not_initiated"; })(FETCH_STATUS || (exports.FETCH_STATUS = FETCH_STATUS = {})); function useFetcher(fn, fnDeps, options = {}) { const { preservePreviousData = true } = options; const [result, setResult] = (0, _react.useState)({ data: undefined, status: FETCH_STATUS.PENDING, loading: true }); const [counter, setCounter] = (0, _react.useState)(0); (0, _react.useEffect)(() => { let controller = new AbortController(); async function doFetch() { controller.abort(); controller = new AbortController(); const signal = controller.signal; const promise = fn({ signal }); if (!promise) { setResult(prevResult => ({ ...prevResult, status: FETCH_STATUS.NOT_INITIATED })); return; } setResult(prevResult => ({ data: preservePreviousData ? prevResult.data : undefined, status: FETCH_STATUS.LOADING, error: undefined, loading: true })); try { const data = await promise; // when http fetches are aborted, the promise will be rejected // and this code is never reached. For async operations that are // not cancellable, we need to check whether the signal was // aborted before updating the result. if (!signal.aborted) { setResult({ data, loading: false, status: FETCH_STATUS.SUCCESS, error: undefined }); } } catch (e) { if (!signal.aborted) { setResult(prevResult => ({ data: preservePreviousData ? prevResult.data : undefined, status: FETCH_STATUS.FAILURE, error: e, loading: false })); } } } doFetch(); return () => { controller.abort(); }; // eslint-disable-next-line react-hooks/exhaustive-deps }, [counter, ...fnDeps]); return (0, _react.useMemo)(() => { return { ...result, loading: result.status === FETCH_STATUS.LOADING || result.status === FETCH_STATUS.PENDING, refetch: () => { // this will invalidate the deps to `useEffect` and will result in a new request setCounter(count => count + 1); } }; }, [result]); }