// Filesystem wrapper around lightning-fs (IndexedDB-backed). isomorphic-git // needs the instance itself; our code uses the Promises-style helpers. import LightningFS from '@isomorphic-git/lightning-fs'; const inst = new LightningFS('passchmop-repo'); export const fs = inst; export const pfs = inst.promises; export const dir = '/repo'; export const entriesDir = `${dir}/entries`; interface FsError extends Error { code?: string } export async function ensureDir(path: string): Promise { try { await pfs.mkdir(path); } catch (e) { if ((e as FsError).code !== 'EEXIST') throw e; } } export async function listEntryFiles(): Promise { try { const names = await pfs.readdir(entriesDir); return names.filter(n => n.endsWith('.enc')); } catch (e) { if ((e as FsError).code === 'ENOENT') return []; throw e; } } export async function readEntryFile(filename: string): Promise { const buf = await pfs.readFile(`${entriesDir}/${filename}`); if (typeof buf === 'string') throw new Error('unexpected string read for entry file'); return new Uint8Array(buf); } export async function writeEntryFile(filename: string, bytes: Uint8Array): Promise { await ensureDir(entriesDir); await pfs.writeFile(`${entriesDir}/${filename}`, bytes); } export async function removeEntryFile(filename: string): Promise { try { await pfs.unlink(`${entriesDir}/${filename}`); } catch (e) { if ((e as FsError).code !== 'ENOENT') throw e; } } export async function readJson(path: string): Promise { try { const buf = await pfs.readFile(`${dir}/${path}`, { encoding: 'utf8' }); const text = typeof buf === 'string' ? buf : new TextDecoder().decode(buf); return JSON.parse(text) as T; } catch (e) { if ((e as FsError).code === 'ENOENT') return null; throw e; } } export async function writeJson(path: string, obj: unknown): Promise { await ensureDir(dir); await pfs.writeFile(`${dir}/${path}`, JSON.stringify(obj, null, 2), 'utf8'); } export async function wipeRepo(): Promise { async function rm(path: string): Promise { try { const stat = await pfs.stat(path); if (stat.isDirectory()) { const kids = await pfs.readdir(path); for (const k of kids) await rm(`${path}/${k}`); await pfs.rmdir(path); } else { await pfs.unlink(path); } } catch (e) { if ((e as FsError).code !== 'ENOENT') throw e; } } await rm(dir); }