UNPKG

@gqty/react

Version:

The No-GraphQL Client for React

163 lines (158 loc) • 4.46 kB
'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); const gqty = require('gqty'); const React = require('react'); const common = require('../common.js'); const createUsePaginatedQuery = ({ createResolver, resolve }, { defaults: { paginatedQueryFetchPolicy: defaultFetchPolicy, paginatedQuerySuspense: defaultSuspense } }) => (fn, { initialArgs, fetchPolicy: hookFetchPolicy = defaultFetchPolicy, merge, retry, skip = false, suspense = defaultSuspense, operationName }) => { const { accessor: { query }, context, selections } = React.useMemo( () => createResolver({ cachePolicy: common.translateFetchPolicy(hookFetchPolicy), operationName, retryPolicy: retry }), [hookFetchPolicy, operationName, retry] ); const [state, setState] = React.useState({ args: initialArgs }); if (suspense) { if (state.promise) throw state.promise; if (state.error) throw state.error; } const mergeData = React.useCallback( (incoming) => { var _a; return (_a = merge == null ? void 0 : merge({ data: { existing: state.data, incoming }, uniqBy: common.uniqBy, sortBy: common.sortBy })) != null ? _a : incoming; }, [merge] ); const fetchData = React.useCallback( async (args, fetchPolicy = hookFetchPolicy) => { const promise = resolve(({ query: query2 }) => fn(query2, args, common.coreHelpers), { cachePolicy: common.translateFetchPolicy(fetchPolicy), operationName, retryPolicy: retry, onSelect(selection, cache) { context.select(selection, cache); } }); if (!context.shouldFetch) { state.data = mergeData(fn(query, args, common.coreHelpers)); return state.data; } if (hookFetchPolicy === "cache-and-network" && context.hasCacheHit) { state.data = mergeData(fn(query, args, common.coreHelpers)); } state.promise = promise; promise.finally(() => { if (state.promise === promise) { state.promise = void 0; } }); return promise; }, [ context, common.coreHelpers, fn, // fn almost guaranteed to change on every render hookFetchPolicy, mergeData, operationName, query, retry ] ); React.useState(() => { if (skip) return setState(({ args }) => ({ args })); const promise = fetchData(initialArgs); promise.then( (data) => { setTimeout(() => { setState(({ args }) => ({ args, data })); }, 1e3); }, (error) => { setState(({ args }) => ({ args, error: gqty.GQtyError.create(error) })); } ).finally(() => context.reset()); if (context.shouldFetch) { if (suspense) { throw promise; } else { setState(({ args }) => ({ args, promise })); } } }); React.useEffect(() => { if (skip || selections.size === 0) return; return context.cache.subscribe( [...selections].map((s) => s.cacheKeys.join(".")), () => setState((state2) => ({ ...state2 })) ); }, [selections.size]); const fetchMore = React.useCallback( async (newArgs, fetchPolicy) => { const currentArgs = typeof newArgs === "function" ? newArgs({ existingData: state.data, existingArgs: state.args }) : newArgs != null ? newArgs : state.args; try { const promise = fetchData(currentArgs, fetchPolicy); const data = await promise.then(mergeData); setState(({ args }) => ({ args, data })); return data; } catch (e) { const error = gqty.GQtyError.create(e); setState(({ args }) => ({ args, error })); throw error; } }, [fetchData] ); React.useEffect(() => { return context.cache.subscribe( [...selections].map((s) => s.cacheKeys.join(".")), () => { setState((state2) => ({ ...state2, data: fn(query, state2.args, common.coreHelpers) })); } ); }, [fn, state, selections.size]); return React.useMemo( () => Object.freeze({ args: state.args, data: state.data, fetchMore, isLoading: state.promise !== void 0 }), [state.args, state.data, fetchMore, state.promise] ); }; exports.createUsePaginatedQuery = createUsePaginatedQuery;