Files
BarangaySystem/resources/js/composables/useFileBlobCache.js
2026-06-06 18:43:00 +08:00

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
};
}