// OPFS-хранилище сырой .sqlite. // Никакого sqlite-wasm здесь пока нет — просто кладём бинарный файл, // чтобы следующие шаги (открытие БД, выгрузка) работали с одним источником правды. /** Имя файла БД в OPFS. Совпадает с десктопом: один и тот же бинарный .sqlite. */ export const DB_FILENAME = 'japanese_app.db'; async function opfsRoot(): Promise { return navigator.storage.getDirectory(); } /** * Сохраняет сырые байты .sqlite в OPFS (перезаписывает файл целиком). * Пишем через SyncAccessHandle, если он доступен, иначе — через WritableStream. */ export async function writeDatabaseFile(data: Uint8Array): Promise { data[18] = 1; data[19] = 1; const root = await opfsRoot(); const handle = await root.getFileHandle(DB_FILENAME, { create: true }); // SyncAccessHandle доступен только в воркерах — пробуем, в main-потоке упадёт. const maybeSync = (handle as unknown as { createSyncAccessHandle?: () => Promise; }).createSyncAccessHandle; if (typeof maybeSync === 'function') { try { const access = await maybeSync.call(handle); try { access.truncate(0); access.write(data, { at: 0 }); access.flush(); } finally { access.close(); } return; } catch { // Падаем ниже на WritableStream — обычный путь для main-потока } } const writable = await handle.createWritable(); try { await writable.truncate(0); // Копия: избегаем проблем с SharedArrayBuffer/neutered буферами const copy = new Uint8Array(data.length); copy.set(data); await writable.write(copy); } finally { await writable.close(); } } /** Читает сырой .sqlite из OPFS. Бросает Error, если файла нет. */ export async function readDatabaseFile(): Promise { const root = await opfsRoot(); let handle: FileSystemFileHandle; try { handle = await root.getFileHandle(DB_FILENAME); } catch { throw new Error('Локальная база не найдена — сначала скачай сохранение'); } const file = await handle.getFile(); if (file.size === 0) throw new Error('Локальная база пуста'); let data = new Uint8Array(await file.arrayBuffer()); return data; } /** Проверяет, есть ли непустой файл БД в OPFS. */ export async function hasDatabaseFile(): Promise { try { const root = await opfsRoot(); const handle = await root.getFileHandle(DB_FILENAME); const file = await handle.getFile(); return file.size > 0; } catch { return false; } }