132 lines
3.7 KiB
JavaScript
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
|
|
};
|
|
}
|