UNPKG

@dynamic-labs/sdk-react-core

Version:

A React SDK for implementing wallet web3 authentication and authorization to your website.

94 lines (89 loc) 4.01 kB
'use client' 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _tslib = require('../../../../../_virtual/_tslib.cjs'); var React = require('react'); var logger = require('../../../shared/logger.cjs'); var resolveFetcher = require('./utils/resolveFetcher/resolveFetcher.cjs'); /** * Custom hook for handling promises and fetching data. * @template T - The type of the data returned by the promise. * @template E - The type of the error thrown by the promise. * @returns {PromiseState<T, E>} - The state object containing the data, error, loading status * and a callback to manually retrigger the promise. * @example * // Example usage with a simple fetcher function * const fetcher = fetch('https://api.example.com/data'); * * const MyComponent = () => { * const { data, isLoading, error } = usePromise(fetcher); * * if (isLoading) { * return <div>Loading...</div>; * } * * if (error) { * return <div>Error: {error.message}</div>; * } * * return <div>Data: {data}</div>; * }; */ const usePromise = ( /** A function that returns the data or a promise that resolves to the data */ fetcher, /** Options for the hook */ options) => { const lastCallTimestamp = React.useRef(new Date().getTime()); const { deps = [], initialData = undefined, enabled = true, retries = 0, } = options || {}; // Keep the callbacks updated regardless of when trigger is called const callbacks = React.useRef({ onBeforeFetch: options === null || options === void 0 ? void 0 : options.onBeforeFetch, onReject: options === null || options === void 0 ? void 0 : options.onReject, onResolve: options === null || options === void 0 ? void 0 : options.onResolve, }); callbacks.current = { onBeforeFetch: options === null || options === void 0 ? void 0 : options.onBeforeFetch, onReject: options === null || options === void 0 ? void 0 : options.onReject, onResolve: options === null || options === void 0 ? void 0 : options.onResolve, }; const [data, setData] = React.useState(initialData); const [isLoading, setIsLoading] = React.useState(enabled); const [error, setError] = React.useState(undefined); const trigger = React.useCallback(() => _tslib.__awaiter(void 0, void 0, void 0, function* () { var _a, _b; const callTimestamp = new Date().getTime(); const diffFromLastCall = callTimestamp - lastCallTimestamp.current; if (diffFromLastCall < 5) { logger.logger.logVerboseTroubleshootingMessage('usePromise: Fetcher function was called in very quick succession. Please make sure the fetcher function is not synchronous and that you are not calling it inside a loop.', deps); } lastCallTimestamp.current = callTimestamp; setIsLoading(true); (_b = (_a = callbacks.current).onBeforeFetch) === null || _b === void 0 ? void 0 : _b.call(_a); return resolveFetcher.resolveFetcher(fetcher, { retries }, (resultError, resultData) => { var _a, _b, _c, _d; if (callTimestamp !== lastCallTimestamp.current) return; if (resultError) { logger.logger.error(resultError); setError(resultError); (_b = (_a = callbacks.current).onReject) === null || _b === void 0 ? void 0 : _b.call(_a, resultError); return; } setData(resultData); (_d = (_c = callbacks.current).onResolve) === null || _d === void 0 ? void 0 : _d.call(_c, resultData); }).finally(() => setIsLoading(false)); // eslint-disable-next-line react-hooks/exhaustive-deps }), deps); React.useEffect(() => { if (enabled) trigger(); }, [trigger, enabled]); return React.useMemo(() => ({ data: data, error, isLoading, retrigger: trigger, }), [data, error, isLoading, trigger]); }; exports.usePromise = usePromise;