UNPKG

@data-client/react

Version:

Async State Management without the Management. REST, GraphQL, SSE, Websockets, Fetch

57 lines (51 loc) 8.86 kB
import { ExpiryStatus } from '@data-client/core'; import { useEffect, useMemo } from 'react'; import useCacheState from './useCacheState.js'; import useController from './useController.js'; /** * Ensure an endpoint is available. * Suspends until it is. * * `useSuspense` guarantees referential equality globally. * @see https://dataclient.io/docs/api/useSuspense * @throws {Promise} If data is not yet available. * @throws {NetworkError} If fetch fails. */ export default function useSuspense(endpoint, ...args) { const state = useCacheState(); const controller = useController(); const key = args[0] !== null ? endpoint.key(...args) : ''; const cacheResults = key && state.endpoints[key]; const meta = state.meta[key]; // Compute denormalized value const { data, expiryStatus, expiresAt, countRef } = useMemo(() => { return controller.getResponseMeta(endpoint, ...args, state); // eslint-disable-next-line react-hooks/exhaustive-deps }, [cacheResults, state.indexes, state.entities, state.entityMeta, meta, key]); // If we are hard invalid we must fetch regardless of triggering or staleness const forceFetch = expiryStatus === ExpiryStatus.Invalid; const maybePromise = useMemo(() => { // null params mean don't do anything if (Date.now() <= expiresAt && !forceFetch || !key) return; return controller // if args is [null], we won't get to this line .fetch(endpoint, ...args).catch(() => {}); // we need to check against serialized params, since params can change frequently // eslint-disable-next-line react-hooks/exhaustive-deps }, [expiresAt, key, forceFetch, state.lastReset]); // fully "valid" data will not suspend even if it is not fresh if (expiryStatus !== ExpiryStatus.Valid && maybePromise) { throw maybePromise; } const error = controller.getError(endpoint, ...args, state); if (error) throw error; // eslint-disable-next-line react-hooks/exhaustive-deps useEffect(countRef, [data]); return data; } //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJFeHBpcnlTdGF0dXMiLCJ1c2VFZmZlY3QiLCJ1c2VNZW1vIiwidXNlQ2FjaGVTdGF0ZSIsInVzZUNvbnRyb2xsZXIiLCJ1c2VTdXNwZW5zZSIsImVuZHBvaW50IiwiYXJncyIsInN0YXRlIiwiY29udHJvbGxlciIsImtleSIsImNhY2hlUmVzdWx0cyIsImVuZHBvaW50cyIsIm1ldGEiLCJkYXRhIiwiZXhwaXJ5U3RhdHVzIiwiZXhwaXJlc0F0IiwiY291bnRSZWYiLCJnZXRSZXNwb25zZU1ldGEiLCJpbmRleGVzIiwiZW50aXRpZXMiLCJlbnRpdHlNZXRhIiwiZm9yY2VGZXRjaCIsIkludmFsaWQiLCJtYXliZVByb21pc2UiLCJEYXRlIiwibm93IiwiZmV0Y2giLCJjYXRjaCIsImxhc3RSZXNldCIsIlZhbGlkIiwiZXJyb3IiLCJnZXRFcnJvciJdLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9ob29rcy91c2VTdXNwZW5zZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBFeHBpcnlTdGF0dXMgfSBmcm9tICdAZGF0YS1jbGllbnQvY29yZSc7XG5pbXBvcnQgdHlwZSB7XG4gIEVuZHBvaW50SW50ZXJmYWNlLFxuICBEZW5vcm1hbGl6ZSxcbiAgU2NoZW1hLFxuICBGZXRjaEZ1bmN0aW9uLFxuICBEZW5vcm1hbGl6ZU51bGxhYmxlLFxuICBSZXNvbHZlVHlwZSxcbn0gZnJvbSAnQGRhdGEtY2xpZW50L2NvcmUnO1xuaW1wb3J0IHsgdXNlRWZmZWN0LCB1c2VNZW1vIH0gZnJvbSAncmVhY3QnO1xuXG5pbXBvcnQgdXNlQ2FjaGVTdGF0ZSBmcm9tICcuL3VzZUNhY2hlU3RhdGUuanMnO1xuaW1wb3J0IHVzZUNvbnRyb2xsZXIgZnJvbSAnLi91c2VDb250cm9sbGVyLmpzJztcblxuLyoqXG4gKiBFbnN1cmUgYW4gZW5kcG9pbnQgaXMgYXZhaWxhYmxlLlxuICogU3VzcGVuZHMgdW50aWwgaXQgaXMuXG4gKlxuICogYHVzZVN1c3BlbnNlYCBndWFyYW50ZWVzIHJlZmVyZW50aWFsIGVxdWFsaXR5IGdsb2JhbGx5LlxuICogQHNlZSBodHRwczovL2RhdGFjbGllbnQuaW8vZG9jcy9hcGkvdXNlU3VzcGVuc2VcbiAqIEB0aHJvd3Mge1Byb21pc2V9IElmIGRhdGEgaXMgbm90IHlldCBhdmFpbGFibGUuXG4gKiBAdGhyb3dzIHtOZXR3b3JrRXJyb3J9IElmIGZldGNoIGZhaWxzLlxuICovXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VTdXNwZW5zZTxcbiAgRSBleHRlbmRzIEVuZHBvaW50SW50ZXJmYWNlPFxuICAgIEZldGNoRnVuY3Rpb24sXG4gICAgU2NoZW1hIHwgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCB8IGZhbHNlXG4gID4sXG4+KFxuICBlbmRwb2ludDogRSxcbiAgLi4uYXJnczogcmVhZG9ubHkgWy4uLlBhcmFtZXRlcnM8RT5dXG4pOiBFWydzY2hlbWEnXSBleHRlbmRzIHVuZGVmaW5lZCB8IG51bGwgPyBSZXNvbHZlVHlwZTxFPlxuOiBEZW5vcm1hbGl6ZTxFWydzY2hlbWEnXT47XG5cbmV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIHVzZVN1c3BlbnNlPFxuICBFIGV4dGVuZHMgRW5kcG9pbnRJbnRlcmZhY2U8XG4gICAgRmV0Y2hGdW5jdGlvbixcbiAgICBTY2hlbWEgfCB1bmRlZmluZWQsXG4gICAgdW5kZWZpbmVkIHwgZmFsc2VcbiAgPixcbj4oXG4gIGVuZHBvaW50OiBFLFxuICAuLi5hcmdzOiByZWFkb25seSBbLi4uUGFyYW1ldGVyczxFPl0gfCByZWFkb25seSBbbnVsbF1cbik6IEVbJ3NjaGVtYSddIGV4dGVuZHMgdW5kZWZpbmVkIHwgbnVsbCA/IFJlc29sdmVUeXBlPEU+IHwgdW5kZWZpbmVkXG46IERlbm9ybWFsaXplTnVsbGFibGU8RVsnc2NoZW1hJ10+O1xuXG5leHBvcnQgZGVmYXVsdCBmdW5jdGlvbiB1c2VTdXNwZW5zZTxcbiAgRSBleHRlbmRzIEVuZHBvaW50SW50ZXJmYWNlPFxuICAgIEZldGNoRnVuY3Rpb24sXG4gICAgU2NoZW1hIHwgdW5kZWZpbmVkLFxuICAgIHVuZGVmaW5lZCB8IGZhbHNlXG4gID4sXG4+KGVuZHBvaW50OiBFLCAuLi5hcmdzOiByZWFkb25seSBbLi4uUGFyYW1ldGVyczxFPl0gfCByZWFkb25seSBbbnVsbF0pOiBhbnkge1xuICBjb25zdCBzdGF0ZSA9IHVzZUNhY2hlU3RhdGUoKTtcbiAgY29uc3QgY29udHJvbGxlciA9IHVzZUNvbnRyb2xsZXIoKTtcblxuICBjb25zdCBrZXkgPSBhcmdzWzBdICE9PSBudWxsID8gZW5kcG9pbnQua2V5KC4uLmFyZ3MpIDogJyc7XG4gIGNvbnN0IGNhY2hlUmVzdWx0cyA9IGtleSAmJiBzdGF0ZS5lbmRwb2ludHNba2V5XTtcbiAgY29uc3QgbWV0YSA9IHN0YXRlLm1ldGFba2V5XTtcblxuICAvLyBDb21wdXRlIGRlbm9ybWFsaXplZCB2YWx1ZVxuICBjb25zdCB7IGRhdGEsIGV4cGlyeVN0YXR1cywgZXhwaXJlc0F0LCBjb3VudFJlZiB9ID0gdXNlTWVtbygoKSA9PiB7XG4gICAgcmV0dXJuIGNvbnRyb2xsZXIuZ2V0UmVzcG9uc2VNZXRhKGVuZHBvaW50LCAuLi5hcmdzLCBzdGF0ZSk7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIHJlYWN0LWhvb2tzL2V4aGF1c3RpdmUtZGVwc1xuICB9LCBbXG4gICAgY2FjaGVSZXN1bHRzLFxuICAgIHN0YXRlLmluZGV4ZXMsXG4gICAgc3RhdGUuZW50aXRpZXMsXG4gICAgc3RhdGUuZW50aXR5TWV0YSxcbiAgICBtZXRhLFxuICAgIGtleSxcbiAgXSk7XG5cbiAgLy8gSWYgd2UgYXJlIGhhcmQgaW52YWxpZCB3ZSBtdXN0IGZldGNoIHJlZ2FyZGxlc3Mgb2YgdHJpZ2dlcmluZyBvciBzdGFsZW5lc3NcbiAgY29uc3QgZm9yY2VGZXRjaCA9IGV4cGlyeVN0YXR1cyA9PT0gRXhwaXJ5U3RhdHVzLkludmFsaWQ7XG5cbiAgY29uc3QgbWF5YmVQcm9taXNlID0gdXNlTWVtbygoKSA9PiB7XG4gICAgLy8gbnVsbCBwYXJhbXMgbWVhbiBkb24ndCBkbyBhbnl0aGluZ1xuICAgIGlmICgoRGF0ZS5ub3coKSA8PSBleHBpcmVzQXQgJiYgIWZvcmNlRmV0Y2gpIHx8ICFrZXkpIHJldHVybjtcblxuICAgIHJldHVybiAoXG4gICAgICBjb250cm9sbGVyXG4gICAgICAgIC8vIGlmIGFyZ3MgaXMgW251bGxdLCB3ZSB3b24ndCBnZXQgdG8gdGhpcyBsaW5lXG4gICAgICAgIC5mZXRjaChlbmRwb2ludCwgLi4uKGFyZ3MgYXMgUGFyYW1ldGVyczxFPikpXG4gICAgICAgIC5jYXRjaCgoKSA9PiB7fSlcbiAgICApO1xuICAgIC8vIHdlIG5lZWQgdG8gY2hlY2sgYWdhaW5zdCBzZXJpYWxpemVkIHBhcmFtcywgc2luY2UgcGFyYW1zIGNhbiBjaGFuZ2UgZnJlcXVlbnRseVxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgfSwgW2V4cGlyZXNBdCwga2V5LCBmb3JjZUZldGNoLCBzdGF0ZS5sYXN0UmVzZXRdKTtcblxuICAvLyBmdWxseSBcInZhbGlkXCIgZGF0YSB3aWxsIG5vdCBzdXNwZW5kIGV2ZW4gaWYgaXQgaXMgbm90IGZyZXNoXG4gIGlmIChleHBpcnlTdGF0dXMgIT09IEV4cGlyeVN0YXR1cy5WYWxpZCAmJiBtYXliZVByb21pc2UpIHtcbiAgICB0aHJvdyBtYXliZVByb21pc2U7XG4gIH1cblxuICBjb25zdCBlcnJvciA9IGNvbnRyb2xsZXIuZ2V0RXJyb3IoZW5kcG9pbnQsIC4uLmFyZ3MsIHN0YXRlKTtcblxuICBpZiAoZXJyb3IpIHRocm93IGVycm9yO1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSByZWFjdC1ob29rcy9leGhhdXN0aXZlLWRlcHNcbiAgdXNlRWZmZWN0KGNvdW50UmVmLCBbZGF0YV0pO1xuXG4gIHJldHVybiBkYXRhO1xufVxuIl0sIm1hcHBpbmdzIjoiQUFBQSxTQUFTQSxZQUFZLFFBQVEsbUJBQW1CO0FBU2hELFNBQVNDLFNBQVMsRUFBRUMsT0FBTyxRQUFRLE9BQU87QUFFMUMsT0FBT0MsYUFBYSxNQUFNLG9CQUFvQjtBQUM5QyxPQUFPQyxhQUFhLE1BQU0sb0JBQW9COztBQUU5QztBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBeUJBLGVBQWUsU0FBU0MsV0FBV0EsQ0FNakNDLFFBQVcsRUFBRSxHQUFHQyxJQUFtRCxFQUFPO0VBQzFFLE1BQU1DLEtBQUssR0FBR0wsYUFBYSxDQUFDLENBQUM7RUFDN0IsTUFBTU0sVUFBVSxHQUFHTCxhQUFhLENBQUMsQ0FBQztFQUVsQyxNQUFNTSxHQUFHLEdBQUdILElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEdBQUdELFFBQVEsQ0FBQ0ksR0FBRyxDQUFDLEdBQUdILElBQUksQ0FBQyxHQUFHLEVBQUU7RUFDekQsTUFBTUksWUFBWSxHQUFHRCxHQUFHLElBQUlGLEtBQUssQ0FBQ0ksU0FBUyxDQUFDRixHQUFHLENBQUM7RUFDaEQsTUFBTUcsSUFBSSxHQUFHTCxLQUFLLENBQUNLLElBQUksQ0FBQ0gsR0FBRyxDQUFDOztFQUU1QjtFQUNBLE1BQU07SUFBRUksSUFBSTtJQUFFQyxZQUFZO0lBQUVDLFNBQVM7SUFBRUM7RUFBUyxDQUFDLEdBQUdmLE9BQU8sQ0FBQyxNQUFNO0lBQ2hFLE9BQU9PLFVBQVUsQ0FBQ1MsZUFBZSxDQUFDWixRQUFRLEVBQUUsR0FBR0MsSUFBSSxFQUFFQyxLQUFLLENBQUM7SUFDM0Q7RUFDRixDQUFDLEVBQUUsQ0FDREcsWUFBWSxFQUNaSCxLQUFLLENBQUNXLE9BQU8sRUFDYlgsS0FBSyxDQUFDWSxRQUFRLEVBQ2RaLEtBQUssQ0FBQ2EsVUFBVSxFQUNoQlIsSUFBSSxFQUNKSCxHQUFHLENBQ0osQ0FBQzs7RUFFRjtFQUNBLE1BQU1ZLFVBQVUsR0FBR1AsWUFBWSxLQUFLZixZQUFZLENBQUN1QixPQUFPO0VBRXhELE1BQU1DLFlBQVksR0FBR3RCLE9BQU8sQ0FBQyxNQUFNO0lBQ2pDO0lBQ0EsSUFBS3VCLElBQUksQ0FBQ0MsR0FBRyxDQUFDLENBQUMsSUFBSVYsU0FBUyxJQUFJLENBQUNNLFVBQVUsSUFBSyxDQUFDWixHQUFHLEVBQUU7SUFFdEQsT0FDRUQ7SUFDRTtJQUFBLENBQ0NrQixLQUFLLENBQUNyQixRQUFRLEVBQUUsR0FBSUMsSUFBc0IsQ0FBQyxDQUMzQ3FCLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO0lBRXBCO0lBQ0E7RUFDRixDQUFDLEVBQUUsQ0FBQ1osU0FBUyxFQUFFTixHQUFHLEVBQUVZLFVBQVUsRUFBRWQsS0FBSyxDQUFDcUIsU0FBUyxDQUFDLENBQUM7O0VBRWpEO0VBQ0EsSUFBSWQsWUFBWSxLQUFLZixZQUFZLENBQUM4QixLQUFLLElBQUlOLFlBQVksRUFBRTtJQUN2RCxNQUFNQSxZQUFZO0VBQ3BCO0VBRUEsTUFBTU8sS0FBSyxHQUFHdEIsVUFBVSxDQUFDdUIsUUFBUSxDQUFDMUIsUUFBUSxFQUFFLEdBQUdDLElBQUksRUFBRUMsS0FBSyxDQUFDO0VBRTNELElBQUl1QixLQUFLLEVBQUUsTUFBTUEsS0FBSzs7RUFFdEI7RUFDQTlCLFNBQVMsQ0FBQ2dCLFFBQVEsRUFBRSxDQUFDSCxJQUFJLENBQUMsQ0FBQztFQUUzQixPQUFPQSxJQUFJO0FBQ2IiLCJpZ25vcmVMaXN0IjpbXX0=