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>
57 lines
1.6 KiB
TypeScript
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();
|
|
}
|
|
}
|