From f7321addc086dc6d1e6a1d696e2db4d0cc71ce42 Mon Sep 17 00:00:00 2001 From: Joshua Lochner Date: Wed, 8 Nov 2023 18:03:10 +0200 Subject: [PATCH] Fix Firefox bug when displaying progress events while reading file from browser cache (#374) * Fix firefox bug Do not display progress events when reading from browser cache in Firefox. * Typo --- src/utils/core.js | 4 ++-- src/utils/hub.js | 45 ++++++++++++++++++++++++++++++++++++++------- 2 files changed, 40 insertions(+), 9 deletions(-) diff --git a/src/utils/core.js b/src/utils/core.js index 72e198789..718ca4f0e 100644 --- a/src/utils/core.js +++ b/src/utils/core.js @@ -11,13 +11,13 @@ /** * Helper function to dispatch progress callbacks. * - * @param {function} progress_callback The progress callback function to dispatch. + * @param {Function} progress_callback The progress callback function to dispatch. * @param {any} data The data to pass to the progress callback function. * @returns {void} * @private */ export function dispatchCallback(progress_callback, data) { - if (progress_callback !== null) progress_callback(data); + if (progress_callback) progress_callback(data); } /** diff --git a/src/utils/hub.js b/src/utils/hub.js index c2557c1bc..a6219bc25 100644 --- a/src/utils/hub.js +++ b/src/utils/hub.js @@ -424,6 +424,8 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti response = await tryCache(cache, localPath, proposedCacheKey); } + const cacheHit = response !== undefined; + if (response === undefined) { // Caching not available, or file is not cached, so we perform the request @@ -490,14 +492,44 @@ export async function getModelFile(path_or_repo_id, filename, fatal = true, opti file: filename }) - const buffer = await readResponse(response, data => { + const progressInfo = { + status: 'progress', + name: path_or_repo_id, + file: filename + } + + /** @type {Uint8Array} */ + let buffer; + + if (!options.progress_callback) { + // If no progress callback is specified, we can use the `.arrayBuffer()` + // method to read the response. + buffer = new Uint8Array(await response.arrayBuffer()); + + } else if ( + cacheHit // The item is being read from the cache + && + typeof navigator !== 'undefined' && /firefox/i.test(navigator.userAgent) // We are in Firefox + ) { + // Due to bug in Firefox, we cannot display progress when loading from cache. + // Fortunately, since this should be instantaneous, this should not impact users too much. + buffer = new Uint8Array(await response.arrayBuffer()); + + // For completeness, we still fire the final progress callback dispatchCallback(options.progress_callback, { - status: 'progress', - ...data, - name: path_or_repo_id, - file: filename + ...progressInfo, + progress: 100, + loaded: buffer.length, + total: buffer.length, }) - }) + } else { + buffer = await readResponse(response, data => { + dispatchCallback(options.progress_callback, { + ...progressInfo, + ...data, + }) + }) + } if ( // Only cache web responses @@ -559,7 +591,6 @@ export async function getModelJSON(modelPath, fileName, fatal = true, options = * @returns {Promise} A Promise that resolves with the Uint8Array buffer */ async function readResponse(response, progress_callback) { - // Read and track progress when reading a Response object const contentLength = response.headers.get('Content-Length'); if (contentLength === null) {