Object.defineProperty(exports, '__esModule', { value: true }); var React = require('react'); var useSwr = require('../use-swr-guqrv3k1.js'); var bunchee_group_0 = require('../config-context-s960zqob.js'); var _internal_index = require('../_internal/index.js'); var shim = require('use-sync-external-store/shim'); var _internal_constants = require('../_internal/constants.js'); const getFirstPageKey = (getKey)=>{ return bunchee_group_0.serialize(getKey ? getKey(0, null) : null)[0]; }; const unstable_serialize = (getKey)=>{ return _internal_constants.INFINITE_PREFIX + getFirstPageKey(getKey); }; // We have to several type castings here because `useSWRInfinite` is a special // hook where `key` and return type are not like the normal `useSWR` types. const EMPTY_PROMISE = Promise.resolve(); const infinite = (useSWRNext)=>(getKey, fn, config)=>{ const didMountRef = React.useRef(false); const { cache, initialSize = 1, revalidateAll = false, persistSize = false, revalidateFirstPage = true, revalidateOnMount = false, parallel = false } = config; const [, , , PRELOAD] = bunchee_group_0.SWRGlobalState.get(bunchee_group_0.cache); // The serialized key of the first page. This key will be used to store // metadata of this SWR infinite hook. let infiniteKey; try { infiniteKey = getFirstPageKey(getKey); if (infiniteKey) infiniteKey = _internal_constants.INFINITE_PREFIX + infiniteKey; } catch (err) { // Not ready yet. } const [get, set, subscribeCache] = bunchee_group_0.createCacheHelper(cache, infiniteKey); const getSnapshot = React.useCallback(()=>{ const size = bunchee_group_0.isUndefined(get()._l) ? initialSize : get()._l; return size; // eslint-disable-next-line react-hooks/exhaustive-deps }, [ cache, infiniteKey, initialSize ]); shim.useSyncExternalStore(React.useCallback((callback)=>{ if (infiniteKey) return subscribeCache(infiniteKey, ()=>{ callback(); }); return ()=>{}; }, // eslint-disable-next-line react-hooks/exhaustive-deps [ cache, infiniteKey ]), getSnapshot, getSnapshot); const resolvePageSize = React.useCallback(()=>{ const cachedPageSize = get()._l; return bunchee_group_0.isUndefined(cachedPageSize) ? initialSize : cachedPageSize; // `cache` isn't allowed to change during the lifecycle // eslint-disable-next-line react-hooks/exhaustive-deps }, [ infiniteKey, initialSize ]); // keep the last page size to restore it with the persistSize option const lastPageSizeRef = React.useRef(resolvePageSize()); // When the page key changes, we reset the page size if it's not persisted bunchee_group_0.useIsomorphicLayoutEffect(()=>{ if (!didMountRef.current) { didMountRef.current = true; return; } if (infiniteKey) { // If the key has been changed, we keep the current page size if persistSize is enabled // Otherwise, we reset the page size to cached pageSize set({ _l: persistSize ? lastPageSizeRef.current : resolvePageSize() }); } // `initialSize` isn't allowed to change during the lifecycle }, [ infiniteKey, cache ]); // Needs to check didMountRef during mounting, not in the fetcher const shouldRevalidateOnMount = revalidateOnMount && !didMountRef.current; // Actual SWR hook to load all pages in one fetcher. const swr = useSWRNext(infiniteKey, async (key)=>{ // get the revalidate context const forceRevalidateAll = get()._i; const shouldRevalidatePage = get()._r; // Capture the cache's unload generation (bumped by every `unload()` // call) so page responses that resolve after an unload are not // written back to the cleared cache. const state = bunchee_group_0.SWRGlobalState.get(cache); const unloadGeneration = state[8]; const unloadedDuringRequest = ()=>state[8] !== unloadGeneration; set({ _r: bunchee_group_0.UNDEFINED }); // return an array of page data const data = []; const pageSize = resolvePageSize(); const [getCache] = bunchee_group_0.createCacheHelper(cache, key); const cacheData = getCache().data; const revalidators = []; let previousPageData = null; for(let i = 0; i < pageSize; ++i){ const [pageKey, pageArg] = bunchee_group_0.serialize(getKey(i, parallel ? null : previousPageData)); if (!pageKey) { break; } const [getSWRCache, setSWRCache] = bunchee_group_0.createCacheHelper(cache, pageKey); // Get the cached page data. let pageData = getSWRCache().data; // should fetch (or revalidate) if: // - `revalidateAll` is enabled // - `mutate()` called // - the cache is missing // - it's the first page and it's not the initial render // - `revalidateOnMount` is enabled and it's on mount // - cache for that page has changed const shouldFetchPage = revalidateAll || forceRevalidateAll || bunchee_group_0.isUndefined(pageData) || revalidateFirstPage && !i && !bunchee_group_0.isUndefined(cacheData) || shouldRevalidateOnMount || cacheData && !bunchee_group_0.isUndefined(cacheData[i]) && !config.compare(cacheData[i], pageData); if (fn && (typeof shouldRevalidatePage === 'function' ? shouldRevalidatePage(pageData, pageArg) : shouldFetchPage)) { const revalidate = async ()=>{ const hasPreloadedRequest = pageKey in PRELOAD; if (!hasPreloadedRequest) { pageData = await fn(pageArg); } else { const req = PRELOAD[pageKey]; // delete the preload cache key before resolving it // in case there's an error delete PRELOAD[pageKey]; // get the page data from the preload cache pageData = await req; } if (!unloadedDuringRequest()) { setSWRCache({ data: pageData, _k: pageArg }); } data[i] = pageData; }; if (parallel) { revalidators.push(revalidate); } else { await revalidate(); } } else { data[i] = pageData; } if (!parallel) { previousPageData = pageData; } } // flush all revalidateions in parallel if (parallel) { await Promise.all(revalidators.map((r)=>r())); } // once we executed the data fetching based on the context, clear the // context. Skipped after an unload so the cleared meta entry isn't // re-created. if (!unloadedDuringRequest()) { set({ _i: bunchee_group_0.UNDEFINED }); } // return the data return data; }, config); const mutate = React.useCallback(// eslint-disable-next-line func-names function(data, opts) { // When passing as a boolean, it's explicitly used to disable/enable // revalidation. const options = typeof opts === 'boolean' ? { revalidate: opts } : opts || {}; // Default to true. const shouldRevalidate = options.revalidate !== false; // It is possible that the key is still falsy. if (!infiniteKey) return EMPTY_PROMISE; if (shouldRevalidate) { if (!bunchee_group_0.isUndefined(data)) { // We only revalidate the pages that are changed set({ _i: false, _r: options.revalidate }); } else { // Calling `mutate()`, we revalidate all pages set({ _i: true, _r: options.revalidate }); } } return arguments.length ? swr.mutate(data, { ...options, revalidate: shouldRevalidate }) : swr.mutate(); }, // swr.mutate is always the same reference // eslint-disable-next-line react-hooks/exhaustive-deps [ infiniteKey, cache ]); // Extend the SWR API const setSize = React.useCallback((arg)=>{ // It is possible that the key is still falsy. if (!infiniteKey) return EMPTY_PROMISE; const [, changeSize] = bunchee_group_0.createCacheHelper(cache, infiniteKey); let size; if (bunchee_group_0.isFunction(arg)) { size = arg(resolvePageSize()); } else if (typeof arg == 'number') { size = arg; } if (typeof size != 'number') return EMPTY_PROMISE; changeSize({ _l: size }); lastPageSizeRef.current = size; // Calculate the page data after the size change. const data = []; const [getInfiniteCache] = bunchee_group_0.createCacheHelper(cache, infiniteKey); let previousPageData = null; for(let i = 0; i < size; ++i){ const [pageKey] = bunchee_group_0.serialize(getKey(i, previousPageData)); const [getCache] = bunchee_group_0.createCacheHelper(cache, pageKey); // Get the cached page data. const pageData = pageKey ? getCache().data : bunchee_group_0.UNDEFINED; // Call `mutate` with infinte cache data if we can't get it from the page cache. if (bunchee_group_0.isUndefined(pageData)) { return mutate(getInfiniteCache().data); } data.push(pageData); previousPageData = pageData; } return mutate(data); }, // exclude getKey from the dependencies, which isn't allowed to change during the lifecycle // eslint-disable-next-line react-hooks/exhaustive-deps [ infiniteKey, cache, mutate, resolvePageSize ]); // Use getter functions to avoid unnecessary re-renders caused by triggering // all the getters of the returned swr object. return { size: resolvePageSize(), setSize, mutate, get data () { return swr.data; }, get error () { return swr.error; }, get isValidating () { return swr.isValidating; }, get isLoading () { return swr.isLoading; } }; }; const useSWRInfinite = _internal_index.withMiddleware(useSwr.useSWR, infinite); exports.default = useSWRInfinite; exports.infinite = infinite; exports.unstable_serialize = unstable_serialize;