64 lines
1.8 KiB
TypeScript
64 lines
1.8 KiB
TypeScript
/**
|
||
* IndexedDB 封装 —— 持久化 FileSystemDirectoryHandle
|
||
*
|
||
* chrome.storage 存不了 FileSystemDirectoryHandle(它不是 JSON 可序列化类型),
|
||
* 必须用 IndexedDB(structured clone 支持)。存一次后跨会话免重复授权。
|
||
*/
|
||
|
||
const DB_NAME = 'ozon-seller-kit';
|
||
const STORE = 'handles';
|
||
const ROOT_KEY = 'SH_ROOT_DIR';
|
||
|
||
function openDb(): Promise<IDBDatabase> {
|
||
return new Promise((resolve, reject) => {
|
||
const req = indexedDB.open(DB_NAME, 1);
|
||
req.onupgradeneeded = () => {
|
||
if (!req.result.objectStoreNames.contains(STORE)) {
|
||
req.result.createObjectStore(STORE);
|
||
}
|
||
};
|
||
req.onsuccess = () => resolve(req.result);
|
||
req.onerror = () => reject(req.error);
|
||
});
|
||
}
|
||
|
||
export async function idbSet(key: string, value: unknown): Promise<void> {
|
||
const db = await openDb();
|
||
return new Promise((resolve, reject) => {
|
||
const tx = db.transaction(STORE, 'readwrite');
|
||
tx.objectStore(STORE).put(value, key);
|
||
tx.oncomplete = () => {
|
||
db.close();
|
||
resolve();
|
||
};
|
||
tx.onerror = () => {
|
||
db.close();
|
||
reject(tx.error);
|
||
};
|
||
});
|
||
}
|
||
|
||
export async function idbGet<T>(key: string): Promise<T | null> {
|
||
const db = await openDb();
|
||
return new Promise((resolve, reject) => {
|
||
const tx = db.transaction(STORE, 'readonly');
|
||
const req = tx.objectStore(STORE).get(key);
|
||
req.onsuccess = () => {
|
||
db.close();
|
||
resolve((req.result as T) ?? null);
|
||
};
|
||
req.onerror = () => {
|
||
db.close();
|
||
reject(req.error);
|
||
};
|
||
});
|
||
}
|
||
|
||
export async function saveRootDir(handle: FileSystemDirectoryHandle): Promise<void> {
|
||
await idbSet(ROOT_KEY, handle);
|
||
}
|
||
|
||
export async function loadRootDir(): Promise<FileSystemDirectoryHandle | null> {
|
||
return idbGet<FileSystemDirectoryHandle>(ROOT_KEY);
|
||
}
|