/** * Small helpers around the Origin Private File System, used to stream muxer * output into a real file with random access instead of hand-assembling * chunks in memory. Browser-only; every function is a no-op when OPFS is not * available. */ const PREFIX = "j621-optimize-"; const STALE_MS = 60 * 60 * 1000; // purge leftovers after an hour function directory(): Promise | null { if (typeof navigator === "undefined") return null; const storage = navigator.storage as StorageManager | undefined; if (!storage?.getDirectory) return null; return storage.getDirectory(); } export function opfsSupported(): boolean { return ( typeof navigator !== "undefined" && Boolean((navigator.storage as StorageManager | undefined)?.getDirectory) ); } export async function createStoredFile( extension: string, ): Promise<{ name: string; handle: FileSystemFileHandle } | null> { const root = await directory(); if (!root) return null; const name = `${PREFIX}${crypto.randomUUID()}.${extension}`; const handle = await root.getFileHandle(name, { create: true }); return { name, handle }; } export async function deleteStoredFile(name: string): Promise { try { const root = await directory(); if (!root) return; await root.removeEntry(name); } catch { // Best effort: stale entries are purged on the next run anyway. } } export async function purgeStaleStoredFiles(): Promise { try { const root = await directory(); if (!root) return; const now = Date.now(); const entries = ( root as unknown as { entries(): AsyncIterableIterator<[string, FileSystemHandle]>; } ).entries(); for await (const [name, handle] of entries) { if (!name.startsWith(PREFIX) || handle.kind !== "file") continue; try { const file = await (handle as FileSystemFileHandle).getFile(); if (now - file.lastModified > STALE_MS) { await root.removeEntry(name); } } catch { // Ignore entries that vanish underneath us. } } } catch { // OPFS iteration is best effort. } }