function splitPath(path) { if (typeof path !== "string" || path.length === 0) { throw new Error("OPFS path must be a non-empty relative path."); } if (path.startsWith("/") || path.includes("//")) { throw new Error(`Invalid OPFS path: ${path}`); } const parts = path.split("/"); if (parts.some((part) => part === "." || part === ".." || part === "")) { throw new Error(`Invalid OPFS path: ${path}`); } return parts; } export async function getOpfsRoot(storage = globalThis.navigator?.storage) { if (!storage?.getDirectory) { throw new Error("OPFS is not available in this browser."); } return storage.getDirectory(); } export async function ensureParentDir(root, path) { const parts = splitPath(path); let current = root; for (const part of parts.slice(0, -1)) { current = await current.getDirectoryHandle(part, { create: true }); } return current; } export async function saveTextFile(path, text, storage) { const root = await getOpfsRoot(storage); const dir = await ensureParentDir(root, path); const filename = splitPath(path).at(-1); const fileHandle = await dir.getFileHandle(filename, { create: true }); const writable = await fileHandle.createWritable(); await writable.write(text); await writable.close(); } export async function loadTextFile(path, storage) { const root = await getOpfsRoot(storage); const parts = splitPath(path); let current = root; for (const part of parts.slice(0, -1)) { current = await current.getDirectoryHandle(part); } const fileHandle = await current.getFileHandle(parts.at(-1)); const file = await fileHandle.getFile(); return file.text(); }