// resources/js/composables/useOPFS.js /** * Composable to handle Origin Private File System (OPFS) operations. */ export function useOPFS() { /** * Get the OPFS root directory. * @returns {Promise} */ const getRoot = async () => { return await navigator.storage.getDirectory(); }; /** * Save a Blob or ArrayBuffer to OPFS as a file. * @param {string} filename * @param {Blob|ArrayBuffer} content * @returns {Promise} */ const saveFile = async (filename, content) => { if (!filename || !content) return false; try { const root = await getRoot(); const fileHandle = await root.getFileHandle(filename, { create: true }); const writable = await fileHandle.createWritable(); await writable.write(content); await writable.close(); return true; } catch (error) { console.error(`[OPFS] Error saving file "${filename}":`, error); return false; } }; /** * Load a file from OPFS as a Blob. * @param {string} filename * @returns {Promise} */ const loadFile = async (filename) => { if (!filename) return null; try { const root = await getRoot(); const fileHandle = await root.getFileHandle(filename); const file = await fileHandle.getFile(); return file; } catch (error) { // File not finding is a common potential case, no need to log error return null; } }; /** * Check if a file exists in OPFS. * @param {string} filename * @returns {Promise} */ const exists = async (filename) => { if (!filename) return false; try { const root = await getRoot(); await root.getFileHandle(filename); return true; } catch (e) { return false; } }; /** * Delete a file from OPFS. * @param {string} filename * @returns {Promise} */ const deleteFile = async (filename) => { if (!filename) return false; try { const root = await getRoot(); await root.removeEntry(filename); return true; } catch (error) { console.error(`[OPFS] Error deleting file "${filename}":`, error); return false; } }; /** * Save JSON data to OPFS. * @param {string} filename * @param {any} data * @returns {Promise} */ const saveJSON = async (filename, data) => { if (!filename || data === undefined) return false; try { const jsonStr = JSON.stringify(data); const blob = new Blob([jsonStr], { type: 'application/json' }); return await saveFile(filename, blob); } catch (error) { console.error(`[OPFS] Error saving JSON "${filename}":`, error); return false; } }; /** * Load JSON data from OPFS. * @param {string} filename * @returns {Promise} */ const loadJSON = async (filename) => { if (!filename) return null; try { const blob = await loadFile(filename); if (!blob) return null; const text = await blob.text(); return JSON.parse(text); } catch (error) { console.error(`[OPFS] Error loading JSON "${filename}":`, error); return null; } }; return { saveFile, loadFile, saveJSON, loadJSON, exists, deleteFile }; }