Files
2026-06-06 18:43:00 +08:00

132 lines
3.7 KiB
JavaScript

// resources/js/composables/useOPFS.js
/**
* Composable to handle Origin Private File System (OPFS) operations.
*/
export function useOPFS() {
/**
* Get the OPFS root directory.
* @returns {Promise<FileSystemDirectoryHandle>}
*/
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<boolean>}
*/
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<Blob|null>}
*/
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<boolean>}
*/
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<boolean>}
*/
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<boolean>}
*/
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<any|null>}
*/
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
};
}