75 lines
2.0 KiB
JavaScript
75 lines
2.0 KiB
JavaScript
import { ref } from 'vue';
|
|
import { useOPFS } from './useOPFS.js';
|
|
|
|
const blobCache = ref({});
|
|
const opfs = useOPFS();
|
|
|
|
export function useFileBlobCache() {
|
|
/**
|
|
* Get a blob URL for a given hash.
|
|
* Order: 1. Locally cached URL (blobCache), 2. Persistent storage (OPFS), 3. Server Fetch.
|
|
*
|
|
* @param {string} hash
|
|
* @returns {Promise<string|null>}
|
|
*/
|
|
const getFile = async (hash) => {
|
|
if (!hash) return null;
|
|
|
|
// 1. Check in local session cache
|
|
if (blobCache.value[hash]) {
|
|
return blobCache.value[hash];
|
|
}
|
|
|
|
// 2. Check in persistent OPFS storage
|
|
const opfsBlob = await opfs.loadFile(hash);
|
|
if (opfsBlob) {
|
|
const blobUrl = URL.createObjectURL(opfsBlob);
|
|
blobCache.value[hash] = blobUrl;
|
|
return blobUrl;
|
|
}
|
|
|
|
// 3. Last resort: fetch from server
|
|
try {
|
|
const url = `/RequestData/File/${hash}`;
|
|
const response = await fetch(url);
|
|
|
|
if (!response.ok) {
|
|
throw new Error(`Failed to fetch file: ${response.statusText}`);
|
|
}
|
|
|
|
const blob = await response.blob();
|
|
|
|
// Save to persistent OPFS storage for future use
|
|
await opfs.saveFile(hash, blob);
|
|
|
|
const blobUrl = URL.createObjectURL(blob);
|
|
|
|
// Store in local session cache
|
|
blobCache.value[hash] = blobUrl;
|
|
|
|
return blobUrl;
|
|
} catch (error) {
|
|
console.error(`Error fetching file with hash ${hash}:`, error);
|
|
return null;
|
|
}
|
|
};
|
|
|
|
/**
|
|
* Pre-cache a list of hashes.
|
|
*
|
|
* @param {string[]} hashes
|
|
*/
|
|
const preCacheFiles = async (hashes) => {
|
|
if (!hashes || !Array.isArray(hashes)) return;
|
|
|
|
const promises = hashes.map(hash => getFile(hash));
|
|
await Promise.all(promises);
|
|
};
|
|
|
|
return {
|
|
getFile,
|
|
preCacheFiles,
|
|
blobCache
|
|
};
|
|
}
|