40 lines
1.4 KiB
JavaScript
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;
|