tickle/modules/utils/makeFileSizeFetcher.mjs

40 lines
1.4 KiB
JavaScript

//@ts-check
import { fetchContentLength } from "./fetchContentLength.mjs";
/**
* Conditional size fetcher, which can be skipped by providing an intial size.
* This function is only useful when used as part of a larger loading framework, when
* files loading may or may not have access to size information, and you want a
* consistent behavior regardless.
*
* If `estimatedTotal` is passed, this is a no-op.
* If `estimatedTotal` is not passed, the created function does a limited `fetch`
* to attempt to retrieve the file size.
* Repeated calls to the function will not repeat the fetch request.
* The function is not guaranteed to succeed, the server has to play along by
* sending the correct headers.
* Ideally, `total` is passed instead to avoid this.
* @see {fetchContentLength} decodeContentLength
* @param {string} filePath
* @param {number} estimatedTotal
* @returns {()=>Promise<number>} a function that always returns the same promise
*/
export const makeFileSizeFetcher = (filePath, estimatedTotal = 0) => {
/**
* @type {Promise<number> | null}
*/
let totalPromise = estimatedTotal ? Promise.resolve(estimatedTotal) : null;
const fetchSize = () =>
(totalPromise =
totalPromise ||
fetchContentLength(filePath).then(
(fetchedTotal) => (estimatedTotal = fetchedTotal)
));
return fetchSize;
};
export default makeFileSizeFetcher;