LocalHtmlDataTest/sqlite/src/handle-store.ts
Jason Tudisco 6ebe02ad56 Initial commit: local-first browser sync library experiment
Four variants of the same sync library (IndexedDB, NeDB, SQLite WASM, sql.js)
plus a paste-bin demo app for testing multi-browser sync via shared folders.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-17 22:04:08 -06:00

57 lines
1.6 KiB
TypeScript

/**
* Tiny IndexedDB sidecar for persisting FileSystemDirectoryHandle.
*
* SQLite can't store DOM objects (they require structured clone),
* so we use a minimal IDB store exclusively for the folder handle.
*/
const DB_NAME = 'FolderSyncDB_handles';
const STORE_NAME = 'handles';
const DB_VERSION = 1;
function openHandleDB(): Promise<IDBDatabase> {
return new Promise((resolve, reject) => {
const req = indexedDB.open(DB_NAME, DB_VERSION);
req.onupgradeneeded = () => {
req.result.createObjectStore(STORE_NAME, { keyPath: 'key' });
};
req.onsuccess = () => resolve(req.result);
req.onerror = () => reject(req.error);
});
}
export async function storeHandle(
key: string,
handle: FileSystemDirectoryHandle,
): Promise<void> {
const db = await openHandleDB();
try {
const tx = db.transaction(STORE_NAME, 'readwrite');
tx.objectStore(STORE_NAME).put({ key, handle });
await new Promise<void>((resolve, reject) => {
tx.oncomplete = () => resolve();
tx.onerror = () => reject(tx.error);
});
} finally {
db.close();
}
}
export async function loadHandle(
key: string,
): Promise<FileSystemDirectoryHandle | null> {
const db = await openHandleDB();
try {
const tx = db.transaction(STORE_NAME, 'readonly');
const req = tx.objectStore(STORE_NAME).get(key);
return await new Promise<FileSystemDirectoryHandle | null>(
(resolve, reject) => {
req.onsuccess = () => resolve(req.result?.handle ?? null);
req.onerror = () => reject(req.error);
},
);
} finally {
db.close();
}
}